I am trying to write a recursive clean target for GNU Makefile on OS X (GNU Make 3.81 - from XCode). Following GNU Make documentation, I came up with the following:

Main Makefile

ALLSUBMAKES=$(wildcard ./*/Makefile)
ALLSUBDIRS=$(patsubst %/Makefile,%,$(ALLSUBMAKES))
.PHONY: submakes clean $(ALLSUBDIRS)

submakes: $(ALLSUBDIRS)

clean: $(ALLSUBDIRS)

    $(MAKE) -C $@

Submake Makefiles

    #do something here

    #some clean operation

The problem:

I find that $(MAKE) passes only the make executable full path name ignoring targets and all other command line options (like -j5 for example). All submakes end up executing the mainTarget when I issue make clean on the top level. What is the right way to implement such recursive clean targets? Or how to pass target along with all command line arguments to submakes?


The way I've seen this done is to collect all the targets into one rule that goes into each subdir:

build clean install:
     @for dir in $(ALLSUBDIRS); do $(MAKE) -C "$$dir" $@; done

You might be able use do something with the builtin variable MAKEFLAGS which is automatically exported to sub-makes.

You could try suffixing the desired action to the target, then splitting this pseudo target to extract the action again later:

default: $(addsuffix .default,$(ALLSUBDIRS))
clean:   $(addsuffix .clean,$(ALLSUBDIRS))

        $(MAKE) -C $*
        $(MAKE) -C $* clean
| improve this answer | |
  • Thanks for your answer. I have seen this done before. I was hoping for something without for loop but it doesn't seem possible. – Bichoy Mar 14 '16 at 19:21
  • I was looking along the line of targets and rules, if possible. – Bichoy Mar 14 '16 at 19:23
  • I added a possibility without a for loop to my answer. – meuh Mar 14 '16 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.