| Message ID | 20260731144345.1560688-3-felix.moessbauer@siemens.com |
|---|---|
| State | New |
| Headers | show |
| Series | Fix kernel build and propagation of linux-libc-dev | expand |
On 31.07.26 16:43, Felix Moessbauer wrote: > In 327fb313, the building of arch=all packages was disabled when cross > compiling. This was needed because Debian in general does not allow to > cross compile arch=all packages. Further, this solved the issue that > these packages were build twice. > > However, this change also resulted in not building the linux-libc-dev at > all, as it previously was built from the cross target. We fix this by > properly modelling the dependency chain - depending on if the > linux-libc-dev package is arch=all or not: If it is not arch=all, it is > just built in the kernel cross compile. If it is arch=all, it is > dispatched to the new -libctarget variant that just builds this library > in native mode (without building the kernel). > > Fixes: 327fb313 ("sbuild: do not build arch all packages on cross") > Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com> > --- > meta/classes-recipe/libctarget.bbclass | 13 ++++++ > meta/classes-recipe/linux-kernel.bbclass | 42 +++++++++++++++++-- > .../linux/files/debian/control.tmpl | 4 +- > .../linux/files/debian/isar/common.tmpl | 6 ++- > .../linux/files/debian/isar/install.tmpl | 9 ++++ > 5 files changed, 67 insertions(+), 7 deletions(-) > create mode 100644 meta/classes-recipe/libctarget.bbclass > > diff --git a/meta/classes-recipe/libctarget.bbclass b/meta/classes-recipe/libctarget.bbclass > new file mode 100644 > index 00000000..9419f402 > --- /dev/null > +++ b/meta/classes-recipe/libctarget.bbclass > @@ -0,0 +1,13 @@ > +# This software is a part of Isar. > +# Copyright (C) 2026 Siemens AG > +# > +# SPDX-License-Identifier: MIT > + > +python libctarget_virtclass_handler() { > + pn = e.data.getVar('PN') > + if pn.endswith('-libctarget'): > + e.data.setVar('BPN', pn[:-len('-libctarget')]) > + e.data.appendVar('OVERRIDES', ':class-libctarget') > +} > +addhandler libctarget_virtclass_handler > +libctarget_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise" > diff --git a/meta/classes-recipe/linux-kernel.bbclass b/meta/classes-recipe/linux-kernel.bbclass > index ff8b1e61..8d5fc880 100644 > --- a/meta/classes-recipe/linux-kernel.bbclass > +++ b/meta/classes-recipe/linux-kernel.bbclass > @@ -100,6 +100,7 @@ TEMPLATE_VARS += " \ > > inherit dpkg > inherit kbuildtarget > +inherit libctarget > > # Add custom cflags to the kernel build > KCFLAGS ?= "-fdebug-prefix-map=${CURDIR}=." > @@ -127,6 +128,14 @@ BUILD_PROFILES = "pkg.${BPN}.kernel pkg.${BPN}.kbuild" > # We only offer the -kbuildtarget variant when actually cross compiling > BBCLASSEXTEND:append:cross-profile = " kbuildtarget" > > +# The arch=all linux-libc-dev packages cannot be built in the cross variant of > +# the base recipe: sbuild is invoked with --no-arch-all there, so no arch=all > +# binary packages are produced. In that situation, build them via a dedicated, > +# native -libctarget variant. This condition is true only when libc-dev deployment > +# is requested and the resulting package is arch=all. > +KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT = "${@ '1' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_DEPLOY')) and bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_ARCH_ALL')) else '0'}" > +BBCLASSEXTEND:append:cross-profile = "${@ ' libctarget' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ''}" > + > # When cross-profile is active: > # Build kernel (including config) cross packages (linux-libc-dev-*-cross) > # with the default variant of the recipe > @@ -157,6 +166,25 @@ RECIPE_PROVIDES:remove:class-kbuildtarget = " \ > DEPENDS:class-kbuildtarget = "${BPN}" As we are at it: +# See reasoning for ISAR_CROSS_COMPILE:class-libctarget But that is unfortunately a forward reference. Maybe you can generalize the comment below, use it here first, and then reference back from below. > ISAR_CROSS_COMPILE:class-kbuildtarget = "0" > > +# The -libctarget variant builds only the (arch=all) linux-libc-dev packages. > +# As these are arch=all packages, they are built natively for the host architecture > +# (like -native). Setting PACKAGE_ARCH to HOST_ARCH makes crossvars.bbclass select > +# the host schroot and a native (non-cross) build, so sbuild is invoked with > +# --arch-all and produces the arch=all packages. The base cross recipe depends on it > +# (see below) to get the packages built. > +BUILD_PROFILES:class-libctarget = "pkg.${BPN}.libc" > +RECIPE_PROVIDES:class-libctarget = " \ > + linux-libc-dev \ > + linux-libc-dev-${DISTRO_ARCH}-cross" > +PACKAGE_ARCH:class-libctarget = "${HOST_ARCH}" > +# This variant builds natively for the host (PACKAGE_ARCH == HOST_ARCH), so it > +# must not be treated as a cross build: disabling ISAR_CROSS_COMPILE keeps the > +# cross-profile override (see the anonymous python above) off this variant. That > +# also prevents the base recipe's "DEPENDS += ${BPN}-libctarget" (which is added > +# under cross-profile) from being applied to the -libctarget variant itself, > +# which would create a dependency loop. > +ISAR_CROSS_COMPILE:class-libctarget = "0" > + > # Make bitbake know we will be producing linux-image and linux-headers packages > # Also make it know about other packages from control > RECIPE_PROVIDES = " \ > @@ -170,10 +198,12 @@ RECIPE_PROVIDES = " \ > # Provide linux-libc-dev packages unless nolibcdev profile used > OVERRIDES:append = ":${@ bb.utils.contains('DEB_BUILD_PROFILES', 'pkg.{}.nolibcdev'.format(d.getVar('BPN')), '', 'libcdev', d)}" > > -RECIPE_PROVIDES:append:libcdev = " \ > - linux-libc-dev" > -RECIPE_PROVIDES:append:libcdev:cross-profile = " \ > - linux-libc-dev-${DISTRO_ARCH}-cross" > +# The base recipe provides the linux-libc-dev packages, except when they are > +# arch=all and we are cross building: in that case they are built and provided > +# by the dedicated -libctarget variant instead (see class-libctarget above), so > +# the base recipe must not advertise them (it cannot build them here). > +RECIPE_PROVIDES:append:libcdev = "${@ '' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ' linux-libc-dev'}" > +RECIPE_PROVIDES:append:libcdev:cross-profile = "${@ '' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ' linux-libc-dev-${DISTRO_ARCH}-cross'}" > > # When cross-profile is active: > # kbuild package is provided by -native or -kbuildtarget variant. Also headers > @@ -183,6 +213,10 @@ RECIPE_PROVIDES:remove:cross-profile = " \ > linux-headers-${KERNEL_NAME_PROVIDED} \ > linux-kbuild-${KERNEL_NAME_PROVIDED}" > > +# The arch=all linux-libc-dev packages are built by the -libctarget variant. > +# Depend on it from the base cross recipe (linux-image-<arch>) so it is built. > +DEPENDS:append:cross-profile = "${@ ' ${BPN}-libctarget' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ''}" > + > # As the multiarch class will not append -compat to -pseudo-native, we end up > # with two providers of it. Remove the wrong one. > RECIPE_PROVIDES:remove:class-compat = "${BPN}-pseudo-native" > diff --git a/meta/recipes-kernel/linux/files/debian/control.tmpl b/meta/recipes-kernel/linux/files/debian/control.tmpl > index ee87cf92..77c4048b 100644 > --- a/meta/recipes-kernel/linux/files/debian/control.tmpl > +++ b/meta/recipes-kernel/linux/files/debian/control.tmpl > @@ -24,7 +24,7 @@ Description: ${KERNEL_NAME_PROVIDED} Linux kernel headers for @KR@ > This is useful for people who need to build external modules > > Package: linux-libc-dev > -Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.kernel> > +Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.kernel> <!pkg.${BPN}.nolibcdev pkg.${BPN}.libc> > Section: devel > Provides: linux-kernel-headers > Architecture: ${KERNEL_LIBC_DEV_ARCH} > @@ -33,7 +33,7 @@ Description: Linux support headers for userspace development > are used by the installed headers for GNU glibc and other system libraries. > > Package: linux-libc-dev-${DISTRO_ARCH}-cross > -Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.cross !pkg.${BPN}.kbuild> > +Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.cross !pkg.${BPN}.kbuild> <!pkg.${BPN}.nolibcdev pkg.${BPN}.libc> > Section: devel > Provides: linux-kernel-headers-${DISTRO_ARCH}-cross > Architecture: all > diff --git a/meta/recipes-kernel/linux/files/debian/isar/common.tmpl b/meta/recipes-kernel/linux/files/debian/isar/common.tmpl > index f9cc2f02..72d3e428 100644 > --- a/meta/recipes-kernel/linux/files/debian/isar/common.tmpl > +++ b/meta/recipes-kernel/linux/files/debian/isar/common.tmpl > @@ -16,7 +16,11 @@ KERNEL_PKG_KERN_KBUILD_CROSS=${KERNEL_PKG_KERN_KBUILD}-${DISTRO_ARCH}-cross > # Force creating debian package with valid host arch for -native build > # Use a cross build to comply with arch specific kernel defconfigs > # The scripts and tools are always created for host arch > -if echo "${DEB_BUILD_PROFILES}" | grep -q -e "cross" -e "kbuild" > +# The -libctarget variant builds the arch=all linux-libc-dev natively on the > +# host, but still needs the target cross-compiler to configure/prepare the > +# target kernel tree for the header generation. > +if echo "${DEB_BUILD_PROFILES}" | grep -q -e "cross" -e "kbuild" || \ > + echo "${DEB_BUILD_PROFILES}" | grep -qw "pkg.${BPN}.libc" > then > CROSS_COMPILE=$(dpkg-architecture -f -A ${DISTRO_ARCH} -q DEB_TARGET_GNU_TYPE)- > fi > diff --git a/meta/recipes-kernel/linux/files/debian/isar/install.tmpl b/meta/recipes-kernel/linux/files/debian/isar/install.tmpl > index 6fa94508..4c28ecc6 100644 > --- a/meta/recipes-kernel/linux/files/debian/isar/install.tmpl > +++ b/meta/recipes-kernel/linux/files/debian/isar/install.tmpl > @@ -52,6 +52,15 @@ do_install() { > fi > fi > > + # The dedicated -libctarget variant builds only the linux-libc-dev packages > + # (pkg.${BPN}.libc profile), without the kernel or kbuild profiles. Handle it > + # here, as the "kernel" branch below is not taken in that case. Match the > + # exact profile token so that "libcdev-arch-all" and "nolibcdev" do not > + # trigger this. > + if echo "${DEB_BUILD_PROFILES}" | grep -qw "pkg.${BPN}.libc"; then > + libc_headers > + fi > + > if echo "${DEB_BUILD_PROFILES}" | grep -q "kernel"; then > if echo "${DEB_BUILD_PROFILES}" | grep -q "cross"; then > # Install cross kernel scripts and tools Both tested here successfully as well, thanks. Jan
diff --git a/meta/classes-recipe/libctarget.bbclass b/meta/classes-recipe/libctarget.bbclass new file mode 100644 index 00000000..9419f402 --- /dev/null +++ b/meta/classes-recipe/libctarget.bbclass @@ -0,0 +1,13 @@ +# This software is a part of Isar. +# Copyright (C) 2026 Siemens AG +# +# SPDX-License-Identifier: MIT + +python libctarget_virtclass_handler() { + pn = e.data.getVar('PN') + if pn.endswith('-libctarget'): + e.data.setVar('BPN', pn[:-len('-libctarget')]) + e.data.appendVar('OVERRIDES', ':class-libctarget') +} +addhandler libctarget_virtclass_handler +libctarget_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise" diff --git a/meta/classes-recipe/linux-kernel.bbclass b/meta/classes-recipe/linux-kernel.bbclass index ff8b1e61..8d5fc880 100644 --- a/meta/classes-recipe/linux-kernel.bbclass +++ b/meta/classes-recipe/linux-kernel.bbclass @@ -100,6 +100,7 @@ TEMPLATE_VARS += " \ inherit dpkg inherit kbuildtarget +inherit libctarget # Add custom cflags to the kernel build KCFLAGS ?= "-fdebug-prefix-map=${CURDIR}=." @@ -127,6 +128,14 @@ BUILD_PROFILES = "pkg.${BPN}.kernel pkg.${BPN}.kbuild" # We only offer the -kbuildtarget variant when actually cross compiling BBCLASSEXTEND:append:cross-profile = " kbuildtarget" +# The arch=all linux-libc-dev packages cannot be built in the cross variant of +# the base recipe: sbuild is invoked with --no-arch-all there, so no arch=all +# binary packages are produced. In that situation, build them via a dedicated, +# native -libctarget variant. This condition is true only when libc-dev deployment +# is requested and the resulting package is arch=all. +KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT = "${@ '1' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_DEPLOY')) and bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_ARCH_ALL')) else '0'}" +BBCLASSEXTEND:append:cross-profile = "${@ ' libctarget' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ''}" + # When cross-profile is active: # Build kernel (including config) cross packages (linux-libc-dev-*-cross) # with the default variant of the recipe @@ -157,6 +166,25 @@ RECIPE_PROVIDES:remove:class-kbuildtarget = " \ DEPENDS:class-kbuildtarget = "${BPN}" ISAR_CROSS_COMPILE:class-kbuildtarget = "0" +# The -libctarget variant builds only the (arch=all) linux-libc-dev packages. +# As these are arch=all packages, they are built natively for the host architecture +# (like -native). Setting PACKAGE_ARCH to HOST_ARCH makes crossvars.bbclass select +# the host schroot and a native (non-cross) build, so sbuild is invoked with +# --arch-all and produces the arch=all packages. The base cross recipe depends on it +# (see below) to get the packages built. +BUILD_PROFILES:class-libctarget = "pkg.${BPN}.libc" +RECIPE_PROVIDES:class-libctarget = " \ + linux-libc-dev \ + linux-libc-dev-${DISTRO_ARCH}-cross" +PACKAGE_ARCH:class-libctarget = "${HOST_ARCH}" +# This variant builds natively for the host (PACKAGE_ARCH == HOST_ARCH), so it +# must not be treated as a cross build: disabling ISAR_CROSS_COMPILE keeps the +# cross-profile override (see the anonymous python above) off this variant. That +# also prevents the base recipe's "DEPENDS += ${BPN}-libctarget" (which is added +# under cross-profile) from being applied to the -libctarget variant itself, +# which would create a dependency loop. +ISAR_CROSS_COMPILE:class-libctarget = "0" + # Make bitbake know we will be producing linux-image and linux-headers packages # Also make it know about other packages from control RECIPE_PROVIDES = " \ @@ -170,10 +198,12 @@ RECIPE_PROVIDES = " \ # Provide linux-libc-dev packages unless nolibcdev profile used OVERRIDES:append = ":${@ bb.utils.contains('DEB_BUILD_PROFILES', 'pkg.{}.nolibcdev'.format(d.getVar('BPN')), '', 'libcdev', d)}" -RECIPE_PROVIDES:append:libcdev = " \ - linux-libc-dev" -RECIPE_PROVIDES:append:libcdev:cross-profile = " \ - linux-libc-dev-${DISTRO_ARCH}-cross" +# The base recipe provides the linux-libc-dev packages, except when they are +# arch=all and we are cross building: in that case they are built and provided +# by the dedicated -libctarget variant instead (see class-libctarget above), so +# the base recipe must not advertise them (it cannot build them here). +RECIPE_PROVIDES:append:libcdev = "${@ '' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ' linux-libc-dev'}" +RECIPE_PROVIDES:append:libcdev:cross-profile = "${@ '' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ' linux-libc-dev-${DISTRO_ARCH}-cross'}" # When cross-profile is active: # kbuild package is provided by -native or -kbuildtarget variant. Also headers @@ -183,6 +213,10 @@ RECIPE_PROVIDES:remove:cross-profile = " \ linux-headers-${KERNEL_NAME_PROVIDED} \ linux-kbuild-${KERNEL_NAME_PROVIDED}" +# The arch=all linux-libc-dev packages are built by the -libctarget variant. +# Depend on it from the base cross recipe (linux-image-<arch>) so it is built. +DEPENDS:append:cross-profile = "${@ ' ${BPN}-libctarget' if bb.utils.to_boolean(d.getVar('KERNEL_LIBC_DEV_NEEDS_LIBC_VARIANT')) else ''}" + # As the multiarch class will not append -compat to -pseudo-native, we end up # with two providers of it. Remove the wrong one. RECIPE_PROVIDES:remove:class-compat = "${BPN}-pseudo-native" diff --git a/meta/recipes-kernel/linux/files/debian/control.tmpl b/meta/recipes-kernel/linux/files/debian/control.tmpl index ee87cf92..77c4048b 100644 --- a/meta/recipes-kernel/linux/files/debian/control.tmpl +++ b/meta/recipes-kernel/linux/files/debian/control.tmpl @@ -24,7 +24,7 @@ Description: ${KERNEL_NAME_PROVIDED} Linux kernel headers for @KR@ This is useful for people who need to build external modules Package: linux-libc-dev -Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.kernel> +Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.kernel> <!pkg.${BPN}.nolibcdev pkg.${BPN}.libc> Section: devel Provides: linux-kernel-headers Architecture: ${KERNEL_LIBC_DEV_ARCH} @@ -33,7 +33,7 @@ Description: Linux support headers for userspace development are used by the installed headers for GNU glibc and other system libraries. Package: linux-libc-dev-${DISTRO_ARCH}-cross -Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.cross !pkg.${BPN}.kbuild> +Build-Profiles: <!pkg.${BPN}.nolibcdev pkg.${BPN}.cross !pkg.${BPN}.kbuild> <!pkg.${BPN}.nolibcdev pkg.${BPN}.libc> Section: devel Provides: linux-kernel-headers-${DISTRO_ARCH}-cross Architecture: all diff --git a/meta/recipes-kernel/linux/files/debian/isar/common.tmpl b/meta/recipes-kernel/linux/files/debian/isar/common.tmpl index f9cc2f02..72d3e428 100644 --- a/meta/recipes-kernel/linux/files/debian/isar/common.tmpl +++ b/meta/recipes-kernel/linux/files/debian/isar/common.tmpl @@ -16,7 +16,11 @@ KERNEL_PKG_KERN_KBUILD_CROSS=${KERNEL_PKG_KERN_KBUILD}-${DISTRO_ARCH}-cross # Force creating debian package with valid host arch for -native build # Use a cross build to comply with arch specific kernel defconfigs # The scripts and tools are always created for host arch -if echo "${DEB_BUILD_PROFILES}" | grep -q -e "cross" -e "kbuild" +# The -libctarget variant builds the arch=all linux-libc-dev natively on the +# host, but still needs the target cross-compiler to configure/prepare the +# target kernel tree for the header generation. +if echo "${DEB_BUILD_PROFILES}" | grep -q -e "cross" -e "kbuild" || \ + echo "${DEB_BUILD_PROFILES}" | grep -qw "pkg.${BPN}.libc" then CROSS_COMPILE=$(dpkg-architecture -f -A ${DISTRO_ARCH} -q DEB_TARGET_GNU_TYPE)- fi diff --git a/meta/recipes-kernel/linux/files/debian/isar/install.tmpl b/meta/recipes-kernel/linux/files/debian/isar/install.tmpl index 6fa94508..4c28ecc6 100644 --- a/meta/recipes-kernel/linux/files/debian/isar/install.tmpl +++ b/meta/recipes-kernel/linux/files/debian/isar/install.tmpl @@ -52,6 +52,15 @@ do_install() { fi fi + # The dedicated -libctarget variant builds only the linux-libc-dev packages + # (pkg.${BPN}.libc profile), without the kernel or kbuild profiles. Handle it + # here, as the "kernel" branch below is not taken in that case. Match the + # exact profile token so that "libcdev-arch-all" and "nolibcdev" do not + # trigger this. + if echo "${DEB_BUILD_PROFILES}" | grep -qw "pkg.${BPN}.libc"; then + libc_headers + fi + if echo "${DEB_BUILD_PROFILES}" | grep -q "kernel"; then if echo "${DEB_BUILD_PROFILES}" | grep -q "cross"; then # Install cross kernel scripts and tools
In 327fb313, the building of arch=all packages was disabled when cross compiling. This was needed because Debian in general does not allow to cross compile arch=all packages. Further, this solved the issue that these packages were build twice. However, this change also resulted in not building the linux-libc-dev at all, as it previously was built from the cross target. We fix this by properly modelling the dependency chain - depending on if the linux-libc-dev package is arch=all or not: If it is not arch=all, it is just built in the kernel cross compile. If it is arch=all, it is dispatched to the new -libctarget variant that just builds this library in native mode (without building the kernel). Fixes: 327fb313 ("sbuild: do not build arch all packages on cross") Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com> --- meta/classes-recipe/libctarget.bbclass | 13 ++++++ meta/classes-recipe/linux-kernel.bbclass | 42 +++++++++++++++++-- .../linux/files/debian/control.tmpl | 4 +- .../linux/files/debian/isar/common.tmpl | 6 ++- .../linux/files/debian/isar/install.tmpl | 9 ++++ 5 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 meta/classes-recipe/libctarget.bbclass