@@ -1010,13 +1010,27 @@ oldconfig syncconfig olddefconfig: $(BUILD_DIR)/buildroot-config/conf outputmake
defconfig: $(BUILD_DIR)/buildroot-config/conf outputmakefile
@$(COMMON_CONFIG_ENV) $< --defconfig$(if $(DEFCONFIG),=$(DEFCONFIG)) $(CONFIG_CONFIG_IN)
-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/$$@ \
+ALL_DEFCONFIGS :=
+# $1: defconfig name with trailing _defconfig
+# $2: br2-external directory, without traiing /configs/
+define defconfig_rule
+ifeq ($$(filter $(2),$$(ALL_DEFCONFIGS)),)
+# Override the BR2_DEFCONFIG from COMMON_CONFIG_ENV with the actual defconfig
+$(2): $$(BUILD_DIR)/buildroot-config/conf outputmakefile
+ $$(Q)$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@ \
$$< --defconfig=$(1)/configs/$$@ $$(CONFIG_CONFIG_IN)
+ALL_DEFCONFIGS += $(2)
+endif
endef
-$(eval $(foreach d,$(call reverse,$(TOPDIR) $(BR2_EXTERNAL_DIRS)),$(call percent_defconfig,$(d))$(sep)))
+$(eval \
+ $(foreach d, \
+ $(call reverse,$(TOPDIR) $(BR2_EXTERNAL_DIRS)), \
+ $(foreach c, \
+ $(wildcard $(d)/configs/*_defconfig $(d)/configs/.*_defconfig), \
+ $(call defconfig_rule,$(d),$(notdir $(c)))$(sep) \
+ ) \
+ ) \
+)
update-defconfig: savedefconfig
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). One of the rationale behind this code, is that we want the defconfig files from br2-external trees further down the list, to override defconfig files from those earlier in the list, even overriding the defconfig files from Buildroot itself. We fix that by only creating explicit rules for defconfig files. To keep the promise that later defconfig files override previous ones (which we do document in our manual), we need to memorise what defconfig file we already created a rule for, and only create a rule for the first-seen-in-reverse-order (aka the last one) defconfig. Since some people appear to be bold enough (or insane enough?) to use defconfig files that start with a dot, also handle those explictly. Fixes: #14996 Reported-by: David Lawson <david.lawson1@tx.rr.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr> --- Changes v1 -> v2: - keep comment - fix typo --- Makefile | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)