7

I have a makefile which calls multiple other makefiles.

I'd like to pass the -j param along to the other makefile calls.

Something like (make -j8):

 all:
     make -f libpng_linux.mk -j$(J)

Where $(J) is the value 8 from -j8. I absolutely swear I've done this before but I cannot locate my example.

$(MAKEFLAGS) seems to contain --jobserver-fds=3,4 -j regardless of what -j2 or -j8

Edit: Possible Solution:

Will post this as an answer soon.

It appears one solution to not worry about it. Include -j8 when you call the main makefile. The sub calls to make should look like this:

 all:
      +make -f libpng_linux.mk -j$(J)

Notice the "+" in front of make. I noticed make tossing a warning when I tried parallel builds: make[1]: warning: jobserver unavailable: using -j1. Add `+' to parent make rule.

Halsafar
  • 2,540
  • 4
  • 29
  • 52
  • Adding a default `-j` to a build is an "evil" thing to do. If set low it may not have a significant impact, but if set even moderately high it can create problems in a multi-user environment. Forcing developers to expressly choose a value forces them to make a choice -- hopefully based on how many people are on the machine, how it will impact currently running processes, etc. With that said, the "jobserver unavailable" warning happens under 2 circumstances: gmake cannot reliably determine that the sub-process is make, or you passed -j to a submake without `+` (as you noted). – Brian Vandenberg Dec 03 '14 at 22:27
  • Your warning is absolutely valid and should be taken i to consideration. Now this was awhile ago but I believe we got it so if -j is not set we default to j=1. If -j is set when calling the parent makefile it passes that j value to the children makefiles. – Halsafar Dec 05 '14 at 03:15

2 Answers2

6

Only certain flags go into $(MAKEFLAGS). -j isn't included because the sub-makes communicate with each other to ensure the appropriate number of jobs are occuring

Also, you should use $(MAKE) instead of make, since $(MAKE) will always evaluate to the correct executable name (which might not be make).

m42a
  • 1,322
  • 2
  • 10
  • 14
  • 1
    Actually, `-j` _is_ included. However, it appears only when _make_ is expanding a recipe. You won't see it for instance if you put a bare `$(info [${MAKEFLAGS}])` into the top level of your makefile. – bobbogo Jul 14 '15 at 16:39
1

"Do not do that" is not always the answer, but in this case it is, at least for GNU make.

GNU make parent process has an internal jobserver. If top-level Makefile is run with -j, subprocess makes will talk to the jobserver and read a parallelism level from it, without an explicit -j.

Ongoing coordination with parent's jobserver is much better for core utilization. For example, during the same build with -j6, parent could be running 2 jobs and the child 4 more, next moment both could be running 3 jobs each, then a parent would run 1 and the child 5.

Victor Sergienko
  • 13,115
  • 3
  • 57
  • 91