The top level Makefile in buildroot has a recursive rule which causes
the appearance of a hang as the number of directories in BR2_EXTERNAL
increases. When the number of directories in BR2_EXTERNAL is small, the
recursion occurs, but make detects the recursion and determines the
target does not have to be remade. This allows make to progress.
This is the failing rule:
define percent_defconfig
# Override the BR2_DEFCONFIG from COMMON_CONFIG_ENV with the new defconfig
%_defconfig: $(BUILD_DIR)/buildroot-config/conf $(1)/configs/%_defconfig outputmakefile
@$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@ \
$$< --defconfig=$(1)/configs/$$@ $$(CONFIG_CONFIG_IN)
endef
$(eval $(foreach d,$(call reverse,$(TOPDIR) $(BR2_EXTERNAL_DIRS)),$(call percent_defconfig,$(d))$(sep)))
The rule for %defconfig is created for each directory in BR2_EXTERNAL.
When the rule is matched, the stem is 'defconfig_name'. The second
prerequisite is expanded to $(1)/configs/defconfig_name_defconfig. The
rule, and all of the other rules defined by this macro, are invoked
again, but the stem is now $(1)/configs/defconfig_name_defconfig. The
second prerequisite is now expanded to
$(1)/configs/($1)/configs/defconfig_name_defconfig. This expansion
continues until make detects the infinite recursion.
With up to 5 br2-external trees, the time is very small, so that it is
not noticeable. But starting with 6 br2-external trees, the time is
insanely big (so much so that we did not even let it finish after it ran
for hours); see timings toward the end of the commit log.
We fix that by adding a single %_defconfig rule, which is now rsponsible
to find the actual defconfig file that triggered the rule, by iterating
on the reverse list of br2-external trees and then in main tree.
Of course, now, there is no way for make to warn that there is no such
defconfig, as it is no longer part of the prerequisites of the rule. So,
we delegate to the recipe the responsibility to check for that.
Timing (seconds) of `make pc_x86_64_bios_defconfig` with 1..1000
external trees, with make 4.2.1 (* with make 4.3), on a Core i7-7700HQ:
#trees Before After
1 0.312 0.319
2 0.319 0.323
3 0.325 0.327
4 0.353 0.339
5 0.993 0.349
6 1.26* 0.347
7 9.10* 0.362
8 85.93* 0.360
9 n/a 0.373
10 n/a 0.374
50 n/a 0.738
100 n/a 1.228
500 n/a 7.483
1000 n/a 16.076
How to reproduce:
#!/usr/bin/env bash
N="${1:-1000}"
for i in $(seq 1 1000); do
[ -d "br2-external/${i}/configs" ] && break
mkdir -p br2-external/${i}/configs
touch br2-external/${i}/{Config.in,external.mk}
echo "name: BR_TEST_${i}" >br2-external/${i}/external.desc
touch br2-external/${i}/configs/foo{,_${i}}_defconfig
done
time make \
BR2_EXTERNAL="$(
for i in $(seq 1 ${N}); do
printf '%s\n' "$(pwd)/br2-external/${i}"
done
)" \
foo_1_defconfig
Notes: the timings are very dependent on how much the CPU is otherwise
loaded, but having a multi-core CPU slightly loaded helps maintain a
high frequency on the siblings, and that can reduce the above timings
in half! Best to try on an otherwise-idle system.
Fixes: #14996
Reported-by: David Lawson <david.lawson1@tx.rr.com>
Signed-off-by: Nevo Hed <nhed+buildroot@starry.com>
[yann.morin.1998@free.fr:
- split long foreach
- drastically extend the commit log
- provide reproducer script and redo timings
]
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit e6195c5304)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
To generate the glibc locale data, we call into a recursive Makefile,
so as to generate locales in parallel. This is done as part of a
target-finalize hook.
However, that hook is registered after all packages have been parsed,
and as such, it maye be registered after hooks defined in packages.
Furthermore, the expansion of target-finalize hooks is done in a recipe,
so it is not easy to understand whether this generates a "simple" rule
or not.
As a consequence, despite the use of $(MAKE), make may not notice that
the command is a recursive call, and will decide to close the jobserver
file-descriptors, yielding warnings like:
make[2]: warning: jobserver unavailable: using -j1. Add '+' to
parent make rule.
This causes the lcoale data to not be generated in parallel, which is
initially all the fuss about using a sub-makefile...
So, do as suggested, and prepend the hook with a '+', so that it is
explicit to make that it should not close its jobserver fds.
Fixes: 6fbdf51596 (Makefile: Parallelize glibc locale generation)
Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Cc: Gleb Mazovetskiy <glex.spb@gmail.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit 4164ed24f2)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
When one is applying patches, it is pretty common to end up with .orig
and/or .rej files lying around. Unfortunately, our 'Config.*' match in
check-package ends up matching those files, causing false positives
when running "make check-package". To avoid this, this commit
excludes *.orig and *.rej files for the find logic used in the
check-package target.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit 7d0d3987e9)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
printvars returns nothing when VARS is not passed or empty. This is done
on purpose, see commit fd5bd12379 ("Makefile: printvars: don't print
anything when VARS is not set").
An error message making explicit what is required from the user in order
to use printvars is however better than silently doing nothing.
This adds a check for a non-empty VARS variable.
Cc: Quentin Schulz <foss+buildroot@0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit ec82347cde)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Commit 5c54c3ef3d (Makefile: workaround make 4.3 issue for 'printvars
and 'show-vars') did not fully fix the show-vars case, which still
segfaults.
Overall, show-vars generates a JSON blurb. That is supposed to be
machine-readable, so we do not care that the variables are sorted, so
we get rid of it to (slightly) simplify the code.
Then, we currently iterate twice on the list of variables: the first one
to filter-out the 'internal' variables, and the second one to filter
only the variables matching the pattern. We can do away by iterating
only once, and applying both filters at once.
Since we now have an 'and' condition, we can take advantage of it: when
none of the items in $(and) are empty, $(and) evaluates to the last
item, while it evaluates to empty if any of the items is empty. So we
can coalesce the $(if) and $(and) together: $(if $(and a,b),c) is
equivalent to: $(and a,b,c) ; this gains us one parentheses depth.
Finally, the cause for the segfault is an overly-long call to $(info).
Reducing that is not easy: we want to call clean-json on the whole of
the JSON blurb, so we can't emit the individual variables one by one, or
the trailing comma would not be trimmed away.
So, we go crazy: we just output each word from clean-json with $(info).
We can do that, because mk-json-str transforms all spaces in a string
to an escaped UTF-8 sequence, so we will never have spaces in values;
the keys are the variables, so they won't have spaces either; spaces in
the rest of the JSON blurb are totally optional, so we don't care how
many there are. We know there are spaces, because we explicitly
introduce some (after "expanded" or "raw", for example), so we should
never hit a too-big word for $(info) to print.
Thanks to Henri for the suggestion to push $(info) further inside the
macro.
Reported-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Roosen Henri <Henri.Roosen@ginzinger.com>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Tested-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
(cherry picked from commit 83f71e7ceb)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Event though the bug with make 4.3 has been reported and fixed, there
has not been a release of make with the fix for a long time, see [1].
As the root cause seems the 'filter' command cannot handle large
chunks of data, like .VARIABLES, we can workaround the problem by
using a foreach command over .VARIABLES, then use the filter command.
It might not be logical to program it that way, but at least the
functionality is now usable.
[1] https://savannah.gnu.org/bugs/?59093#comment10
Signed-off-by: Henri Roosen <henri.roosen@ginzinger.com>
[yann.morin.1998@free.fr: add comment to reference the bug]
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit 5c54c3ef3d)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Now that all hash files have been fixed, enable checking of hash
spacing in check-package.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
(cherry picked from commit 64f1603bb8)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
This commit adds support for a new type of graph, showing the timeline
of a build. It shows, with one line per package, when each of this
package steps started/ended, and therefore allows to see the
sequencing of the package builds.
For a fully serialized build like we have today, this is not super
useful (except to show that everything is serialized), but it becomes
much more useful in the context of top-level parallel build.
We chose to order the graph by the time-of-configure, as it is the
closest to the actual cascade-style of a true dependency graph, which is
tiny bit more complex to achieve properly. The actual result still looks
pretty good.
The graph-build make target is extended to also generate this new
timeline graph.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
[yann.morin.1998@free.fr:
- sort by start-of-configure time
- re-use existing colorsets (default or alternate)
- fix python2isms
- fix check-package
]
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit 5e8b01afd5)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
U-Boot looks for the environment variable DEVICE_TREE and uses its value if
set instead of the CONFIG_DEFAULT_DEVICE_TREE configuration option since
v2021.01, more specifically commit c0f1ebe9c1b9745e (binman: Allow selecting
default FIT configuration) - So unexport it like we do for other
"troublesome" environment variables to ensure consistent behaviour.
Reported-by: Neal Frager <nealf@xilinx.com>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
The variable 'KERNEL_ARCH' is actually a normalized version of
'ARCH'/'BR2_ARCH'. For example, 'arcle' and 'arceb' both become 'arc', just
as all powerpc variants become 'powerpc'.
It is presumably called 'KERNEL_ARCH' because the Linux kernel is typically
the first place where support for a new architecture is added, and thus is
the entity that defines the normalized name.
However, the term 'KERNEL_ARCH' can also be interpreted as 'the architecture
used by the kernel', which need not be exactly the same as 'the normalized
name for a certain arch'. In particular, for cases where a 64-bit
architecture is running a 64-bit kernel but 32-bit userspace. Examples
include:
* aarch64 architecture, with aarch64 kernel and 32-bit (ARM) userspace
* x86_64 architecture, with x86_64 kernel and 32-bit (i386) userspace
In such cases, the 'architecture used by the kernel' needs to refer to the
64-bit name (aarch64, x86_64), whereas all userspace applications need to
refer the, potentially normalized, 32-bit name.
This means that there need to be two different variables:
KERNEL_ARCH: the architecture used by the kernel
NORMALIZED_ARCH: the normalized name for the current userspace architecture
At this moment, both will actually have the same content. But a subsequent
patch will add basic support for situations described above, in which
KERNEL_ARCH may become overwritten to the 64-bit architecture, while
NORMALIZED_ARCH needs to remain the same (32-bit) case.
This commit replaces use of KERNEL_ARCH where actually the userspace arch is
needed. Places that use KERNEL_ARCH in combination with building of kernel
modules are not touched.
There may be cases where a package builds both a kernel module as userspace,
in which case it may need to know about both KERNEL_ARCH and
NORMALIZED_ARCH, for the case where they differ. But this is to be fixed on
a per-need basis.
Signed-off-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
Reviewed-by: Romain Naour <romain.naour@gmail.com>
[Arnout: Also rename BR2_KERNEL_ARCH to BR2_NORMALIZED_ARCH]
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Similar to other arch-specific strings, the 'KERNEL_ARCH' variable can be
determined from Config.in.<arch> files.
Besides aligning with similar strings, this also means simplification: the
big 'sed' covers several architectures not even supported by Buildroot.
Signed-off-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
Reviewed-by: Romain Naour <romain.naour@gmail.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
The seperation of the fields in the hash file should be 2 spaces for
consistency.
Since a large number of hash files still violate this rule, exclude it
from "make check-package" (and thus from CI).
Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
Cc: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
[Arnout:
- Move it to a separate class, so it can be excluded.
- Exclude it from "make check-package"
]
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
We introduce the concept of a pre-build script that works similar to
the already existing post-build and post-image scripts.
The pre-build script(s) are executed before the build commences. This
allows a user to run some preperatory tasks prior to the build.
Signed-off-by: Markus Mayer <mmayer@broadcom.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Make 4.3 is buggy and leads to a "Segmentation fault (core dumped)" when
calling 'make printvars' or 'make show-vars', so let's refuse to execute
those recipes if Make 4.3 by adding 'check-make-version' recipe as
depedendency of 'printvars' and 'show-vars' as suggested by Yann E. Morin.
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
The current printvars output suffers from a serious design flaw:
variables are not delimited, which makes it impossible to reliably
retrieve the value of variables; only variables that are known to
not contain a \n can be relatively safely extracted.
However, in some cases, it is important to be able to retrieve the
multi-line value of a variable, notably the CMDS or the hooks. One
such use-case (to follow in an unscheduled future) would be to hash
the variables that make up a package "configuration", and cache or
extract the files for that package to speed up the build.
Modeled after printvars and show-info, we introduce show-vars (what a
lack of imagination here) that outputs a json dictionary which keys are
the variable names, and for each variable, provides the raw and expanded
values.
Unlike printvars, we do not provide a way to get either the raw or
expanded value; both are systematically printed; a user will get just
the one is needs. Additionally, strings in JSON are quoted, so there is
no need to provide a way to quote variables; that would not make sense.
Note: for printvars, we require that the user provides an explicit
pattern to filter variables on. This is historical (see fd5bd12379,
Makefile: printvars: don't print anything when VARS is not set). The
underlying reasoning was that printvars is too "raw", and variables are
not well delimited, so printvars was mostly used to extract a few values
here and there, from scripts, or to quickly inspect a specific package's
variables during debugging.
But show-vars, although technically plain-text, being JSON, is not very
human-readable, and is mostly aimed at tools that will parse it with a
real JSON parser, and which will want to have a complete view of a lot
of variables at once. As such, and contrary to printvars, it makes sense
to report on all variables by default, unless the user explicitly
requested a subset.
As a final note: a lot of our variables only make sense in the context
of an actual make target. For example, a variable of package foo, that
contains $(@D)/bar, would expand to .../build/FOO-VERSION/bar. This is
because our CMDS and hooks are expanded as the recipe of a stamp file
that lies in the package build directory.
But for show-info, this falls flat on its face: it is not the stamp file
of a package, so there is no package directory, and show-info itself has
not directory part, so $(@D) expands to '.' (dot).
Additionally, some variables may contain calls to $(shell) (e.g. to call
pkg-config), and this also does not work with show-info.
These two issues make it impossible to emit the correct expanded value
of variables. To be noted: printvars has the exact same limitations for
the exact same reasons.
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Set HOSTCC_NOCCACHE and HOSTCXX_NOCCACHE only if they are not
set. This allows recursive calls to "make" to work as intended in the
presence of ccache. Such recursive calls to "make" can for example
happen if one calls "make legal-info" from within a post-build script,
to integrate some results of the legal-info output into the root
filesystem.
Without guarding these variables, a recursive invocation of make would
re-define
HOSTCC_NOCCACHE := $(HOSTCC)
and
HOSTCXX_NOCCACHE := $(HOSTCXX)
at a point in time when HOSTCC and HOSTCXX already point to ccache.
It used to work by "accident" until
ca6a2907c2 ("make: support: use `command
-v' instead of `which'"), due to how "which" was behaving when invoked
with multiple arguments. After switching to "command -v", which
behaves different with multiple arguments, this HOSTCC_NOCCACHE
redefinition problem surfaced. Even though
ca6a2907c2 has since then been reverted
for other reasons, it does make sense to guard the definition of
HOSTCC_NOCCACHE and HOSTCXX_NOCCACHE to not rely on a side-effect of
using "which".
Signed-off-by: Markus Mayer <mmayer@broadcom.com>
Reviewed-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Since a long time, we have a check-package check for patches. Make sure
that this check runs in 'make check-package', by including *.patch in
the find expression.
There are still a number of patches without SoB, and these are not so
trivial to fix, so for now, disable the SoB check.
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
[Ricardo: do not run check for SoB for now]
Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
The unmatched escaped single-quote lies in the middle of a few
function calls, so they too must be fake-closed to properly fix
colour highlighting in some editors.
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
xz compresses better than bzip2, and is (getting) more popular, so build
release tarballs as .tar.xz (in addition to .tar.gz) instead of .tar.bz2,
similar to how the kernel did ~8 years ago:
https://www.kernel.org/happy-new-year-and-good-bye-bzip2.html
-rw-r--r-- 1 peko peko 5,1M Dec 2 17:55 buildroot-2021.11-rc3.tar.xz
-rw-r--r-- 1 peko peko 5,7M Nov 30 18:15 buildroot-2021.11-rc3.tar.bz2
-rw-r--r-- 1 peko peko 6,8M Nov 30 18:15 buildroot-2021.11-rc3.tar.gz
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
`which' has been discontinued after 2.21 release in 2015 due this (git
repository is empty [1]) and version shipped in Debian produces warning
[2]:
/usr/bin/which: this version of `which' is deprecated; use `command -v' in scripts instead.
`command is POSIX [3] and supported on all common shells (bash, zsh,
dash, busybox sh, mksh).
Patch tested on dash as the default shell.
[1] https://git.savannah.gnu.org/cgit/which.git
[2] 3a8dd10b45
[3] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html
Signed-off-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Parallelizes locale generation based on `BR2_JLEVEL` setting.
Locale generation always runs during the finalize stage and can consume
a significant amount of time. Parallelizing it greatly reduces that time
on multi-core machines.
To parallelize it, we first invoke `localedef` for every locale in
parallel with the `--no-archive` option. This creates the intermediate
locale data instead of writing to the finally archive directly.
Then, we invoke `localedef` again once to create the archive from the
intermediate compiled locale data files.
We have to do it this way because `localedef` does not do any locking
when writing to the archive file, so calling it without `--no-archive`
concurrently could result in a corrupt archive file or an archive file
that is missing some locales.
While we're at it, make two additional improvements:
- Remove locale-archive before adding to it. Otherwise, repeated
applications of target-finalize will keep on growing the file.
- Sort the locales when creating locale-archive so its contents are
reproducible.
We use `find` to collect the installed locales rather than LOCALES. This
makes it possible for something else (skeleton, overlay, custom package)
to create and install additional locales and still have them added to
locale-archive.
Signed-off-by: Gleb Mazovetskiy <glex.spb@gmail.com>
[Arnout:
- Remove -j$(PARALLEL_JOBS), it's already part of $(MAKE)
- Remove HOST_DIR, TARGET_DIR, STAGING_DIR, they're already exported
- Extend commit message
]
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>