toolchain: allow using custom headers newer than latest known ones
authorVincent Fazio <vfazio@xes-inc.com>
Wed, 15 Jan 2020 18:29:07 +0000 (19:29 +0100)
committerPeter Korsgaard <peter@korsgaard.com>
Sat, 8 Feb 2020 19:25:10 +0000 (20:25 +0100)
When Buildroot is released, it knows up to a certain kernel header
version, and no later. However, it is possible that an external
toolchain will be used, that uses headers newer than the latest version
Buildroot knows about.

This may also happen when testing a development, an rc-class, or a newly
released kernel, either in an external toolchain, or with an internal
toolchain with custom headers (same-as-kernel, custom version, custom
git, custom tarball).

In the current state, Buildroot would refuse to use such toolchains,
because the test is for strict equality.

We'd like to make that situation possible, but we also want the user not
to be lenient at the same time, and select the right headers version
when it is known.

So, we add a new Kconfig blind option that the latest kernel headers
version selects. This options is then used to decide whether we do a
strict or loose check of the kernel headers.

Suggested-by: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
[yann.morin.1998@free.fr:
  - only do a loose check for the latest version
  - expand commit log
]
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Tested-by: Vincent Fazio <vfazio@xes-inc.com>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
package/linux-headers/Config.in.host
package/linux-headers/linux-headers.mk
support/scripts/check-kernel-headers.sh
toolchain/Config.in
toolchain/helpers.mk
toolchain/toolchain-external/pkg-toolchain-external.mk
toolchain/toolchain-external/toolchain-external-custom/Config.in.options

index cae56701e4818d2468f2c12f591c5fd292ce32ef..71d35dad7f6cc8ea1c180ac2610dfcbf510c76d0 100644 (file)
@@ -124,8 +124,11 @@ choice
          This is used to hide/show some packages that have strict
          requirements on the version of kernel headers.
 
+         If your kernel headers are more recent than the latest version
+         in the choice, then select the latest version.
+
 config BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_4
-       bool "5.4.x"
+       bool "5.4.x or later"
        select BR2_TOOLCHAIN_HEADERS_AT_LEAST_5_4
 
 config BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_3
index 2b7879c62f596e011d77bb455038f887feef728c..80a077537baad1e3f4b2a6a9e0b0f7c68e51e7b8 100644 (file)
@@ -136,11 +136,14 @@ define LINUX_HEADERS_INSTALL_STAGING_CMDS
 endef
 
 ifeq ($(BR2_KERNEL_HEADERS_VERSION)$(BR2_KERNEL_HEADERS_AS_KERNEL)$(BR2_KERNEL_HEADERS_CUSTOM_TARBALL)$(BR2_KERNEL_HEADERS_CUSTOM_GIT),y)
+# In this case, we must always do a 'loose' test, because they are all
+# custom versions which may be later than what we know right now.
 define LINUX_HEADERS_CHECK_VERSION
        $(call check_kernel_headers_version,\
                $(BUILD_DIR),\
                $(STAGING_DIR),\
-               $(call qstrip,$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)))
+               $(call qstrip,$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\
+               loose)
 endef
 LINUX_HEADERS_POST_INSTALL_STAGING_HOOKS += LINUX_HEADERS_CHECK_VERSION
 endif
index 9d23c00feb18a7fbe41c69931bb2794fa5a02685..d1864cb05ede2fbe1d67c5430767b7ccfa3622b3 100755 (executable)
@@ -1,9 +1,25 @@
 #!/bin/sh
 
+# This script (and the embedded C code) will check that the actual
+# headers version match the user told us they were:
+#
+# - if both versions are the same, all is well.
+#
+# - if the actual headers are older than the user told us, this is
+#   an error.
+#
+# - if the actual headers are more recent than the user told us, and
+#   we are doing a strict check, then this is an error.
+#
+# - if the actual headers are more recent than the user told us, and
+#   we are doing a loose check, then a warning is printed, but this is
+#   not an error.
+
 BUILDDIR="${1}"
 SYSROOT="${2}"
 # Make sure we have enough version components
 HDR_VER="${3}.0.0"
+CHECK="${4}"  # 'strict' or 'loose'
 
 HDR_M="${HDR_VER%%.*}"
 HDR_V="${HDR_VER#*.}"
@@ -28,20 +44,24 @@ ${HOSTCC} -imacros "${SYSROOT}/usr/include/linux/version.h" \
           -x c -o "${EXEC}" - <<_EOF_
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 int main(int argc __attribute__((unused)),
          char** argv __attribute__((unused)))
 {
-    if((LINUX_VERSION_CODE & ~0xFF)
-        != KERNEL_VERSION(${HDR_M},${HDR_m},0))
+    int ret = 0;
+    int l = LINUX_VERSION_CODE & ~0xFF;
+    int h = KERNEL_VERSION(${HDR_M},${HDR_m},0);
+
+    if(l != h)
     {
         printf("Incorrect selection of kernel headers: ");
         printf("expected %d.%d.x, got %d.%d.x\n", ${HDR_M}, ${HDR_m},
                ((LINUX_VERSION_CODE>>16) & 0xFF),
                ((LINUX_VERSION_CODE>>8) & 0xFF));
-        return 1;
+        ret = ((l >= h) && !strcmp("${CHECK}", "loose")) ? 0 : 1;
     }
-    return 0;
+    return ret;
 }
 _EOF_
 
index 858121d2c5c3189af66ecd134af834004caf4b2b..973c03254fb55c03f18f8fd6fb73c4e51e95252f 100644 (file)
@@ -457,6 +457,14 @@ config BR2_TOOLCHAIN_HEADERS_AT_LEAST_5_3
 config BR2_TOOLCHAIN_HEADERS_AT_LEAST_5_4
        bool
        select BR2_TOOLCHAIN_HEADERS_AT_LEAST_5_3
+       select BR2_TOOLCHAIN_HEADERS_LATEST
+
+# This should be selected by the latest version, above, to indicate that
+# Buildroot does not know of more recent headers than the ones selected.
+# This allows using toolchains with headers more recent than Buildroot
+# knows about, while still enforcing strict check for older headers.
+config BR2_TOOLCHAIN_HEADERS_LATEST
+       bool
 
 # This order guarantees that the highest version is set, as kconfig
 # stops affecting a value on the first matching default.
index 996cc70d441b107b2df3df38d522da87aa3f234f..2c2a987c3eeefc2d514ff53f199794783e633093 100644 (file)
@@ -161,9 +161,13 @@ copy_toolchain_sysroot = \
 # $1: build directory
 # $2: sysroot directory
 # $3: kernel version string, in the form: X.Y
+# $4: test to do for the latest kernel version, 'strict' or 'loose'
+#     always 'strict' if this is not the latest version.
 #
 check_kernel_headers_version = \
-       if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3); then \
+       if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) \
+               $(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \
+       then \
                exit 1; \
        fi
 
index 1c43409514313914b9fb8aa3a70c9ecfa40ee7db..b01082aadd027e526f0101dfc98844b1da29ff35 100644 (file)
@@ -542,7 +542,8 @@ define $(2)_CONFIGURE_CMDS
        $$(call check_kernel_headers_version,\
                $$(BUILD_DIR)\
                $$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC)),\
-               $$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST))); \
+               $$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\
+               $$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict)); \
        $$(call check_gcc_version,$$(TOOLCHAIN_EXTERNAL_CC),\
                $$(call qstrip,$$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \
        if test "$$(BR2_arm)" = "y" ; then \
index 9680509a13e58c6bcffea693dcd9086f06c9b91d..302f6babac6d0560e5a208a73459a1548dde7602 100644 (file)
@@ -112,8 +112,11 @@ choice
            m = ( LINUX_VERSION_CODE >> 8  ) & 0xFF
            p = ( LINUX_VERSION_CODE >> 0  ) & 0xFF
 
+         If your toolchain uses headers newer than the latest version
+         in the choice, then select the latest version.
+
 config BR2_TOOLCHAIN_EXTERNAL_HEADERS_5_4
-       bool "5.4.x"
+       bool "5.4.x or later"
        select BR2_TOOLCHAIN_HEADERS_AT_LEAST_5_4
 
 config BR2_TOOLCHAIN_EXTERNAL_HEADERS_5_3