Go to file
Nevo Hed e7dee76f9b Makefile: fix use of many br2-external trees
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>
2023-01-12 11:18:45 +01:00
arch arch/arch.mk.xtensa: relax check on overlay file to apply only to internal toolchains 2022-11-13 22:32:31 +01:00
board board/freescale/imx6ulevk/readme.txt: update broken url 2023-01-03 22:22:27 +01:00
boot boot/edk2: refine license 2022-11-23 22:38:33 +01:00
configs configs/ls1028ardb: update codeaurora URLs to github 2023-01-04 08:52:04 +01:00
docs Update for 2022.11 2022-12-05 08:23:19 +01:00
fs fs/cpio: don't fail systems without /dev/null 2022-11-01 21:44:49 +01:00
linux {linux, linux-headers}: bump 5.15.x / 6.{0, 1}.x series 2023-01-04 14:16:35 +01:00
package package/wireshark: add libcap optional dependency 2023-01-11 20:42:47 +01:00
support support/tests: print failed command and output on assertRunOK error 2023-01-01 19:34:23 +01:00
system package/systemd: add setting for systemd default.target 2022-05-02 22:58:44 +02:00
toolchain toolchain/Config.in: fix check-package warning 2022-11-25 21:31:56 +01:00
utils utils/scancpan: bump required perl version 2022-12-21 20:38:06 +01:00
.clang-format .clang-format: initial import from Linux 5.15.6 2022-01-01 15:01:13 +01:00
.defconfig arch: remove support for sh64 2016-09-08 22:15:15 +02:00
.flake8 Revert ".flake8: fix check for 80/132 columns" 2021-01-02 17:38:20 +01:00
.gitignore
.gitlab-ci.yml utils/checkpackagelib/lib_sysv: run shellcheck 2022-02-06 18:27:03 +01:00
.shellcheckrc utils/check-package: improve shellcheck reproducibility 2022-07-25 23:52:47 +02:00
CHANGES Update for 2022.11 2022-12-05 08:23:19 +01:00
Config.in Config.in: update default CPAN mirror to https, update mirrors URL 2022-12-21 20:41:51 +01:00
Config.in.legacy package/rabbitmq-server: drop package 2022-12-03 15:41:49 +01:00
COPYING
DEVELOPERS DEVELOPERS: add Julien Olivain for package/gnupg2 2023-01-10 19:41:53 +01:00
Makefile Makefile: fix use of many br2-external trees 2023-01-12 11:18:45 +01:00
Makefile.legacy Remove BR2_DEPRECATED 2016-10-15 23:14:45 +02:00
README docs: move the IRC channel away from Freenode 2021-05-29 22:16:23 +02:00

Buildroot is a simple, efficient and easy-to-use tool to generate embedded
Linux systems through cross-compilation.

The documentation can be found in docs/manual. You can generate a text
document with 'make manual-text' and read output/docs/manual/manual.text.
Online documentation can be found at http://buildroot.org/docs.html

To build and use the buildroot stuff, do the following:

1) run 'make menuconfig'
2) select the target architecture and the packages you wish to compile
3) run 'make'
4) wait while it compiles
5) find the kernel, bootloader, root filesystem, etc. in output/images

You do not need to be root to build or run buildroot.  Have fun!

Buildroot comes with a basic configuration for a number of boards. Run
'make list-defconfigs' to view the list of provided configurations.

Please feed suggestions, bug reports, insults, and bribes back to the
buildroot mailing list: buildroot@buildroot.org
You can also find us on #buildroot on OFTC IRC.

If you would like to contribute patches, please read
https://buildroot.org/manual.html#submitting-patches