I have a Makefile, which should when calling make just call make in a list of subdirectories. The subdirectories should not be automatically detected but are fine to be hard coded (Tool1, Package2, Submodule3 below). Furthermore, if I call make Tool1, Tool1 should be built (i.e. the directory names should be recognised as targets). At this top level I have no use for dependency checking, the Makefiles in the subdirectories take care of that. My current version looks like this:

subdirs := Tool1 Package2 Submodule3

.PHONY: all clean $(subdirs)



define makesubdir
  make -C $(1)

all: $(1)

define makesubdirclean
  make -C $(1) clean

clean: $(1)-clean

$(foreach SUBDIR,$(subdirs),$(eval $(call makesubdir,$(SUBDIR))))
$(foreach SUBDIR,$(subdirs),$(eval $(call makesubdirclean,$(SUBDIR))))

What I already considered:

  • I don't want a for loop in the all target, to allow parallel building with make -j. An older version read like:

    all: for DIR in $(subdirs); do make -C $$DIR ; done

  • The subdirectories should be defined only in one place, adding a new subdirectory should happen only on one place.

  • The subdirectories are .PHONY such that make gets called in them, regardless of the directory's timestamp.

  • I thought all: $(subdirs) would be easier to read than all: $(1) but that way only Tool1 got built.


It could be a matter of personal taste, but I use functions as the last resort. Consider

.PHONY: $(subdirs)

all: $(subdirs)
clean: $(subdirs)

    make -C $@ $(MAKECMDGOALS)
| improve this answer | |

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.