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?

1 Answer 1


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
  • 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, 2016 at 19:21
  • I was looking along the line of targets and rules, if possible.
    – Bichoy
    Mar 14, 2016 at 19:23
  • I added a possibility without a for loop to my answer.
    – meuh
    Mar 14, 2016 at 20:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .