tags:

views:

149

answers:

3

I'm learning makefiles and I'm trying to figure out how to reuse a rule. Right now I have the following:

CPP = cl

CPPFLAGS = /Od /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt

.SUFFIXES: .exe .cpp

Exercise35.exe:
    $(CPP) Exercise35.cpp $(CPPFLAGS)

debug:
    $(CPP) Exercise35.cpp $(CPPFLAGS) /D "_DEBUG"

It seems bad that the debug rule essentially repeats the Exercise35 rule with an extra command-line parameter. Is there a better way?

+2  A: 

Recursive make, and append your debugging flag to CPPFLAGS.

debug:
    $(MAKE) CPPFLAGS="$(CPPFLAGS) /D _DBEBUG" Exercise35.exe
eduffy
I did this and get: NMAKE : fatal error U1073: don't know how to make '" /D _DEBUG"'
AlanT
The change you made works. Thank you!
AlanT
A: 

G'day,

I'd be more inclined to make the debug option a macro within the Makefile.

CPP = cl

CPPFLAGS = /Od /D "WIN32" /D "_CONSOLE" /D \
    "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 \
    /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 \
    /nologo /c /ZI /TP /errorReport:prompt

#DEBUG = /D "_DEBUG"
DEBUG =

.SUFFIXES: .exe .cpp

Exercise35.exe:
    ${CPP} Exercise35.cpp ${CPPFLAGS} ${DEBUG}

and then comment out the version of the DEBUG macro that you don't want to use.

BTW It's better to refer to Makefile macros using ${} rather than $() as round brackets are used for object substitution into archives and curly brackets aren't.

Edit: If you're learning make and makefiles then I'd highly recommend having a read of the first few chapters of "Managing Projects with GNU Make". It'll help you get your head around some non-intuitive aspects of the behaviour of make, esp. it's backwards-chaining behaviour.

If you can find a copy of the small first edition which isn't so gmake specific then even better. It's explanation is much better IMHO.

Edit 2: Here's a link to the Amazon site for the first edition of the book simply called "Managing Projects with Make". As I said above, great description of why make behaves as it does.

HTH

cheers,

Rob Wells
+1  A: 

You should check out the following properties of the make and look at the sample below:

  • $@ - means the name of the current target file, in this case it corresponds to the value of APP.
  • $< - means a single file that is newer than the target on which the target is dependant.
  • $? - means a list of files newer than the current target on which the target is dependant.
.SUFFIXES: .cpp.exe
CPP = cl
EXTRAFLAGS = 
CPPFLAGS = /Od /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /ZI /TP /errorReport:prompt

FILES = Exercise35
APP = Exercise35.exe

.cpp.exe:
     $(CPP) $(EXTRAFLAGS) $(CPPFLAGS) /c $<

all : $(APP)

$(APP) : $(FILES)
     $(CPP) $(EXTRAFLAGS) $(CPPFLAGS) $@ $(FILES)

clobber : clean mrproper

clean:
     del $(FILES)

mrproper:
     del $(APP)

I got this from my old makefile template, notice that the make will appear 'intelligent' and flexible as you can override the flag specifically for debugging/release within the one make file by executing like this

make EXTRAFLAGS="/D _DDEBUG"

This will pass in the extra define into the makefile to include the _DDEBUG macro, if you wish to build a release, leave out the EXTRAFLAGS on the command line.

Edit: As per Mike's point-out, I thought it would be useful to include the extra rules so that you can clean the directory with exe's and object code lying around...This was my original template makefile from AIX (which I've used under Linux also...) Thanks Mike for the heads up!

Hope this helps, Best regards, Tom.

tommieb75
Shouldn't it be `FILES = Exercise35.cpp`? Also, why the trailing semicolon on the `$(APP)` rule? And don't you need a `.PHONY: all clobber clean mrproper` rule?
Mike DeSimone
@Mike: Oops...that semicolon...I will edit this accordingly... :(
tommieb75