How do you implement a makefile that remembers the last build target?

Say you have a Makefile with two pseudo targets, “all” and “debugging”. The purpose of "debug" is to create the same project as "everything", except for some different compilation switches (for example, -ggdb). Since the targets use different compilation keys, you obviously need to rebuild the entire project if you switch between them. But GNUmake naturally does not recognize this.

So, if you type make all , you will get

 Building ... ... 

Then, if you type make debug , you will get

 make: Nothing to be done for `debug'. 

So my question is: how do you implement a clean solution in the Makefile to notice that the last build used different pseudo-target or different compilation keys than the one you currently want? If they are different, the Makefile will restore everything.

+6
makefile gnu-make target
source share
3 answers

Place the assembly products in different directory trees (while, of course, saving one copy of the source). Thus, you are always simply compiled from a modern assembly, whether it be debugging or release (or even others). There is no possibility of confusion.

EDIT

Sketch above.

 src := 1.c 2.c 3.c bare-objs := ${src:%.c=%.o} release-objs := ${bare-objs:%=Release/%} debug-objs := ${bare-objs:%=Debug/%} Release/prog: ${release-objs} Debug/prog: ${debug-objs} ${release-objs}: Release/%.o: %.c # You gotta lurve static pattern rules gcc -c $< -o $@ ${debug-objs}: Debug/%.o: %.c gcc -c $< -o $@ Release/prog Debug/prog: gcc $^ -o $@ .PHONY: all all: Release/prog ; echo $@ Success .PHONY: debug debug: Debug/prog ; echo $@ Success 

(Disclaimer: Unverified and not even executed via make.)

There you go. It's even -j safe, so you can do make -j5 all debug . There is a lot of obvious boiler stove just screaming for cleaning.

+2
source share

Saving options for sets of object files (as in bobbogo's solution) is probably the best way, but if for some reason you don't want to do this, you can use empty files as markers to indicate how you last built the executable file:

 %-marker: @rm -f $(OBJECTS) *-marker @touch $@ debug: GCCFLAGS += -ggdb debug: SOMEOTHERFLAG = WHATEVER all debug: % : %-marker @echo making $@ @$(MAKE) -S GCCFLAGS='$(GCCFLAGS)' SOMEOTHERFLAG='$(SOMEOTHERFLAG)' main 

There are other variations of this idea; you may have a small file containing the flag settings that the make file will create, and include . That would be smart, but not really cleaner than that.

+1
source share

The only clean solution is to include the difference in the target names. For example. you can define the variable $(DEBUG) and use it sequentially for all purposes that depend on the compilation stage.

0
source share

All Articles