diff mbox series

external-toolchain: Detect linux/version.h via cross compiler

Message ID 20201023093641.619746-1-raj.khem@gmail.com
State New
Headers show
Series external-toolchain: Detect linux/version.h via cross compiler | expand

Commit Message

Khem Raj Oct. 23, 2020, 9:36 a.m. UTC
Using linux/version.h is assumed to be hardcoded inside sysroot but this
does not consider the case where toolchains might be built with
--with-native-system-header-dir which means the header directories will
not be under <sysroot>/usr/include but customized, archlinux, debian
built cross toolchains use these install settings ( due to multiarch )
they have the headers installed like /usr/aarch64-linux-gnu/include and
not /usr/aarch64-linux-gnu/usr/include

This patch adds logic to use cross compiler to compute the path to
linux/version.h on the fly, it means we do not really need to assume the
install structure

Fixes built when using external toolchains provided by archlinux e.g.

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
---
 support/scripts/check-kernel-headers.sh           | 15 ++++++++++++++-
 toolchain/helpers.mk                              |  2 +-
 .../toolchain-external/pkg-toolchain-external.mk  |  3 ++-
 3 files changed, 17 insertions(+), 3 deletions(-)

Comments

Thomas Petazzoni Nov. 3, 2020, 8 p.m. UTC | #1
Hello Khem,

Thanks for the patch.

On Fri, 23 Oct 2020 02:36:41 -0700
Khem Raj <raj.khem@gmail.com> wrote:

> Using linux/version.h is assumed to be hardcoded inside sysroot but this
> does not consider the case where toolchains might be built with
> --with-native-system-header-dir which means the header directories will
> not be under <sysroot>/usr/include but customized, archlinux, debian
> built cross toolchains use these install settings ( due to multiarch )
> they have the headers installed like /usr/aarch64-linux-gnu/include and
> not /usr/aarch64-linux-gnu/usr/include

I am wondering how this can work with Buildroot. Indeed all the logic
of our external toolchains consists in copying the external toolchain
sysroot to $STAGING_DIR, and then pointing the cross-compiler to it
using --sysroot. But if the toolchain headers are not inside the
sysroot, I think we would not copy them to STAGING_DIR, and therefore
the rest of the Buildroot logic would not work.

Could you give more details on how this work with regard to how we're
copying the sysroot to STAGING_DIR ?

Thanks!

Thomas
Yann E. MORIN Nov. 3, 2020, 8:16 p.m. UTC | #2
Khem, All,

On 2020-10-23 02:36 -0700, Khem Raj spake thusly:
> Using linux/version.h is assumed to be hardcoded inside sysroot but this
> does not consider the case where toolchains might be built with
> --with-native-system-header-dir which means the header directories will
> not be under <sysroot>/usr/include but customized, archlinux, debian
> built cross toolchains use these install settings ( due to multiarch )
> they have the headers installed like /usr/aarch64-linux-gnu/include and
> not /usr/aarch64-linux-gnu/usr/include
> 
> This patch adds logic to use cross compiler to compute the path to
> linux/version.h on the fly, it means we do not really need to assume the
> install structure
> 
> Fixes built when using external toolchains provided by archlinux e.g.

So, to summarise our previous discussion on IRC the other day:

  - Buildroot does not officially support distributions' cross
    toolchains, as they may contain extra libraries that are not
    accoutned for by Buildroot,

  - those toolchains are also not always relocatable, even if some
    might be.

Also, Thomas since replied with further questionning, so we really need
a bit more details in there, and how you manage to make it work.

Regards,
Yann E. MORIN.

> Signed-off-by: Khem Raj <raj.khem@gmail.com>
> Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> ---
>  support/scripts/check-kernel-headers.sh           | 15 ++++++++++++++-
>  toolchain/helpers.mk                              |  2 +-
>  .../toolchain-external/pkg-toolchain-external.mk  |  3 ++-
>  3 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/support/scripts/check-kernel-headers.sh b/support/scripts/check-kernel-headers.sh
> index 4e6dce5487..5cedb9a082 100755
> --- a/support/scripts/check-kernel-headers.sh
> +++ b/support/scripts/check-kernel-headers.sh
> @@ -21,6 +21,9 @@ SYSROOT="${2}"
>  HDR_VER="${3}.0.0"
>  CHECK="${4}"  # 'strict' or 'loose'
>  
> +# cross compiler passed in case of external toolchains
> +CROSS_CC="${5}"
> +
>  HDR_M="${HDR_VER%%.*}"
>  HDR_V="${HDR_VER#*.}"
>  HDR_m="${HDR_V%%.*}"
> @@ -36,11 +39,21 @@ trap 'rm -f "${EXEC}"' EXIT
>  
>  EXEC="$(mktemp -p "${BUILDDIR}" -t .check-headers.XXXXXX)"
>  
> +if [ -n "${CROSS_CC}" ]; then
> +  MAKE_VER_H=$(${CROSS_CC} -M -xc - <<_EOF_
> +#include <linux/version.h>
> +_EOF_
> +  )
> +  VER_H=`echo $MAKE_VER_H | awk 'END {print $NF}'`
> +else
> +  VER_H="${SYSROOT}/usr/include/linux/version.h"
> +fi
> +
>  # We do not want to account for the patch-level, since headers are
>  # not supposed to change for different patchlevels, so we mask it out.
>  # This only applies to kernels >= 3.0, but those are the only one
>  # we actually care about; we treat all 2.6.x kernels equally.
> -${HOSTCC} -imacros "${SYSROOT}/usr/include/linux/version.h" \
> +${HOSTCC} -imacros "${VER_H}" \
>            -x c -o "${EXEC}" - <<_EOF_
>  #include <stdio.h>
>  #include <stdlib.h>
> diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
> index 17bc159f3e..51d840b176 100644
> --- a/toolchain/helpers.mk
> +++ b/toolchain/helpers.mk
> @@ -166,7 +166,7 @@ copy_toolchain_sysroot = \
>  #
>  check_kernel_headers_version = \
>  	if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) \
> -		$(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \
> +		$(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict) $(5); \
>  	then \
>  		exit 1; \
>  	fi
> diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
> index 6d91cb5d1e..93f725dada 100644
> --- a/toolchain/toolchain-external/pkg-toolchain-external.mk
> +++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
> @@ -549,7 +549,8 @@ define $(2)_CONFIGURE_CMDS
>  		$$(BUILD_DIR),\
>  		$$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC)),\
>  		$$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\
> -		$$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict)); \
> +		$$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict),\
> +		$$(TOOLCHAIN_EXTERNAL_CC)); \
>  	$$(call check_gcc_version,$$(TOOLCHAIN_EXTERNAL_CC),\
>  		$$(call qstrip,$$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \
>  	if test "$$(BR2_arm)" = "y" ; then \
> -- 
> 2.29.0
> 
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
Khem Raj Nov. 3, 2020, 8:19 p.m. UTC | #3
Hello Thomas

On Tue, Nov 3, 2020 at 12:00 PM Thomas Petazzoni
<thomas.petazzoni@bootlin.com> wrote:
>
> Hello Khem,
>
> Thanks for the patch.
>
> On Fri, 23 Oct 2020 02:36:41 -0700
> Khem Raj <raj.khem@gmail.com> wrote:
>
> > Using linux/version.h is assumed to be hardcoded inside sysroot but this
> > does not consider the case where toolchains might be built with
> > --with-native-system-header-dir which means the header directories will
> > not be under <sysroot>/usr/include but customized, archlinux, debian
> > built cross toolchains use these install settings ( due to multiarch )
> > they have the headers installed like /usr/aarch64-linux-gnu/include and
> > not /usr/aarch64-linux-gnu/usr/include
>
> I am wondering how this can work with Buildroot. Indeed all the logic
> of our external toolchains consists in copying the external toolchain
> sysroot to $STAGING_DIR, and then pointing the cross-compiler to it
> using --sysroot. But if the toolchain headers are not inside the
> sysroot, I think we would not copy them to STAGING_DIR, and therefore
> the rest of the Buildroot logic would not work.
>
> Could you give more details on how this work with regard to how we're
> copying the sysroot to STAGING_DIR ?

It still copied the target pieces to staging area and the compiler
headers and libs are still
used from original install location. so when sysroot is pointing to
new location it can find
the non-compiler specific headers as expected and then use the
compiler headers from
default location and sysroot setting would not have changed that anyway.
The typical usecase is to use distro provided cross compilers, so if a
SDK is generated to use such a  setup you would ask the user to
install the distro cross
toolchain and hook it us into buildroot via external toolchain setup
using defconfig



>
> Thanks!
>
> Thomas
> --
> Thomas Petazzoni, CTO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
Khem Raj Nov. 3, 2020, 8:25 p.m. UTC | #4
On Tue, Nov 3, 2020 at 12:16 PM Yann E. MORIN <yann.morin.1998@free.fr> wrote:
>
> Khem, All,
>
> On 2020-10-23 02:36 -0700, Khem Raj spake thusly:
> > Using linux/version.h is assumed to be hardcoded inside sysroot but this
> > does not consider the case where toolchains might be built with
> > --with-native-system-header-dir which means the header directories will
> > not be under <sysroot>/usr/include but customized, archlinux, debian
> > built cross toolchains use these install settings ( due to multiarch )
> > they have the headers installed like /usr/aarch64-linux-gnu/include and
> > not /usr/aarch64-linux-gnu/usr/include
> >
> > This patch adds logic to use cross compiler to compute the path to
> > linux/version.h on the fly, it means we do not really need to assume the
> > install structure
> >
> > Fixes built when using external toolchains provided by archlinux e.g.
>
> So, to summarise our previous discussion on IRC the other day:
>
>   - Buildroot does not officially support distributions' cross
>     toolchains, as they may contain extra libraries that are not
>     accoutned for by Buildroot,
>

yes that's fine, this patch does not claim to support all of them
either, it just
makes the situation a bit better without regressing the supported usecases
I think it helps lowering the build times on such distros for
developers and improve
first time experience

>   - those toolchains are also not always relocatable, even if some
>     might be.

right and in this case, they are working ok I tried with archlinux
aarch64-linux-gnu-gcc package
and it worked well, debian also worked ok

>
> Also, Thomas since replied with further questionning, so we really need
> a bit more details in there, and how you manage to make it work.
>

right I have tried to clarify, feel free to ask more.

> Regards,
> Yann E. MORIN.
>
> > Signed-off-by: Khem Raj <raj.khem@gmail.com>
> > Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> > ---
> >  support/scripts/check-kernel-headers.sh           | 15 ++++++++++++++-
> >  toolchain/helpers.mk                              |  2 +-
> >  .../toolchain-external/pkg-toolchain-external.mk  |  3 ++-
> >  3 files changed, 17 insertions(+), 3 deletions(-)
> >
> > diff --git a/support/scripts/check-kernel-headers.sh b/support/scripts/check-kernel-headers.sh
> > index 4e6dce5487..5cedb9a082 100755
> > --- a/support/scripts/check-kernel-headers.sh
> > +++ b/support/scripts/check-kernel-headers.sh
> > @@ -21,6 +21,9 @@ SYSROOT="${2}"
> >  HDR_VER="${3}.0.0"
> >  CHECK="${4}"  # 'strict' or 'loose'
> >
> > +# cross compiler passed in case of external toolchains
> > +CROSS_CC="${5}"
> > +
> >  HDR_M="${HDR_VER%%.*}"
> >  HDR_V="${HDR_VER#*.}"
> >  HDR_m="${HDR_V%%.*}"
> > @@ -36,11 +39,21 @@ trap 'rm -f "${EXEC}"' EXIT
> >
> >  EXEC="$(mktemp -p "${BUILDDIR}" -t .check-headers.XXXXXX)"
> >
> > +if [ -n "${CROSS_CC}" ]; then
> > +  MAKE_VER_H=$(${CROSS_CC} -M -xc - <<_EOF_
> > +#include <linux/version.h>
> > +_EOF_
> > +  )
> > +  VER_H=`echo $MAKE_VER_H | awk 'END {print $NF}'`
> > +else
> > +  VER_H="${SYSROOT}/usr/include/linux/version.h"
> > +fi
> > +
> >  # We do not want to account for the patch-level, since headers are
> >  # not supposed to change for different patchlevels, so we mask it out.
> >  # This only applies to kernels >= 3.0, but those are the only one
> >  # we actually care about; we treat all 2.6.x kernels equally.
> > -${HOSTCC} -imacros "${SYSROOT}/usr/include/linux/version.h" \
> > +${HOSTCC} -imacros "${VER_H}" \
> >            -x c -o "${EXEC}" - <<_EOF_
> >  #include <stdio.h>
> >  #include <stdlib.h>
> > diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
> > index 17bc159f3e..51d840b176 100644
> > --- a/toolchain/helpers.mk
> > +++ b/toolchain/helpers.mk
> > @@ -166,7 +166,7 @@ copy_toolchain_sysroot = \
> >  #
> >  check_kernel_headers_version = \
> >       if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) \
> > -             $(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \
> > +             $(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict) $(5); \
> >       then \
> >               exit 1; \
> >       fi
> > diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
> > index 6d91cb5d1e..93f725dada 100644
> > --- a/toolchain/toolchain-external/pkg-toolchain-external.mk
> > +++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
> > @@ -549,7 +549,8 @@ define $(2)_CONFIGURE_CMDS
> >               $$(BUILD_DIR),\
> >               $$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC)),\
> >               $$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\
> > -             $$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict)); \
> > +             $$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict),\
> > +             $$(TOOLCHAIN_EXTERNAL_CC)); \
> >       $$(call check_gcc_version,$$(TOOLCHAIN_EXTERNAL_CC),\
> >               $$(call qstrip,$$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \
> >       if test "$$(BR2_arm)" = "y" ; then \
> > --
> > 2.29.0
> >
> > _______________________________________________
> > buildroot mailing list
> > buildroot@busybox.net
> > http://lists.busybox.net/mailman/listinfo/buildroot
>
> --
> .-----------------.--------------------.------------------.--------------------.
> |  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
> | +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
> | +33 561 099 427 `------------.-------:  X  AGAINST      |  \e/  There is no  |
> | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
> '------------------------------^-------^------------------^--------------------'
Thomas Petazzoni Nov. 3, 2020, 8:43 p.m. UTC | #5
On Tue, 3 Nov 2020 12:25:25 -0800
Khem Raj <raj.khem@gmail.com> wrote:

> >   - Buildroot does not officially support distributions' cross
> >     toolchains, as they may contain extra libraries that are not
> >     accoutned for by Buildroot,
> 
> yes that's fine, this patch does not claim to support all of them
> either, it just
> makes the situation a bit better without regressing the supported usecases
> I think it helps lowering the build times on such distros for
> developers and improve
> first time experience

This has not clarified things for me. Most distributions allow extra
libraries to be installed in their cross-toolchains, i.e on Debian, you
can install libxml2, zlib, and zillions of other libraries
cross-compiled into your cross-compilation toolchain.

Then things are confusing for Buildroot: when it copies the sysroot, it
already contains more than just the C library... potentially libraries
that will conflict with libraries that Buildroot will build.

I don't see how this can work reliably.

Thomas
Khem Raj Nov. 4, 2020, 3:24 a.m. UTC | #6
On Tue, Nov 3, 2020 at 12:43 PM Thomas Petazzoni
<thomas.petazzoni@bootlin.com> wrote:
>
> On Tue, 3 Nov 2020 12:25:25 -0800
> Khem Raj <raj.khem@gmail.com> wrote:
>
> > >   - Buildroot does not officially support distributions' cross
> > >     toolchains, as they may contain extra libraries that are not
> > >     accoutned for by Buildroot,
> >
> > yes that's fine, this patch does not claim to support all of them
> > either, it just
> > makes the situation a bit better without regressing the supported usecases
> > I think it helps lowering the build times on such distros for
> > developers and improve
> > first time experience
>
> This has not clarified things for me. Most distributions allow extra
> libraries to be installed in their cross-toolchains, i.e on Debian, you
> can install libxml2, zlib, and zillions of other libraries
> cross-compiled into your cross-compilation toolchain.

right, this change is only using compiler and compiler runtime
(headers+libs) from those toolchains, everything else is built by
buildroot.
so there is clear separation since --sysroot would point to BR created
sysroot for all target libs. I will install an additional lib and see
how that pans out.

>
> Then things are confusing for Buildroot: when it copies the sysroot, it
> already contains more than just the C library... potentially libraries
> that will conflict with libraries that Buildroot will build.

>
> I don't see how this can work reliably.
>
> Thomas
> --
> Thomas Petazzoni, CTO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
diff mbox series

Patch

diff --git a/support/scripts/check-kernel-headers.sh b/support/scripts/check-kernel-headers.sh
index 4e6dce5487..5cedb9a082 100755
--- a/support/scripts/check-kernel-headers.sh
+++ b/support/scripts/check-kernel-headers.sh
@@ -21,6 +21,9 @@  SYSROOT="${2}"
 HDR_VER="${3}.0.0"
 CHECK="${4}"  # 'strict' or 'loose'
 
+# cross compiler passed in case of external toolchains
+CROSS_CC="${5}"
+
 HDR_M="${HDR_VER%%.*}"
 HDR_V="${HDR_VER#*.}"
 HDR_m="${HDR_V%%.*}"
@@ -36,11 +39,21 @@  trap 'rm -f "${EXEC}"' EXIT
 
 EXEC="$(mktemp -p "${BUILDDIR}" -t .check-headers.XXXXXX)"
 
+if [ -n "${CROSS_CC}" ]; then
+  MAKE_VER_H=$(${CROSS_CC} -M -xc - <<_EOF_
+#include <linux/version.h>
+_EOF_
+  )
+  VER_H=`echo $MAKE_VER_H | awk 'END {print $NF}'`
+else
+  VER_H="${SYSROOT}/usr/include/linux/version.h"
+fi
+
 # We do not want to account for the patch-level, since headers are
 # not supposed to change for different patchlevels, so we mask it out.
 # This only applies to kernels >= 3.0, but those are the only one
 # we actually care about; we treat all 2.6.x kernels equally.
-${HOSTCC} -imacros "${SYSROOT}/usr/include/linux/version.h" \
+${HOSTCC} -imacros "${VER_H}" \
           -x c -o "${EXEC}" - <<_EOF_
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
index 17bc159f3e..51d840b176 100644
--- a/toolchain/helpers.mk
+++ b/toolchain/helpers.mk
@@ -166,7 +166,7 @@  copy_toolchain_sysroot = \
 #
 check_kernel_headers_version = \
 	if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) \
-		$(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \
+		$(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict) $(5); \
 	then \
 		exit 1; \
 	fi
diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
index 6d91cb5d1e..93f725dada 100644
--- a/toolchain/toolchain-external/pkg-toolchain-external.mk
+++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
@@ -549,7 +549,8 @@  define $(2)_CONFIGURE_CMDS
 		$$(BUILD_DIR),\
 		$$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC)),\
 		$$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\
-		$$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict)); \
+		$$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict),\
+		$$(TOOLCHAIN_EXTERNAL_CC)); \
 	$$(call check_gcc_version,$$(TOOLCHAIN_EXTERNAL_CC),\
 		$$(call qstrip,$$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \
 	if test "$$(BR2_arm)" = "y" ; then \