[2/4] fix(kernel): restore building of linux-libc-dev

Message ID 20260731144345.1560688-3-felix.moessbauer@siemens.com
State New
Headers show
Series Fix kernel build and propagation of linux-libc-dev | expand

Commit Message

Felix Moessbauer July 31, 2026, 2:43 p.m. UTC
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

Comments

Jan Kiszka July 31, 2026, 4:29 p.m. UTC | #1
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

Patch

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