3
votes

I have the following make file target:

all_libs:
$(foreach module, $(LIBMODULES), cd $(module) && $(MAKE) lib; )

This executes one at a time, despite using make -j. Many if the libraries contain only a few source files, so many of the available CPU cores get under-utilized. How to make this compile all libraries in parallel?

I tried the suggestion from Tom Tanner in the answers section and it does not work. There is a problem with the 'cd' part. I get the following output after I added @echo $(LIBMODULES) before the cd command:

15:25:15 **** Build of configuration Rev3 Debug for project p4080ds ****
make -m all_libs 
/cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/source/utils /cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/source/dda /cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/source/mqtpcid_app /cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/source/mqtpcid_core /cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/source/mqtpcid_drv /cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/source/mqtpcid_lib
cd . && /cygdrive/d/Cook/OSE5.7_PPC/cygwin/bin/make lib
make[1]: Entering directory `/cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/examples/p4080ds'
make[1]: Leaving directory `/cygdrive/y/MCT_Comp/comp/tools/cdk/OSE/OSE5.7_PPC/examples/p4080ds'
make[1]: *** No rule to make target `lib'.  Stop.
make: *** [all_libs] Error 2

You can see the $(@D) is translating to '.' and not the current element of the $(LIBMODULES) variable.

Update: According to make $(@D) translates to:

‘$(@D)’
The directory part of the file name of the target, with the trailing slash removed. 
If the value of ‘$@’ is dir/foo.o then ‘$(@D)’ is dir. This value is . if ‘$@’ does 
not contain a slash.
2

2 Answers

1
votes

Have you tried this?

$(LIBMODULES):
    $(MAKE) -C $@ lib

The -C tells make to change to the directory. It looks like $LIBMODULES is already a list of directories so you don't need use $(@D) to get a directory name.

0
votes

You'd want something like:

all_libs: $(LIBMODULES)

$(LIBMODULES):
    cd $(@D) && $(MAKE) lib

Assuming that firstly, those targets don't clash with something else, and secondly that it is OK to do recursive builds like that, which is open to question. Recursive make is not a very good idea (look up 'recursive make considered harmful' on google for all the reasons).