0

I am trying to create debug and release configurations for a project, and I just can't figure out what is wrong.

For some reason, when I do 'make debug', make skips the dependencies for 'all', giving me a bunch of errors from g++ (no such file or directory). Even weirder is that if I do 'make all', everything works just fine.

Here is the makefile:

SHELL=/bin/sh
CXX=g++
LIBS=-LE:\Software\StrategyEngine\Release -llibdebug
CFLAGS=-Wall -O3 -IE:\Software\StrategyEngine\include

BDIR=Build\Release

debug: CFLAGS+=-g -DDEBUG
debug: LIBS=-LE:\Software\StrategyEngine\Debug -llibdebug
debug: BDIR=Build\Debug

OBJS= $(BDIR)\blocksort.o  \
      #... more object files
      $(BDIR)\CompressionStream.o

debug: all

all: $(OBJS) 
    $(CXX) $(LIBS) -shared -o $(BDIR)\libbz2.dll $(OBJS)
    $(CXX) $(LIBS) $(CFLAGS) -o $(BDIR)\bzip2-shared bzip2.cpp $(BDIR)\libbz2.dll

$(BDIR)\blocksort.o: blocksort.cpp
    $(CXX) $(CFLAGS) -c blocksort.cpp -o $(BDIR)\blocksort.o
#.... more rules for each object file defined in OBJS

clean: 
    rm -f Build\debug\* Build\release\*

Why is this happening? I can't find any error in the makefile.

I am using the mingw compiler suite (make version 3.81), running on windows 7.

जलजनक
  • 3,072
  • 2
  • 24
  • 30
Tibi
  • 4,015
  • 8
  • 40
  • 64
  • First, change your backslashes into slashes. I'm not sure these tools can handle backslashes as directory separators. – reinierpost Jul 17 '12 at 10:44
  • 1
    Second, `make` isn't good at doing things across different directories. The custom is to compile things in the same directory and have a separate `install` step to put the final results into place. – reinierpost Jul 17 '12 at 10:45
  • @reinierpost: you probably meant that make doesn't create directories for you. – Maxim Egorushkin Jul 17 '12 at 10:57
  • @Maxim Yegorushkin: No, I meant that make's pattern rules treat slashes in a way I don't understand. – reinierpost Jul 18 '12 at 08:40
  • @reinierpost make treats targets as strings and doesn't know anything about directory separators, e.g. `/a/b/c/` and `/a/b/../b/c` are different targets for make. – Maxim Egorushkin Jul 18 '12 at 09:02
  • @Maxim Yegorushkin: But it, at least GNU make, does perform special processing to separate the filename from the directory name when matching pattern rules, see e.g. http://opensource.apple.com/source/gnumake/gnumake-104/make/implicit.c – reinierpost Jul 18 '12 at 14:01

1 Answers1

2

The object file location BDIR in your makefile doesn't change depending on the build mode.

I suggest refactoring the script as follows:

SHELL=/bin/sh
CXX=g++

BUILD := debug # default mode

CFLAGS.release := -Wall -O3 -IE:/Software/StrategyEngine/include -D_NDEBUG
CFLAGS.debug   := -Wall -g  -IE:/Software/StrategyEngine/include -DDEBUG
LIBS.release := -LE:/Software/StrategyEngine/Release -llibdebug
LIBS.debug   := -LE:/Software/StrategyEngine/Debug -llibdebug
BDIR.release := Build/Release
BDIR.debug   := Build/Debug

CFLAGS := ${CFLAGS.${BUILD}}
LIBS := ${LIBS.${BUILD}}
BDIR := ${BDIR.${BUILD}}

OBJS= $(BDIR)/blocksort.o  /
      #... more object files
      $(BDIR)/CompressionStream.o

all: $(OBJS)
    $(CXX) $(LIBS) -shared -o $(BDIR)/libbz2.dll $(OBJS)
    $(CXX) $(LIBS) $(CFLAGS) -o $(BDIR)/bzip2-shared bzip2.cpp $(BDIR)/libbz2.dll

$(BDIR)/blocksort.o: blocksort.cpp
    $(CXX) $(CFLAGS) -c blocksort.cpp -o $(BDIR)/blocksort.o
#.... more rules for each object file defined in OBJS

clean:
    rm -f Build/debug/* Build/release/*

.PHONY: all clean 

And use it like:

make BUILD=debug
make BUILD=release
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • Thank you, this was very helpful. I have one small question though, what is the difference between `:=` and `=` in make? – Tibi Jul 17 '12 at 11:19
  • Never mind the last question, already found the answer http://stackoverflow.com/questions/448910/makefile-variable-assignment . – Tibi Jul 17 '12 at 11:20