[Buildroot] [PATCHv4] toolchain: allow using custom headers newer than latest known ones

Vincent Fazio vfazio at xes-inc.com
Tue Jan 14 20:50:14 UTC 2020


Yann,

On 1/13/20 12:06 PM, Yann E. MORIN wrote:
> From: Vincent Fazio <vfazio at xes-inc.com>
>
> 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 at xes-inc.com>
> Signed-off-by: Vincent Fazio <vfazio at xes-inc.com>
> [yann.morin.1998 at free.fr:
>    - only do a loose check for the latest version
>    - expand commit log
> ]
> Signed-off-by: Yann E. MORIN <yann.morin.1998 at free.fr>
> Cc: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
>
> ---
> Changes v3 -> v4: (Yann)
>    - fix commit title: it's not just about external toolchains  (Thomas)
>    - fix C-code coding style  (Thomas)
>    - add 'or later' to the prompts  (Thomas)
>
> Changes v2 -> v3:  (Yann)
>    - also handle the internal toolchain for custom headers
>      (noticed by Vincent)
>
> Changes v1 -> v2:  (Yann)
>    - make it loose only for the latest version
> ---
>   package/linux-headers/Config.in.host          |  5 +++-
>   package/linux-headers/linux-headers.mk        |  5 +++-
>   support/scripts/check-kernel-headers.sh       | 27 ++++++++++++++++---
>   toolchain/Config.in                           |  8 ++++++
>   toolchain/helpers.mk                          |  6 ++++-
>   .../pkg-toolchain-external.mk                 |  3 ++-
>   .../Config.in.options                         |  5 +++-
>   7 files changed, 50 insertions(+), 9 deletions(-)
>
> diff --git a/package/linux-headers/Config.in.host b/package/linux-headers/Config.in.host
> index 6b6fe028c5..905497f496 100644
> --- a/package/linux-headers/Config.in.host
> +++ b/package/linux-headers/Config.in.host
> @@ -118,8 +118,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
> diff --git a/package/linux-headers/linux-headers.mk b/package/linux-headers/linux-headers.mk
> index 676c8c44ea..d653c951fd 100644
> --- a/package/linux-headers/linux-headers.mk
> +++ b/package/linux-headers/linux-headers.mk
> @@ -131,11 +131,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
> diff --git a/support/scripts/check-kernel-headers.sh b/support/scripts/check-kernel-headers.sh
> index 9d23c00feb..b99e0a7c2d 100755
> --- a/support/scripts/check-kernel-headers.sh
> +++ b/support/scripts/check-kernel-headers.sh
> @@ -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#*.}"
> @@ -32,16 +48,19 @@ ${HOSTCC} -imacros "${SYSROOT}/usr/include/linux/version.h" \
Since we're using strcmp now, we'll want #include <string.h> otherwise 
GCC may throw a warning:

<stdin>: In function ‘main’:
<stdin>:17:29: warning: implicit declaration of function ‘strcmp’ 
[-Wimplicit-function-declaration]
Incorrect selection of kernel headers: expected 4.19.x, got 4.20.x

>   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_
>   
> diff --git a/toolchain/Config.in b/toolchain/Config.in
> index 858121d2c5..973c03254f 100644
> --- a/toolchain/Config.in
> +++ b/toolchain/Config.in
> @@ -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.
> diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
> index 996cc70d44..2c2a987c3e 100644
> --- a/toolchain/helpers.mk
> +++ b/toolchain/helpers.mk
> @@ -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
>   
> diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
> index 1c43409514..b01082aadd 100644
> --- a/toolchain/toolchain-external/pkg-toolchain-external.mk
> +++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
> @@ -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 \
> diff --git a/toolchain/toolchain-external/toolchain-external-custom/Config.in.options b/toolchain/toolchain-external/toolchain-external-custom/Config.in.options
> index 665765a104..81ace76493 100644
> --- a/toolchain/toolchain-external/toolchain-external-custom/Config.in.options
> +++ b/toolchain/toolchain-external/toolchain-external-custom/Config.in.options
> @@ -109,8 +109,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

-- 
Vincent Fazio
Embedded Software Engineer - Linux
Extreme Engineering Solutions, Inc
http://www.xes-inc.com




More information about the buildroot mailing list