linux/linux.mk: forcibly (re)enable Make jobserver for linux-rebuild-with-initramfs target

Commit 0b9efc991f ("linux: use BR2_MAKE", 2023-04-10) replaced $(MAKE)
with $(BR2_MAKE) in a number of recipes. As a consequence, the child
make is unable to discover the job server, in some cases. In those
cases, we get a warning such as:

> warning: jobserver unavailable: using -j1. Add `+' to parent make rule.

See [1] and [2].

Falling back to single job can make build considerably longer.
This longer build time issue can be reproduced in specific
conditions. This situation happens when:

1. The top GNU Make is using a "pipe" jobserver.
   This is the default when GNU Make <= 4.3 is used (and v4.3 is the
   version inside the current Buildroot Docker reference image).
   Make > 4.3 changed the default jobserver style to "fifo".
   See [3][4]. With Make > 4.3, the issue can be reproduced by
   calling "make --jobserver-style=pipe ...".
2. The root filesystem is an initramfs linked into the Kernel
  (i.e. using the config BR2_TARGET_ROOTFS_INITRAMFS=y)
3. Buildroot per-package directories is used
  (i.e. using the config BR2_PER_PACKAGE_DIRECTORIES=y)
4. The build is made in parallel, with 2 or more jobs. For example:
   make -j$(nproc)

Overall, the issue can be reproduced with the commands:

utils/docker-run
cat >.config <<EOF
BR2_aarch64=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_PER_PACKAGE_DIRECTORIES=y
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y
BR2_TARGET_ROOTFS_INITRAMFS=y
EOF
make olddefconfig
make -j$(nproc)

The Linux Kernel is built once (with a fake empty initramfs cpio
image), when build log is showing ">>> linux 7.2.6 Building". Then,
at the end of the Buildroot build, once the CPIO filesystem is
complete, it is integrated inside the Kernel with an extra "make"
invocation when the build log shows
">>>   Rebuilding kernel with initramfs".

This second kernel "make" is not expected to rebuild the whole
kernel, since compiled objects from the first compilation are still
here. However, in the described conditions, the second kernel is
fully rebuilt. This is an undesired behaviour. The Make jobserver
issue adds up to that: this second full kernel is rebuilt with only
one job, which can significantly increase the build time.

Running the previous example on a host with 128 CPUs:
without this change, build takes 1h5m,
with this change, build takes 7m.

Note: using GNU Make >= 4.4 (with a fifo jobserver style by default)
or removing per-package directories no longer produces the issue.
For reference, running the example, without this change and without
per-package directories on the same host, the build takes 10 mins.

This commit improves the situation by prefixing the recipe with "+",
to inform the parent Make that $(BR2_MAKE) can deal with the job
server. This will give a chance to do jobs in parallel, in general.

Note: the pkg-generic.mk infra already has '+' for _BUILD_CMDS, which is
why other $(BR2_MAKE) invocations in linux.mk does not need this '+'.
See [5].

[1] https://www.gnu.org/software/make/manual/html_node/Error-Messages.html
[2] https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html
[3] https://www.gnu.org/software/make/manual/html_node/Options-Summary.html#index-_002d_002djobserver_002dstyle
[4] https://cgit.git.savannah.gnu.org/cgit/make.git/commit/?id=7ad2593b2d2bb5b9332f4444d8bf93ac6f958bc6
[5] 069b33a30e

Cc: Arnout Vandecappelle <arnout@mind.be>
Cc: Oleg Lyovin <ovlevin@sberdevices.ru>
Cc: buildroot@buildroot.org
Signed-off-by: Laszlo Ersek <laszlo.ersek@arm.com>
[Julien: extend commit log]
Signed-off-by: Julien Olivain <ju.o@free.fr>
(cherry picked from commit 86a56dcc17)
Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
This commit is contained in:
Laszlo Ersek
2026-07-30 20:06:24 +02:00
committed by Raphaël Mélotte
parent ec746f6b57
commit 31feeffd69

View File

@@ -692,7 +692,7 @@ linux-rebuild-with-initramfs: rootfs-cpio
linux-rebuild-with-initramfs:
@$(call MESSAGE,"Rebuilding kernel with initramfs")
# Build the kernel.
$(LINUX_MAKE_ENV) $(BR2_MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) $(LINUX_TARGET_NAME)
+$(LINUX_MAKE_ENV) $(BR2_MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) $(LINUX_TARGET_NAME)
$(LINUX_APPEND_DTB)
# Copy the kernel image(s) to its(their) final destination
$(call LINUX_INSTALL_IMAGE,$(BINARIES_DIR))