Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting 'foreach' to parallel build with make

Tags:

makefile

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.
like image 276
ShaneCook Avatar asked Dec 06 '25 05:12

ShaneCook


1 Answers

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.

like image 113
TrentP Avatar answered Dec 09 '25 14:12

TrentP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!