I have a "lib" directory in my applications main directory, which contains an arbitrary number of subdirectories, each having its own Makefile.
I would like to have a single Makefile in the main directory, that calls each subdirectory's Makefile. I know this is possible if I manually list the subdirs, but I would like to have it done automatically.
I was thinking of something like the following, but it obviously does not work. Note that I also have clean, test, etc. targets, so % is probably not a good idea at all.
LIBS=lib/*
all: $(LIBS)
%:
(cd $@; $(MAKE))
Any help is appreciated!
What if you want to call different targets than all in an unknown number of subdirectories?
The following Makefile uses macros so create a forwarding dummy-target for a number of subdirectories to apply the given target from the command line to each of them:
Hope this helps. Really helpfull when dealing with paralelism: make -j12 clean all in a tree with makefiles having these targets... As always: playing with make is dangerous, different meta-levels of programming are too close together ,-)
The following will work with GNU
make
:If there might be something other than directories in
lib
, you could alternatively use:To address the multiple targets issue, you can build special targets for each directory, then strip off the prefix for the sub-build:
There is also a way of listing sub-directories with gmake commands only, without using any shell commands:
This will list all sub-directories with trailing
'/'
. To remove it you can use the substitute pattern:Then to actually create rules executing makefiles in each sub-directory you can use a small trick - a phony target in a non-existent directory. I think in this case an example will tell more than any explanation:
Basically, target
'all'
lists all sub-directories as prerequisites. For example, ifLIB_DIRS
containedlib/folder1 lib/folder2
then the expansion would look like this:Then 'make', in order to execute rule
'all'
, tries to match each prerequisite with an existing target. In this case the target is'make-rule/%:'
, which uses'$*'
to extract the string after'make-rule/'
and uses it as argument in the recipe. For example, the first prerequisite would be matched and expanded like this: