tools/Config.mk: speed up builds by caching the prefix-detection shells#18868
Merged
Merged
Conversation
Three `export VAR ?= $(shell ...)` assignments cause GNU make to
re-run the embedded ${shell ...} every time the variable is exported
to a recipe's environment. That spawns `tools/incdir` and
`tools/define` once per recipe, serialised through the master make
thread, which adds per recipe overhead to multi-job builds.
Wrap each with `ifeq ($(origin VAR),undefined)` + `:=` so the shell
call runs once at parse time while preserving the override semantics
of `?=`.
Measured impact on a 20-core build host is a ~26% speedup of wall
time.
Signed-off-by: Daniel Fanache <dan@rts.ro>
d444326 to
db91870
Compare
Contributor
Author
|
Yikes - the CI builds were not happy. The I've added a shell |
xiaoxiang781216
approved these changes
May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Currently, three top-level assignments in
tools/Config.mkuse the formexport VAR ?= $(... ${shell ...} ...)which produces a recursive/lazy variable, slowing down the build.The right-hand side is re-expanded - and the embedded
${shell ...}reruns every time the variable is used. Because these variables are alsoexported, make expands them once per recipe's environment, spawning thetools/incdir/tools/definehost helpers hundreds of times over a full build.This PR replaces the three lines with:
Here,
:=is simply-expanded, so the shell runs just once at parse time. Theifeq ...wrapper is meant to preserve the override semantics of?=(passingDEFINE_PREFIX=...on the make command line or as an env variable cancels the assignment).Impact
Developers and build systems: noticeably faster full builds on multi-core hosts; no behaviour change - the override semantics of
?=are preserved.Measured impact on a 20-core build host is a ~26% speedup of wall time, while testing a number of standard boards.
Testing
Host: Linux, 20-threads x86_64, arm-none-eabi-gcc 15.2.1, GNU make 4.4.1.
Methodology: three full clean builds per side (patched/unpatched), each preceded by
make distcleanand a freshconfigure.sh + olddefconfig. The patched and unpatched runs were taken back to back on the same host, with the same-j20invocation. The times reported in seconds are medians over the three runs; variance was always under 0.2s.Config 1:
raspberrypi-pico-2:nsh(rp23xx, Cortex-M33)Extra apps enabled to increase the number of recipes:
TESTING_OSTEST,SYSTEM_SYSTEM_TOP,TESTING_GETPRIME,BENCHMARKS_COREMARK,BENCHMARKS_DHRYSTONE,LIBC_FLOATINGPOINT.The elf was flashed to a Raspberry Pi Pico 2 W; ostest ran to completion with exit status 0.
Config 2:
imxrt1064-evk:netnsh(iMX RT 1064, Cortex-M7)Default config, no app overrides. No hardware test; build success only.
Larger scale impact and fix origins
This optimization came about by trying to speedup the build of a RP2350-based custom PX4-Autopilot board target, where the build time drops from 126.01s to 14.69s wall time (88% speedup, 8.6x quicker).
In PX4, NuttX is built through CMake and multiple isolated sub-makes are spawned (each NuttX library is a separate
add_custom_commandinvokingmake -C <libdir>and the wrappers resetMAKELEVEL=0probably to avoid jobserver collision). So here we can see a proportionally larger speed increase, because the bug fires per-sub-make rather than once.I am not including timing logs of the PX4 builds as evidence for now, just as context on how the cost of the existing inefficiency increases with build complexity from other projects including the OS.