6

I have created a (very simple) makefile:

DEBUG = -DDEBUG

main: main.c add.c
   gcc $(DEBUG) main.c add.c -o main -lm

What I want (and don't understand how to do), is to create the makefile so that if the user prints make debug, the code will compile with the debug option, but when printing only make, the debug will be left out. What is the best way to do this?

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
user16655
  • 1,901
  • 6
  • 36
  • 60
  • possible duplicate of [Change a make variable, and call another rule, from a recipe in same Makefile?](http://stackoverflow.com/questions/26382846/change-a-make-variable-and-call-another-rule-from-a-recipe-in-same-makefile) – Jonathan Wakely Oct 21 '14 at 10:12

3 Answers3

9

You probably are looking for something like

main: main.c add.c
   gcc $(DEBUG) main.c add.c -o main -lm

debug: DEBUG = -DDEBUG

debug: main
downhillFromHere
  • 1,967
  • 11
  • 11
  • Thank you, this works. The only thing is that if i write 'make' then 'make debug' or the other way around, it still compiles to the first 'make' I write. Is it possible to create the makefile so that it recompiles with the option I give each time? – user16655 Oct 21 '14 at 10:40
  • No, it doesn't compile to the first `make` you run. It simply checks if your source files are newer than your executable. If not, it won't do anything. So whatever `make` you run second will do nothing unless you update your source files in between. But if you want `make debug` to always recompile, simply add `.PHONY: debug`. – downhillFromHere Oct 21 '14 at 12:04
  • Adding `.PHONY: debug` won't help. That just makes the `debug` target itself, which has no commands, phony. You'll have to write a "clean" rule then run `make clean` between the two invocations of `make`. Or, modify your makefile so the debug versions are created in a different directory. – MadScientist Oct 21 '14 at 12:34
  • @MadScientist Thanks for pointing that out. Apparently it worked when I tested it due to a change I forgot to revert back. – downhillFromHere Oct 21 '14 at 12:52
  • So instead of making `debug` phony, you could do `main debug: main.c add.c` in your first rule to make sure `make debug` always recompiles. – downhillFromHere Oct 21 '14 at 12:58
1

This may be late, ...

The basic idea is to build all objects in the subdirectory, say ./build. We create a release file in ./build when we compile with make and create a debug file when make debug. So if there is a release file when make debug, remove everything in ./build and then build.

all: $(BD)/release $(bin1) $(bin2)

debug: CFLAGS += -g -DDEBUG=1
debug: CXXFLAGS += -g -DDEBUG=1
debug: $(BD)/debug $(bin1) $(bin2)

$(BD)/%.o: %.c Makefile # changes in Makefile will cause a rebuild
    @mkdir -p $(BD)
    $(CC) $(CFLAGS) -c -o $@ $<

$(BD)/%.o: %.cpp Makefile
    @mkdir -p $(BD)
    $(CXX) $(CXXFLAGS) -c -o $@ $<

$(BD)/release:
    @if [ -e $(BD)/debug ]; then rm -rf $(BD); fi
    @mkdir -p $(BD)
    @touch $(BD)/release

$(BD)/debug:
    @if [ -e $(BD)/release ]; then rm -rf $(BD); fi
    @mkdir -p $(BD)
    @touch $(BD)/debug
ABacker
  • 190
  • 4
0

I came up with this solution, that depends on bash variable substitution.

Makefile:

main: main.c add.c
    ${CC} `echo $${DEBUG+-DDEBUG}` main.c add.c -o main -lm

When environment variable DEBUG is defined to anything (even blank), this makefile will substitute the -DDEBUG useful to the compiler. So invocation looks like:

DEBUG=1 make main
bgStack15
  • 180
  • 3
  • 11