[Buildroot] [git commit branch/next] core/pkg-kconfig: ensure kconfig base and fragment files exist

Thomas Petazzoni thomas.petazzoni at free-electrons.com
Sat Aug 8 10:56:43 UTC 2015


commit: http://git.buildroot.net/buildroot/commit/?id=7148361652c5b40f32e1474119cc8be1fe0d66a9
branch: http://git.buildroot.net/buildroot/commit/?id=refs/heads/next

Even though we do have a dependency chain back to each of the kconfig
base and fragment files:

    $$($(2)_DIR)/.config: $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES)

we can't rely on it to ensure they are all present, because they all have
this rule:

    $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES): | $(1)-patch

but since this rule has no prerequisite (only build-order, but that does
not count in this case) and no recipe, make will believe each missing
file to be a PHONY target, and will always run targets that depend on
it:
    https://www.gnu.org/software/make/manual/make.html#Force-Targets

So, that means a missing kconfig base or fragment file would always
cause the rule to generate .config to be run at each invocation, which
in turn would cause a rebuild of the kernel, which is clearly not what
we want.

Since this is expected make behaviour, we can well end up with a missing
Kconfig base or fragment. To avoid continuously rebuilding the kernel in
that case, we must check those files exist by ourselves, and error out
if any one of them is missing.

One would expect we check for them right in their dependency rule, like
so:

    $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES): | $(1)-patch
        [ -f $(@) ] || {echo Missing $(@) >&2; exit 1; }

but that does not work, as only the first target is tested for. That
check msut be turned into a loop explicitly testing all files, like so:

    $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES): | $(1)-patch
        for f in $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES); do \
            [ -f $(@) ] || {echo Missing $$$${f} >&2; exit 1; }; \
        done

Signed-off-by: "Yann E. MORIN" <yann.morin.1998 at free.fr>
Cc: Floris Bos <bos at je-eigen-domein.nl>
Cc: Thomas De Schampheleire <patrickdepinguin at gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
---
 package/pkg-kconfig.mk |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/package/pkg-kconfig.mk b/package/pkg-kconfig.mk
index e65c6f9..e441548 100644
--- a/package/pkg-kconfig.mk
+++ b/package/pkg-kconfig.mk
@@ -38,8 +38,24 @@ $(2)_KCONFIG_FIXUP_CMDS ?=
 $(2)_KCONFIG_FRAGMENT_FILES ?=
 
 # The config file as well as the fragments could be in-tree, so before
-# depending on them the package should be extracted (and patched) first
+# depending on them the package should be extracted (and patched) first.
+#
+# Since those files only have a order-only dependency, make would treat
+# any missing one as a "force" target:
+#   https://www.gnu.org/software/make/manual/make.html#Force-Targets
+# and would forcibly any rule that depend on those files, causing a
+# rebuild of the kernel each time make is called.
+#
+# So, we provide a recipe that checks all of those files exist, to
+# overcome that standard make behaviour.
+#
 $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES): | $(1)-patch
+	for f in $$($(2)_KCONFIG_FILE) $$($(2)_KCONFIG_FRAGMENT_FILES); do \
+		if [ ! -f "$$$${f}" ]; then \
+			printf "Kconfig fragment '%s' for '%s' does not exist\n" "$$$${f}" "$(1)"; \
+			exit 1; \
+		fi; \
+	done
 
 # The specified source configuration file and any additional configuration file
 # fragments are merged together to .config, after the package has been patched.


More information about the buildroot mailing list