3

I have a simple makefile with 3 build rules:

  1. clean (that cleans the .o)
  2. debug (compiles my code with debgging stuff)
  3. release (compiles my code with optimization stuff)

sometimes I want to switch between debug mode and release so I would issue this

make clean debug -j8

or

make clean release -j8

that has a drawback because while it's doing the clean stuff, the -j8 allows make to jump some command since the .o are still there Then those .o are removed by the clean rule and the compiler complains because it can't find those .o

I could do something like

make clean; make debug -j8

but since I use an odd makefile in another dir, the command becomes

make -C ../src -f nMakefile clean ; make -C ../src -f nMakefile -j8 release

that is more annoying. I was wondering if there was an hiddedn-guru-mode-rule that allows me to do it in one line

Hope it's clear enough...

bibi
  • 3,671
  • 5
  • 34
  • 50
  • 3
    Creating two new targets would solve it. I mean clean_release and clean_debug. Also you should not need to clean when switching if you direct objects to different sub-directories depending on release/debug. I think having different subdirs is the way you should go. – user2672165 Mar 25 '14 at 20:24
  • do you mean adding clean_release: clean release – bibi Mar 26 '14 at 19:10
  • I was wondering if "order-only prerequisites" (https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html) could be used to solve this, but haven't managed to get it working so far. – oliver Mar 09 '18 at 13:44

2 Answers2

2

I needed to solve this very same problem, and the solution I came up was to parse the MAKECMDGOALS for clean, and dispatch a shell command to do the actual cleaning work; RATHER than clean the build as a target. This way, any MAKECMDGOALS that include "clean" will clean the build as part of that build, first, sequentially, rather than clean running asynchronously as its own target.

-include $(deps)
bin/%.o : %.cpp
    @mkdir -p $@D
    g++ $(flags) $(includes) -MMD -c $< -o $@

.PHONY : clean
clean:
    @echo rm -rf bin/

ifneq ($(filter clean,$(MAKECMDGOALS)),)
    $(shell rm -rf bin/)
endif
payo
  • 4,501
  • 1
  • 24
  • 32
1

As I stated above, the normal practice is to have different sub directories for the object files. As you are running in parallel I would think you need to enforce serial execution so that clean is completed before release. One way of doing it could be:

clean_release: clean
    +@$(MAKE) -s --no-print-directory release

or if you prefer

clean_release:
    +@$(MAKE) -s --no-print-directory clean && $(MAKE) -s --no-print-directory release
user2672165
  • 2,986
  • 19
  • 27
  • 2
    Simple, but this doesn't work if you need to specify "clean" along with several other targets manually specified on the command line - like how the author specified. E.g. what if he wants to `make clean debug release -j8` ? (Atmel Studio is an example of an IDE that forces you to do it this way, BTW...) I think the answer from Eldar at http://stackoverflow.com/questions/8496135/parallel-makefile-require-depency-ordering is a good way to do it... it just serializes all targets passed on command line - doesn't care about the names or how many. – James Johnston Jan 08 '15 at 20:46