#!/bin/bash
set +o posix
shopt -s extglob

##########################################################################
# Script : kernel.SlackBuild
# Purpose: Natively build and package the Linux Kernel for Slackware ARM
# Author : Stuart Winter <mozes@slackware.com>
# Date...: 22-Nov-2024
##########################################################################
# Changelog
############
# 22-Nov-24:
# * Merged the 'a/kernel-modules' package into a single 'a/kernel_armv8'
#   to be inline with x86.
# 01-Jan-24:
#  Implemented a shared Kernel module list 'sources/kmod-dirlist' between
#  the OS InitRD and Slackware Installer.
# 10-Feb-22:
#  Build a/kernel-modules & d/kernel-headers package to reduce build time
#  for Kernel packages, and ease maintenance of stable releases.
# 20-Apr-21:
#  Updated for AArch64.
#  Removed legacy ARM initrd creation code.
# 01-Apr-2018:
#  * Handle building Kernels in /patches
#  * Simplify and remove duplication of code.
# 20-Sep-2005
#  * First version for Linux 2.6.13.1 on the StrongARM RiscPC
# 31-Dec-2005
#   * Linux 2.6.14.5
##########################################################################
#
# Copyright 2005-2024  Stuart Winter, Earth, Milky Way, "".
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

# Record toolchain & other info for the build log:
slackbuildinfo

# Paths to skeleton port's source & real Slackware source tree:
export CWD=$PWD

# Detect whether we're building for /patches:  This function sets the variable 'SLACKPATCHING'
slack_findpkgstore_is_stablerelease
echo "Building in /patches/? $SLACKPATCHING"

# Temporary build locations:
export TMPBUILD=$TMP/build-$PKGNAM
export PKG=$TMP/package-$PKGNAM
# Delete & re-create temporary directories then cd into $TMPBUILD
mkpkgdirs

# When using xz with tar, set the options:
#export XZ_OPTS="--threads $(( $(nproc) -1 )) -z9f -C crc32"
export XZ_OPTS="--threads 0 -ez9f -C crc32"

# The CONFIG_DEBUG_INFO_BTF_MODULES option adds a huge amount of debugging
# data to the modules which we don't actually need. We'll strip debugging
# information from kernel modules by default. If you are building a debug
# kernel and wish to retain this data, export the variable below set to "0".
STRIP_DEBUG=${STRIP_DEBUG:-1}

# Let's export the variable with the name needed by the kernel's Makefiles,
# just for good measure.
[ "$STRIP_DEBUG" = 1 ] && {
   export INSTALL_MOD_STRIP=$STRIP_DEBUG ;} ||
   unset STRIP_DEBUG

# OS InitRD & Slackware Installer Kernel module include list:
KMODINCLUDELIST=$CWD/sources/kmod-dirlist
[ ! -f ${KMODINCLUDELIST} ] && { echo "ERROR: Kernel module include list not found" ; exit 1 ;}

# Default location into which the Linux src will be unpacked:
KERNELSRCDIR=$TMPBUILD/kernel-src
mkdir -p $KERNELSRCDIR

# Parse any command line operators:
PARAMS="$( getopt -qn "$( basename $0 )" -o P:s:n -l pkgstoreoverride:,srcdir:,noconfig,nopatches -- "$@" )"
eval set -- "${PARAMS}"
for param in $*; do
  case "$param" in
     -n|--noconfig)
        NOPLACECONFIG=Yes
        shift ;;
     -p|--nopatches)
        NOAPPLYPATCHES=Yes
        shift ;;
     -P|--pkgstoreoverride)
        PKGSTORE_OVERRIDE="$2"
        # This is set so that the 'kernels' directory in the Slackware ARM
        # source isn't overwritten with test Kernels when users are building packages.
        ROOTDIR_OVERRIDE="$2"
        shift 2;;
     -m|--mergeconfig)
        MERGECONFIG="$2"
        shift 2;;
     -s|--srcdir)
        KERNELSRCDIR="$2"
        ALTERNATEKSRC=Yes
        shift 2;;
     --) shift; break;;
  esac
done

# If the user has specified -P/--pkgstoreoverride, they want to store the resulting
# package files in a directory other than $PKGSTORE.
# We cannot override $PKGSTORE because this build script extracts assets from
# packages within $PKGSTORE.  Packages include 'a/bash'.
# We will ensure that the destination directory exists.
[ ! -z "${PKGSTORE_OVERRIDE}" -a ! -d "${PKGSTORE_OVERRIDE}" ] && {
   echo "ERROR: Alternate package destination directory '${PKGSTORE_OVERRIDE}' does not exist"
   exit 1 ;} || { echo "Packages will be stored in: ${PKGSTORE_OVERRIDE}" ;}

# If the user has specified --srcdir to an unpacked Linux source tree,
# enter that.  Otherwise unpack the source held within the Slackware ARM src tree.
# Extract the kernel source:
[ ! -d "$KERNELSRCDIR" ] && { echo "Error: unable to find directory $KERNELSRCDIR" ; exit 1 ;}
cd $KERNELSRCDIR
if [ "$ALTERNATEKSRC" = "Yes" ]; then
   echo "Entering unpacked Linux Kernel source directory $KERNELSRCDIR"
 else
   echo -n "Extracting Kernel source... "
   tar xf $CWD/sources/linux-*.tar.xz || exit 1
   echo "done"
   # Make the source tree dir name match $VERSION (useful for rc releases)
   mv -fv linux-* linux-$VERSION
fi

# If the user specified their own existing Kernel src tree, does the
# directory format match what we need?
[ ! -d linux-$VERSION ] && { echo "Error: unable to find Linux kernel source directory linux-$VERSION" ; exit 1; }

# Enter the Linux Kernel source directory:
cd linux-*/ || failextract

# Set permissions:
slackhousekeeping

# Install the appropriate Kernel config file, unless
# the --noconfig option was supplied.
[ -z "$NOPLACECONFIG" ] && install -vpm644 $CWD/configs/config-$SLKKERNELARCH .config

# Merge a config in? This is used for onboarding new Hardware Models.
[ -f "$MERGECONFIG" ] && {
   echo "Merging in Kernel configuration file $MERGECONFIG"
   ./scripts/kconfig/merge_config.sh .config $MERGECONFIG ;}

# Remove any hyphen from the EXTRAVERSION name.
sed -i '/EXTRAVERSION *=/s/-//g' Makefile

# Ensure that the Kernel version reported in the Makefile matches
# the version in the package name that we plan to use.
#
# If we're doing builds of RC kernels, we can ignore this check and assume we performed the
# necessary due dilligence.  Non-RC releases have no 'EXTRAVERSION' value set.
#
if ! echo "$VERSION" | grep -E "rc|next" ; then
   if [ "$( echo "$(sed -ne's/^VERSION *= *//p' Makefile).$(sed -ne's/^PATCHLEVEL *= *//p' Makefile).$(sed -ne's/^SUBLEVEL *= *//p' Makefile)" )" != $VERSION ]; then
      echo "**** Package name vs Kernel version mismatch ****"
      echo "*** Slackware Packaging Version: $VERSION"
      echo "*** Kernel versions (From files): $( sed -ne's/^VERSION *= *//p' Makefile).$(sed -ne's/^PATCHLEVEL *= *//p' Makefile).$(sed -ne's/^SUBLEVEL *= *//p' Makefile )"
      exit 1
   fi
fi

echo "Kernel Slackware package version: $VERSION"

# Apply patches unless --nopatches command line option was specified, or
# there are none available in the source tree:
ls $CWD/sources/patches/!(*debian*|*no-autopatch*)xz* > /dev/null 2>&1 || NOAPPLYPATCHES=Yes
[ -z "$NOAPPLYPATCHES" ] && {
   #[ "$SLKPORTARCH" = "aarch64" ] && { auto_apply_patch $CWD/sources/patches/0103-futex-no-autopatch.patch.xz || failpatch ;}
      for i in $CWD/sources/patches/!(*debian*|*no-autopatch*)xz* ; do
         auto_apply_patch $i || failpatch
      done ;}

# For GCC-10:
sed -i "s/--param=allow-store-data-races=0/-fno-allow-store-data-races/g" Makefile

#tar xvvf $CWD/sources/patches/linux*debian*z
#for i in debian/patches/features/arm/* ; do
#   auto_apply_patch $i || exit 1
#done
#for i in debian/patches/bugfix/arm/* ; do
#   auto_apply_patch $i || exit 1
#done

# Build Kernel
echo "Cleaning Kernel.."
make clean
echo "******************************"
echo "*** Building kernel Image  ***"
echo "******************************"

# NUMJOBS is set by the Slackware ARM build orchestration system.
# If you're building this outside of the official master environment,
# we'll default to the number of local processors:
NUMJOBS=${NUMJOBS:--j$( nproc )}

[ "$SLKPORTARCH" = "arm" ] && \
   { make $NUMJOBS ARCH=$LINUXKERNELARCH CONFIG_DEBUG_SECTION_MISMATCH=y zImage || failmake ;}
[ "$SLKPORTARCH" = "aarch64" ] && \
  { make $NUMJOBS ARCH=$LINUXKERNELARCH CONFIG_DEBUG_SECTION_MISMATCH=y Image || failmake ;}

# Build modules:
echo "************************"
echo "*** Building modules ***"
echo "************************"
make $NUMJOBS ARCH=$LINUXKERNELARCH CONFIG_DEBUG_SECTION_MISMATCH=y modules || failmake

# Archive the compiled kernel source - this is used to create the kernel-source package.
# The reason why we check the architecture is because with the soft float port we had
# multiple kernels, but there was no need to have multiple Kernel sources.
# With the hard float and aarch64 port, we have just one Kernel; but in case we end up with
# more than one Kernel in the future, we'll keep this check in place.
# "SLKKERNELARCH" is the _package_ name architecture not the OS architecture - e.g. it'd be "armv5", "armv7", "armv8"
# e.g. the ARM port's packages are named "foo-1.0-arm-1.txz", but this particular _package_ will only run
# on armv7 or greater, so its specific package architecture is "armv7".
# If there is a case to require >1 kernel per arch again, there should be
# a kernel-source package for it, since it would be required to build modules that we don't ship, but
# that can easily be added by the user.
#
# The kernel-source package is now built at the end of this process rather than
# from a separate build script.
#if [[ "${SLKKERNELARCH}" =~ (armv7|armv8) ]]; then
#   echo "Archiving compiled source for kernel-source package..."
#   # This takes far too long on ARM. I'll let the Distro polishing script pack this one:
#   # ( cd .. && tar -Ixz -pcf $CWD/compiled-sources/$SLKKERNELARCH-kernel-$VERSION-compiled.tar.xz linux-$VERSION )
#   ( cd .. && tar pcf $CWD/compiled-sources/$SLKKERNELARCH-kernel-$VERSION-compiled.tar linux-$VERSION )
#fi

echo "Installing Kernel includes for package d/kernel-headers..."
# Create package structure:
mkdir -vpm755 $TMPBUILD/package-kernel-headers/{install,usr}
# Install 'sanitised' headers:
make ARCH=$LINUXKERNELARCH \
     INSTALL_HDR_PATH=$TMPBUILD/package-kernel-headers/usr \
     headers_install || failinstall
( cd $TMPBUILD/package-kernel-headers || exit 1
  # Wipe these '.install' and '..install.cmd' files
  find . -iname '.*' -type f -print0 | xargs -0 rm -f )
# Not anymore - the glibc build uses the Kernel package headers.
#  echo "Archiving kernel-headers for use with glibc"
#  mkdir -vpm755 $CWD/sources/kernel-headers
#  time tar -Ixz -pcf $CWD/sources/kernel-headers/$SLKKERNELARCH-kernel-headers-$VERSION.tar.xz . )

# Install modules into the package:
make ARCH=$LINUXKERNELARCH \
     INSTALL_MOD_PATH=$PKG \
     INSTALL_MOD_STRIP=$STRIP_DEBUG \
     modules_install || failinstall

# We'll install the Kernel modules to the OS once they have been
# compressed within $PKG:
if [ -d $PKG/lib/modules/$VERSION-$SLKKERNELARCH ]; then
   rm -rf /lib/modules/$VERSION-$SLKKERNELARCH
 else
   echo "ERROR: Failed build - the Kernel modules aren't present within the package tree"
   exit 1
fi

# Needed for mkinitrd to find the modules, but we'll install
# the compressed versions from $PKG since it cuts down on build time.
#make ARCH=$LINUXKERNELARCH modules_install || exit 1

# Wipe the firmware from the package since it's included in the a/kernel-firmware package
# and dealt with above:
echo "Wiping /lib/firmware from the current package contents so that"
echo "it won't be included in the a/kernel package ..."
rm -rf $PKG/lib/firmware

# Compress the Kernel modules that have been installed into the
# package:
echo "Compressing package's Kernel modules"
pushd $PKG
   find ./lib/modules -type f -name "*.ko" | parallel xz $XZ_OPTS
   #find ./lib/modules -type f -name '*.ko' | xz $XZ_OPTS --files
   #find ./lib/modules -type f -name "*.ko" -exec xz $XZ_OPTS {} \;
   # Fix symlinks now that the Kernel modules have a .xz suffix:
   for i in $(find ./lib/modules -type l -name "*.ko") ; do ln -vfs $( readlink $i ).xz $i.xz ; rm -fv $i ; done

   # Install the newly-compressed Kernel modules into the OS:
   echo "Installing compressed Kernel modules into /lib/modules for the running OS"
   time cp -fa ./lib/modules/$VERSION-$SLKKERNELARCH /lib/modules/
popd

# Compress OS's copy of the Linux kernel modules to reduce the size of the initrd.
#echo "Compressing Host OS' Kernel modules (for $SLKKERNELARCH) with xz -e9 -- this will take 10-15 mins.."
##find /lib/modules/$VERSION-$SLKKERNELARCH -type f -name "*.ko" -exec gzip -9f {} \;
#time find /lib/modules -type f -name "*.ko" -exec xz $XZ_OPTS \;
#for i in $(find /lib/modules/$VERSION-$SLKKERNELARCH -type l -name "*.ko") ; do ln -vfs $( readlink $i ).xz $i.xz ; rm -fv $i ; done

# Usually we'd do this inside the resulting package but we need the modules
# to be up to date on the live system so that mkinitrd can grab what it needs:
( cd /
  echo "Updating host OS' module dependencies for $VERSION-$SLKKERNELARCH"
  find lib/modules -name $VERSION-$SLKKERNELARCH -type d -mindepth 1 -maxdepth 1 -printf "%f\n" | xargs -i depmod {} -b. )

# Install the kernel image and system map:
mkdir -vpm755 $PKG/{install,boot}

# Building zImage for ARM creates Image, and subsequently
# compresses it.  Since we don't ship the uncompressed version
# for ARM, we'll delete it so that it doesn't get included
# by the search code below.
[ "$SLKPORTARCH" = "arm" ] && rm -f arch/$LINUXKERNELARCH/boot/Image

#gzip -f9cv System.map > $PKG/boot/System.map-$SLKKERNELARCH-$VERSION.gz
# These are named after their respective architectures so that you
# can have more than 1 Kernel package installed on the system
# at any one time, and configure your boot loader to boot, say
# "/uImage-", and not then have to maintain Kernel version
# numbers.
# We'll wipe the ones we don't need for this architecture a bit
# further down.
install -vpm644 System.map $PKG/boot/System.map-$SLKKERNELARCH-$VERSION
for imgtype in {,z,u}Image ; do
   [ -f arch/$LINUXKERNELARCH/boot/$imgtype ] && \
   install -vpm644 arch/$LINUXKERNELARCH/boot/$imgtype $PKG/boot/$imgtype-$SLKKERNELARCH-$VERSION
done
# Make symlinks:
( cd $PKG/boot
  ln -vfs System.map-$SLKKERNELARCH-$VERSION System.map-$SLKKERNELARCH
  for imgtype in {,z,u}Image ; do
     [ -f $imgtype-$SLKKERNELARCH-$VERSION ] && \
     ln -vfs $imgtype-$SLKKERNELARCH-$VERSION $imgtype-$SLKKERNELARCH
  done )

# Jan 2025 - tested on RPi and RockPro64 - won't boot.
# RockPro64 boots Kernel but cannot find the initrd.  RPi fails to boot Kernel.
# Works using GRUB on the HoneyComb LX2 though.
# Compress the kernel using gzip. Initially, we avoided compression on AArch64
# due to compatibility issues with older boot loaders. However, compression is
# now supported. Since existing boot loader configurations expect a kernel named
# 'Image-armv8', we'll compress it under the same name for consistency and
# compatibility.
#[ "$SLKPORTARCH" = "aarch64" ] && {
#  gzip -9v $PKG/boot/Image-$SLKKERNELARCH-$VERSION
#  mv -fv $PKG/boot/Image-$SLKKERNELARCH-$VERSION{.gz,} ;}

# The Kernel config file used (following the Slackware standard):
install -pvm644 .config $PKG/boot/config-$SLKKERNELARCH-$VERSION

# The package description:
install -pvm644 $CWD/slack-descs/kernel-$SLKKERNELARCH $PKG/install/slack-desc
# The script to handle appending DTB files to systems that have the
# 'dtb=' kernel paramater specified:
# Not needed for hard float port since all of the U-Boot versions are new enough
# to handle loading a DTB, but we'll leave this in here and let it error out.
install -pvm644 $CWD/sources/doinst.sh $PKG/install/

# Copy the Kernel into our tree's 'kernels' directory:
# If the 'ROOTDIR_OVERRIDE' is set (usually by k/build_test_kernels.sh), put the assets there,
# otherwise store them in the main tree:
[ -d "${ROOTDIR_OVERRIDE}" ] && rootdir="${ROOTDIR_OVERRIDE}" || rootdir=$PORTROOTDIR
#if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then
if [ "$SLACKPATCHING" = "no" ]; then
   mkdir -vpm755 $rootdir/kernels/$SLKKERNELARCH

   for imgtype in {,z,u}Image ; do
        [ -f arch/$LINUXKERNELARCH/boot/$imgtype ] && \
        install -vpm644 arch/$LINUXKERNELARCH/boot/$imgtype \
                       $rootdir/kernels/$SLKKERNELARCH/$imgtype-$SLKKERNELARCH
   done

   # This is really for the installer build script:
   gzip -f9cv System.map  > $rootdir/kernels/$SLKKERNELARCH/System.map.gz

   # Install the Kernel configuration file, as this can be a useful reference:
   install -vpm644 .config $rootdir/kernels/$SLKKERNELARCH/config
fi

# Make an initrd for the architecture.
# Unpack the generic Slackware Initial RAM disk ('OS initrd') tree:
rm -rf $TMPBUILD/initrd-tree
mkdir -vpm755 $TMPBUILD/initrd-tree
tar xf /usr/share/mkinitrd/initrd-tree.tar.gz -C $TMPBUILD/initrd-tree

# Unpack bash, ncurses, jfsutils and xfsprogs as we need a few
# components:
mkdir -p $TMPBUILD/pkg-extract/special-handling
pushd $TMPBUILD/pkg-extract
   # Handle locating the packages from which we extract components when
   # building within /patches for a stable release, vs -current.
   #[ "$SLACKPATCHING" = "yes" ] && pkgstore=$PORTROOTDIR/slackware || pkgstore=$PKGSTORE
   # If we're building in patches or building test Kernels, $PKGSTORE may not contain
   # all or any of the packages we require to assemble the OS InitRD.
   # PORTROOTDIR is set in /usr/share/slackdev/slackdev.config which always points to
   # the correct place.
   # Presently, this means that we won't use any newer versions of patch packages
   # from within /patches, but I don't foresee this posing any issue.
   # PORTPATCHPKGS, PORTPATCHSRC can be used in future if necessary.
   # Note: 'pkgstore' is only used here to extract packages, $PKGSTORE is where the
   # new Kernel packages are written to.
   pkgstore=$PORTROOTDIR/slackware

   # 'a' series packages:
   explodepkg $pkgstore/a/bash-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/a/coreutils-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/a/hwdata-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/a/jfsutils-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/a/usbutils-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/a/pciutils-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/a/util-linux-+([^-])-+([^-])-+([^-]).t[gblx]z
   # set up symlinks for util-linux
   grep -E '^\( cd .*(rm|ln)' install/doinst.sh | bash
   explodepkg $pkgstore/a/xfsprogs-+([^-])-+([^-])-+([^-]).t[gblx]z

   # 'ap' series packages:
   explodepkg $pkgstore/ap/dmidecode-+([^-])-+([^-])-+([^-]).t[gblx]z

   # 'l' series packages:
   #explodepkg $pkgstore/l/glibc-i18n-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/l/v4l-utils-+([^-])-+([^-])-+([^-]).t[gblx]z
   explodepkg $pkgstore/l/ncurses-+([^-])-+([^-])-+([^-]).t[gblx]z
   # set up symlinks for ncurses
   grep -E '^\( cd .*(rm|ln)' install/doinst.sh | bash

   # Install /usr/lib(64)/locale/en_US.utf8 from l/glibc-i18n.
   # bash-5.2 in a 'chroot' segfaults otherwise.
   #mkdir -vpm755 $TMPBUILD/initrd-tree/usr/lib${LIBDIRSUFFIX}/locale
   #cp -fav usr/lib${LIBDIRSUFFIX}/locale/en_US.utf8 $TMPBUILD/initrd-tree/usr/lib${LIBDIRSUFFIX}/locale/

   # Add dmidecode:
   install -vpm755 usr/sbin/dmidecode $TMPBUILD/initrd-tree/sbin/

   # Wholesale replacement of Busybox's MTD utilities, as the proper ones
   # have more features.  These aren't required for booting the OS, but may
   # prove useful during troubleshooting or onboarding new Hardware Models:
   pushd $TMPBUILD/pkg-extract/special-handling
   explodepkg $pkgstore/a/mtd-utils-+([^-])-+([^-])-+([^-]).t[gblx]z
   cp -fav usr/libexec $TMPBUILD/initrd-tree/usr/
   pushd usr/sbin
   for mtdutil in * ; do
      rm -fv $TMPBUILD/initrd-tree/sbin/$mtdutil
      install -vpm755 $mtdutil $TMPBUILD/initrd-tree/sbin/
   done
   popd
   popd

   # Replace 'readlink' from BusyBox with the coreutils version:
   rm -f $TMPBUILD/initrd-tree/bin/readlink
   install -vpm755 bin/readlink $TMPBUILD/initrd-tree/bin/
   # Replace 'mount' with util-linux's version:
   #rm -f $TMPBUILD/initrd-tree/bin/mount
   #install -vpm755 bin/mount $TMPBUILD/initrd-tree/bin/

   # Replace 'mktemp' with coreutils' version (for some debug scripts):
   rm -f $TMPBUILD/initrd-tree/bin/mktemp
   install -vpm755 bin/mktemp $TMPBUILD/initrd-tree/bin/

   # Replace 'lspci' from Busybox with the 'pciutils' version, and 'lsusb' from the 'usbutils' package.
   # This is because Busybox's doesn't consult the hardware ID data, which we use to conditionally
   # load Kernel modules within the OS InitRD:
   rm -f $TMPBUILD/initrd-tree/bin/ls{pci,usb}
   install -vpm755 usr/bin/ls{pci,usb} $TMPBUILD/initrd-tree/bin/
   # Add pci.ids and usb.ids from the 'a/hwdata' package:
   mkdir -vpm755 $TMPBUILD/initrd-tree/usr/share/hwdata
   install -vpm644 usr/share/hwdata/{pci.ids,usb.ids} \
        $TMPBUILD/initrd-tree/usr/share/hwdata/
   gzip -9v $TMPBUILD/initrd-tree/usr/share/hwdata/*

   # Install /usr/bin/ir-keytable from 'l/v4l-utils' package:
   # since udev calls it, and soft errors if unavailable:
   mkdir -vpm755 $TMPBUILD/initrd-tree/usr/bin
   install -vpm755 usr/bin/ir-keytable $TMPBUILD/initrd-tree/usr/bin/

   # Install libtinfo from ncurses:
   mkdir -vpm755 $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}
   cp -fav lib${LIBDIRSUFFIX}/libtinfo*.so* $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}/

   # Install lsblk and its dependencies from the a/util-linux package:
   # This is used by the 'await_device' to find labeled file systems.
   cp -fav bin/lsblk $TMPBUILD/initrd-tree/bin/
   cp -fav lib${LIBDIRSUFFIX}/libmount.so.* $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}/
   cp -fav lib${LIBDIRSUFFIX}/libsmartcols.so.* $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}/

   # Support custom keymaps:
   install -vpm644 /usr/share/mkinitrd/keymaps.tar.gz $TMPBUILD/initrd-tree/etc/

   # These are added by Slackware's 'mkinitrd' if these modules are required.
   # We'll add them as standard, since we bundle the modules in the generic
   # initrd.
   install -Dvpm755 sbin/{xfs_repair,jfs_fsck} -t $TMPBUILD/initrd-tree/sbin/

   # Use the 'bash' shell instead of busybox, as Slackware ARM uses the
   # richer feature set to make the module loader scripts more succinct:
   rm -f $TMPBUILD/initrd-tree/bin/bash # is a symlink to busybox
   # /init needs to use bash as we use some of the extended features:
   sed -i 's?#!/bin/ash?#!/bin/bash?g' $TMPBUILD/initrd-tree/init
   install -vpm755 bin/bash* $TMPBUILD/initrd-tree/bin/bash

   # Helper to wait for the root device to become available:
   sed -i '\?^sleep \$WAIT*? a\. /await_device' $TMPBUILD/initrd-tree/init || exit 1
   install -vpm755 $CWD/SlkOS-initrd-overlay/await_device $TMPBUILD/initrd-tree/

   # Support execution of a function prior to switching into the OS proper:
   # This could be defined within a Hardware Model's Kernel Module Loader helper
   # script, or perhaps within the /boot/local/load_kernel_modules.post.
   # This is the last chance before the OS proper boots, and it's post software RAID
   # et al initialisation.
   sed -i '\?exec switch_root ?i\fnexists hwm_hook_pre_switch_root && hwm_hook_pre_switch_root' $TMPBUILD/initrd-tree/init || exit 1
   sed -i '\?exec switch_root ?i\fnexists hook_pre_switch_root && hook_pre_switch_root' $TMPBUILD/initrd-tree/init || exit 1

   # Wrap reboot to call the reboot binary with -f(orce).  This is required because the
   # OS environment isn't fully established:
   # This wraps the binary because /usr/local/sbin is ahead of /sbin in $PATH
   mkdir -vpm755 $TMPBUILD/initrd-tree/usr/local/sbin
   echo "/sbin/reboot -f" > $TMPBUILD/initrd-tree/usr/local/sbin/reboot
   chmod 755 $TMPBUILD/initrd-tree/usr/local/sbin/reboot
popd

# Use 'mkinitrd' to create a default environment:
cd $TMPBUILD

echo "Calling mkinitrd: creating a default Slackware initrd environment"
# Note: '-C luksdummy' is to enable mkinitrd to install the appropriate
# libraries and tools into the initrd.  No LUKS config is shipped by default.
MKINITRD_ALLOWEXEC=yes \
mkinitrd \
  -R \
  -L \
  -u \
  -C luksdummy \
  -k $VERSION-$SLKKERNELARCH \
  -s $TMPBUILD/initrd-tree \
  -o $TMPBUILD/initrdtmp.gz

# Sanity check that mkinitrd created some output:
[ ! -f $TMPBUILD/initrdtmp.gz ] && {
   read -p "ERROR: creation of temporary Initial RAM disk failed"
   exit 1 ;}

# Switch to that new environment.
# At this stage, we've
# 1. Unpacked the standard Slackware initrd environment that's packaged
#    within the a/mkinitrd package
# 2. Added 'bash' and a library from 'ncurses' to that environment
# 3. Used the mkinitrd tool to populate that enviromnemt with the default
#    set of runtime libraries, taken from the host build system.
# 4. Now we're going to switch to that new environment and continue
#    populating it to become the generic ARM OS InitRD.
mv -fv $TMPBUILD/initrd-tree{,.orig}
mkdir -vpm755 $TMPBUILD/initrd-tree
cd $TMPBUILD/initrd-tree
# Unpack the newly built initrd image into the fresh initrd root fs:
zcat $TMPBUILD/initrdtmp.gz | cpio -di

echo "Copying Kernel modules into OS InitRD"
rm -rf lib/modules # purge what 'mkinitrd' populated
# Copy the indexes, etc. (everything other than the Kernel modules and the build/source symlinks):
mkdir -vpm755 lib/modules/$VERSION-$SLKKERNELARCH/kernel
#cp -fa $PKG/lib/modules/$VERSION-$SLKKERNELARCH/!(build|kernel|source) lib/modules/$VERSION-$SLKKERNELARCH/
cp -fa $PKG/lib/modules/$VERSION-$SLKKERNELARCH/modules.{order,builtin*} lib/modules/$VERSION-$SLKKERNELARCH/

# Copy the Kernel module directories containing the major components:
pushd $PKG/lib/modules/$VERSION-$SLKKERNELARCH/kernel
grep -Ev '^#|^$' ${KMODINCLUDELIST} | tar --wildcards -pvvcf - -T- | tar -C${TMPBUILD}/initrd-tree/lib/modules/$VERSION-$SLKKERNELARCH/kernel/ -pxf -
popd

# Slim down the modules within the initrd by removing unnecessary
# major sub systems or drivers for hardware that is not required during
# the initial boot.
# There will be far more that are also surplus to requirements but I'm
# trying to strike a balance between size and enabling the community to
# more easily light up Slackware AArch64 onto new platforms.
#
. $CWD/scripts/slim-kmods-initrd || exit 1

echo "Compressing initrd's Kernel modules with xz -e9 -- this will take 10-15 mins.."
#time find ./lib/modules -type f -name "*.ko" -exec xz --threads $(( $(nproc) -1 )) -ze9f -C crc32 {} \;
time find ./lib/modules -type f -name "*.ko" -exec xz $XZ_OPTS {} \;
# Fix any broken symlinks post compression:
for i in $(find ./lib/modules -type l -name "*.ko") ; do ln -vfs $( readlink $i ).xz $i.xz ; rm -fv $i ; done

# Install some tools to help when onboarding Slackware ARM to new Hardware Models.
mkdir -vpm755 tools
install -vpm755 $CWD/SlkOS-initrd-overlay/tools/* tools/

# Install the Slackware ARM Hardware Model Discovery tool:
# Into the OS InitRD:
install -vpm755 $CWD/SlkOS-initrd-overlay/sbin/slk-hwm-discover sbin/
# and into the OS a/kernel_armvN package:
mkdir -vpm755 $PKG/sbin
install -vpm755 $CWD/SlkOS-initrd-overlay/sbin/slk-hwm-discover $PKG/sbin/

# Kernel Module loader for Slackware AArch64.  This loads a base set of
# platform modules generally useful on all SoCs, and at boot time
# loads specific SoC modules for the host platform.
# If you want to add support for a new platform, please look at this
# script and give mozes@slackware.com a diff.
install -vpm755 $CWD/SlkOS-initrd-overlay/load_kernel_modules .
# Install the board support scripts:
mkdir -vpm755 load_kernel_modules.scr/platform/$SLKPORTARCH
install -vpm755 $CWD/SlkOS-initrd-overlay/load_kernel_modules.scr/platform/$SLKPORTARCH/* \
                load_kernel_modules.scr/platform/$SLKPORTARCH/
# Kernel module modprobe configuration files.  This is principally to enable
# module black lists:
# At run time the /load_kernel_modules moves any modprobe config files it finds
# into the OS InitRD's /etc/modprobe.d/ prior to the modules being loaded.
mkdir -vpm755 etc/modprobe.d usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d
if [ -d $CWD/SlkOS-initrd-overlay/usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d ]; then
   # note: the Installer builder sets all files to chmod 644 and dirs to 755.
   # if we need any other perms we'll need to be more discerning within the Installer builder.
   install -vpm644 \
      $CWD/SlkOS-initrd-overlay/usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d/* \
      usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d/
fi

# Add them into the Slackware Kernel package:
# Not yet since there's no way to have modprobe discriminate at the Hardware Model level.
# Some Hardware Models share IP cores, and we might not want the same settings for
# Each Hardware model.
# Presently we'll only handle this within the Installer and OS InitRD.  If we need to
# sync with the /etc/modprobe.d/ within the Slackware OS, we'll figure it out later.
# We also might want to have a user-maintained /etc/modprobe.d/ synced with the InitRD
# as a way for the user to control it.
# I could probably have the installer populate the modprobe.d configs but we still
# need to manage the updates somehow.
# Food for thought..
#mkdir -vpm755 $PKG/etc/modprobe.d
#install -vpm644 $CWD/SlkOS-initrd-overlay/etc/modprobe.conf/* $PKG/etc/modprobe.d/

# Walk the host architecture, calling the helper scripts to
# perform any Hardware Model specific actions.
# Presently this is to install firmware into the OS InitRD's /lib/firmware
# for Hardware Models.
if [ -d  $CWD/platform/$SLKPORTARCH ]; then
   for helper in $( find $CWD/platform/$SLKPORTARCH -type f -mindepth 1 -maxdepth 1 ) ; do
      echo "Executing Kernel Build helper for ${helper##*/}"
      . $helper
   done
fi

# Generic initrd configuration:
> rootdev # both are controlled by the Kernel cmdline parameters since
> rootfs  # this is a generic platform initrd.
echo 2 > wait-for-root # media spinup delay
echo "/boot/initrd-$SLKKERNELARCH.gz" > initrd-name
rm -f command_line # it was a temporary build - useless info
# Wipe dummy LUKS config:
> luksdev
> lukskey
rm -f lukstrim # just incase one ever appears!

# Shipping the Software RAID configuration of a build machine
# doesn't make sense.  /init tries to set up Software RAID itself
# but users can also use the os-initrd-mgr tool to manage the
# addition and removal of the OS's /etc/mdadm.conf.
rm -f etc/mdadm.conf

# Add the Kernel module loader 'mega list'
# When the Kernel cmdline option 'kmod_megaload' is supplied,
# the loader will recursively load all modules found within the specified
# subsystem directories. This is primarily intended to assist with onboarding
# new or unverified hardware platforms where the exact module requirements are
# not yet known:
install -vpm644 $CWD/sources/kmod_megaload_dirlist .kmod_megaload_dirlist

# A global exclusion list for the Kernel Module Loader's "megaload" dev
# feature. This prevents loading modules that emit errors and are generally not too useful
# on most systems:
install -vpm644 $CWD/sources/kmod_megaload_exclude .kmod_megaload_exclude

# Update the indexes so we can boot this baby:
echo "Updating linker cache and Kernel module maps...."
ldconfig -r.
depmod -b. $VERSION-$SLKKERNELARCH

# Pack into initramfs format:
find . | cpio -o -H newc | gzip -9 > $TMPBUILD/initrd-$SLKKERNELARCH.gz
# This works, but we need to remove the.gz suffixes within this build script and retest with Linux 6.1:
#os-initrd also needs to pack with lzma - it can already identify and decompress gz or xz.
#find . | cpio -o -H newc | xz --threads $(( $(nproc) -1 )) -vz9f -C crc32 > $TMPBUILD/initrd-$SLKKERNELARCH.gz

# Add a README for the Raspberry Pi users explaining that the Kernel and InitRD
# are duplicated to its platform Hardware Model VFAT partition:
install -vpm644 $CWD/sources/README-RaspberryPi.txt $PKG/boot/

# Store the size of the initrd uncompressed, so that the
# /usr/sbin/os-initrd-mgr knows how much temp space to allocate
# when repacking the OS initrd to include any user local additions:
cat << EOF > $PKG/boot/.boot_details
# Build host: $( uname -n )
# Kernel build date: $( date -u )
#
# This file was created originally by source/k/kernel.SlackBuild
# during the Kernel package build process, and potentially updated
# by /usr/sbin/os-initrd-mgr.
#
#
# Do not edit this file by hand!
#
#
# Size of the OS InitRD in bytes.  This is used for os-initrd-mgr to
# determine whether it can safely unpack the initrd.
initrdsize=$( du -sb . | awk '{print $1}' )
# ARM architecture version.  This allows os-initrd-mgr to rebuild
# the initrd via the symlink /boot/initrd-armvN.
# armv7 = "Slackware ARM" - 32bit/ARM32
# armv8 = "Slackware AArch64" - 64bit/ARM64
platform=$SLKKERNELARCH
# Slackware Kernel version:
slkkernel=$VERSION-$SLKKERNELARCH
EOF

# Add the sample scripts:
install -Dvpm644 $CWD/boot-skeleton/local/* -t $PKG/boot/local/
# Add the Hardware Model post Kernel package installation helper scripts.
# There aren't any for ARM32 presently:
[ "$SLKPORTARCH" = "aarch64" ] && {
   install -Dvpm644 $CWD/boot-skeleton/platform/aarch64/helper/README.txt -t $PKG/boot/platform/aarch64/helper/
   # We may store other types of helper scripts here in the future, so
   # we'll take only our 'kernel' helpers:
   install -Dvpm755 $CWD/boot-skeleton/platform/aarch64/helper/pkg-kernel-* -t $PKG/boot/platform/aarch64/helper/
}

# Add the OS Initrd Manager:
install -Dvpm755 $CWD/sources/os-initrd-mgr -t $PKG/usr/sbin/
mkdir -vpm755 $PKG/usr/man/man8
pod2man \
   --section=8  \
   --release="$( grep -E ' Date.*:' $CWD/sources/os-initrd-mgr | awk -F: '{ print $2 }' )" \
   --center=' ' \
   --date="os-initrd-mgr Version $( grep -E ' Version.*: ' $CWD/sources/os-initrd-mgr | awk -F: '{ print $2 }' )" \
   $CWD/sources/os-initrd-mgr.pod 2>&1 | gzip -9f > $PKG/usr/man/man8/os-initrd-mgr.8.gz

# Add the sample os-initrd-mgr config file:
install -Dvpm644 $CWD/sources/os-initrd-mgr.conf.sample -t $PKG/etc/

# Store the standard gzipped initial RAM disk, plus its U-Boot format counterpart:
#
# 1. Within the 'slackware-current/kernels' directory.
#
# When building patch packages, we never provide an updated version of this file outside of the
# package archive.  This is because files in the '/kernels' directory are generally for
# use with the Slackware installer image, and we normally don't update those once the
# Slackware version is released (as they'd be different versions to those in the main
# 'slackware/' tree).
#if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then
if [ "$SLACKPATCHING" = "no" ]; then
   for imgtype in {,u}initrd ; do
      [ -f $TMPBUILD/${imgtype}-$SLKKERNELARCH.gz ] && \
      install -vpm644 $TMPBUILD/${imgtype}-$SLKKERNELARCH.gz \
                      $rootdir/kernels/$SLKKERNELARCH/${imgtype}-$SLKKERNELARCH
   done
fi

# 2. Within $PKG/boot
#
# This allows devices whose boot loader can read the partition where /boot resides
# (all Directly Integrated Hardware Model support):
[ -f $TMPBUILD/uinitrd-$SLKKERNELARCH ] && \
   install -vpm644 $TMPBUILD/uinitrd-$SLKKERNELARCH $PKG/boot/uinitrd-$SLKKERNELARCH-$VERSION
# The gzipped compressed cpio version:
install -vpm644 $TMPBUILD/initrd-$SLKKERNELARCH.gz $PKG/boot/initrd-$SLKKERNELARCH-$VERSION

# Create symlinks to enable static boot loader configuration:
# (having version numbers would necessitate a boot loader change with every
# Kernel package release):
( cd $PKG/boot
 for imgtype in {,u}initrd ; do
     [ -f $imgtype-$SLKKERNELARCH-$VERSION ] && \
     ln -vfs $imgtype-$SLKKERNELARCH-$VERSION $imgtype-$SLKKERNELARCH
  done )

# It's nice to have this final touch (pun intended):
##if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then
#if [ "$SLACKPATCHING" = "no" ]; then
#   ( cd $rootdir/kernels/$SLKKERNELARCH/
#     for imgtype in {,z,u}Image ; do
#        [ -f $imgtype-$SLKKERNELARCH ] && \
#          touch -r $imgtype-$SLKKERNELARCH * $PKG/boot/*
#     done )
#fi

# Compile the Device Tree Source (DTS) files into Device Tree Blobs (DTB):
# This file is for the 'Flattened Device Tree' technology.
# For the generic 'armv7' kernels, we have no way of knowing which DTB file
# the user will require, so we have to ship them all for each architecture.
#
mkdir -vpm755 $PKG/{install,boot/dtb-$VERSION}
ln -rvfs $PKG/boot/dtb-$VERSION $PKG/boot/dtb

# Ensure that we're in the correct directory to build the DTB files.
cd $KERNELSRCDIR/linux-$VERSION && make ARCH=$LINUXKERNELARCH dtbs || failmake

# Install them to a temporary directory.  The make install
# creates a 'dtbs' directory within the specified path.
make INSTALL_PATH=$TMPBUILD dtbs_install || failmake

# Copy the extra ones that are not yet in the mainline kernel.  These are only for
# armv7:
# This was for an experiment where I was using a forked Kernel tree.
#if [ "$SLKKERNELARCH" = "armv7" ]; then
#  echo "Adding extra DTBs from $CWD/sources/extra-dtb/ (if any exist)"
#  cp -fav $CWD/sources/extra-dtb/*.dtb $KERNELSRCDIR/linux-$VERSION/arch/$LINUXKERNELARCH/boot/dts/
#fi

# Install DTB's into the package:
#install -vpm644 $KERNELSRCDIR/linux-$VERSION/arch/$LINUXKERNELARCH/boot/dts/*.dtb $PKG/boot/dtb-$VERSION/
# AArch64 groups the DTBs by platform type, unlike ARM where they're in a
# flat level directory structure.
# The directory structure is: $TMPBUILD/dtbs/5.10.21-armv8
cp -fa $TMPBUILD/dtbs/*/* $PKG/boot/dtb-$VERSION/ || failinstall

# Install copies into the 'kernels' directory so that they can be easily
# available for tftp booting:
# We don't version the DTB files inside the '/kernels' directory because
# the kernel + initrd files are not versioned here since this dir is not
# packaged/version managed.
#if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then
if [ "$SLACKPATCHING" = "no" ]; then
   rm -rf $rootdir/kernels/$SLKKERNELARCH/dtb
   mkdir -vpm755 $rootdir/kernels/$SLKKERNELARCH/dtb
   cp -fa $TMPBUILD/dtbs/*/* $rootdir/kernels/$SLKKERNELARCH/dtb/ || failinstall
   #install -vpm644 -oroot -groot $PKG/boot/dtb-$VERSION/* $rootdir/kernels/$SLKKERNELARCH/dtb/
fi

###############################################################################
# Build the base 'a/kernel' package:
###############################################################################
echo "*****************************************************************"
echo "Building base package slackware/a/$SLACKPACKAGE"
echo "*****************************************************************"

# Replace version number with a _ so it doesn't get confused with
# the package name.
# This is incase we're using any '-rc' releases.
export VERSION="$( echo $VERSION | sed 's?-??g' )"

cd $PKG

# This is a symlink to where the kernel was compiled
# We wipe these and create new ones pointing to /usr/src
# (our kernels were compiled in a temporary location, so the symlink would be broken)
# The symlinks looked like this:
# /lib/modules/<ver>/build -> /root/tmp/build-kernel_armv7/linux-5.15.19
# Why don't we just make the symlink using the existing variables?
# That's because at the time of writing I'm taking this from the old kernel-modules.SlackBuild
# and my guess is that at some points, the dir name might not be what we expected.
pushd lib/modules/*
LINKLOC=$( find . -name source -printf "%l\n" | rev | cut -d/ -f1 | rev )
rm -rf source
ln -vfs ../../../usr/src/$LINKLOC source
LINKLOC=$( find . -name build -printf "%l\n" | rev | cut -d/ -f1 | rev )
rm -rf build
ln -vfs ../../../usr/src/$LINKLOC build
popd

# Update the dependencies list:
# depmod -b $PKG $VERSION
# Generate modules.dep files for each ARM architecture we have inside lib/modules.
# This is legacy from when we had the all-in-one script, but I like it so it stays :-)
find lib/modules -type d -mindepth 1 -maxdepth 1 -printf "%f\n" | xargs -i depmod {} -b.

# Apply some of the generic Slackware packaging policies:
slackslack  # chown -R root:root, chmod -R og-w, slack644docs

# If $PKGSTORE_OVERRIDE is set and exists as a directory, we'll switch
# $PKGSTORE to it so that our packages are stored outside of the main tree.
# This enables new Kernels to be tested more easily.
# The PKGSERIES directories (a,d,k) should have already been created.
[ -d "${PKGSTORE_OVERRIDE}" ] && PKGSTORE="${PKGSTORE_OVERRIDE}"

# We need to pre-pend the symlink code to the main 'doinst.sh' since it requires the
# versionless symlinks for /usr/sbin/os-initrd-mgr
#makepkg -p -l y -c n $PKGSTORE/$PKGSERIES/$PKGNAM-$VERSION-$SLKPORTARCH-$BUILD.txz
slackmp -p # run makepkg --prepend -l y -c n

###############################################################################
# Build the 'd/kernel-headers' package:
###############################################################################

# The headers are installed into the root of this package earlier
# in the Kernel build process, so all we need here is to install the
# slack-desc and set permissions.

# Package information:
export PKGNAM=kernel-headers
export SLACKPACKAGE=$PKGNAM-$VERSION-$PKGARCH-$BUILD.txz

echo "*****************************************************************"
echo "Building package: $SLACKPACKAGE"
echo "*****************************************************************"

# Handle building within /patches:
[ "$SLACKPATCHING" = "no" ] && export PKGSERIES=d

# Enter package root:
cd $TMPBUILD/package-kernel-headers || exit 1

# Install package description:
install -vpm644 $CWD/slack-descs/kernel-headers install/slack-desc

# Apply some of the generic Slackware packaging policies:
slackslack  # chown -R root:root, chmod -R og-w, slack644docs

echo " + Running makepkg for 'kernel-headers'"
slackmp # run makepkg

###############################################################################
# Build the 'k/kernel-source' package:
###############################################################################

# Package information:
export PKGNAM=kernel-source
export SLACKPACKAGE=$PKGNAM-$VERSION-$PKGARCH-$BUILD.txz

echo "*****************************************************************"
echo "Building package: $SLACKPACKAGE"
echo "*****************************************************************"

# Handle building within /patches:
[ "$SLACKPATCHING" = "no" ] && export PKGSERIES=k

# Move the Kernel source into a directory into which we can package it:
cd $KERNELSRCDIR

# Prepare the package framework:
mkdir -vpm755 $TMPBUILD/package-kernel-source/{install,usr/src}

# Move the Linux source into our packaging directory:
# echo "Copying Linux source for packaging..."
# We won't do this since it takes longer and during development
# I never need any of the assets that are removed by the packaging process.
# Reversion: actually, I started using it all the time so we'll copy them now.
# Plus this breaks when using the '--srcdir' option to kernel.SlackBuild.
cp -fa linux-$VERSION $TMPBUILD/package-kernel-source/usr/src/ || exit 1
#mv -fv linux-$VERSION $TMPBUILD/package-kernel-source/usr/src/ || exit 1
cd $TMPBUILD/package-kernel-source/usr/src || exit 1

# Ensure that the linux dir name matches the $VERSION of the package so that
# in the a/kernel package, the /lib/modules/*/{build,source}
# symlinks are correct.
ln -vfs linux-$VERSION linux
cd linux || exit 1

# Prepare for packaging:
echo " + Cleaning up the source tree"
make ARCH=$LINUXKERNELARCH clean
# Make sure header files aren't missing:
make ARCH=$LINUXKERNELARCH prepare
# Don't package the kernel in the sources:
find . -name "*Image" -exec rm "{}" \;
# No need for these:
rm -fv .config.old .version
find . -name "*.cmd" -exec rm -f "{}" \;
rm -v .*.d
find . -name '.gitignore' -print0 | xargs -0 rm -rf
find . -name '.tmp*' -print0 | xargs -0 rm -rf
# Still some dotfiles laying around... probably fine though
# Get rid of any ELF (non-eBPF) binaries that are not executable:
find . -type f -perm 0644 ! -name "*.c" ! -name "*.h" ! -name "*.S" ! -name "*.dts*" ! -name "Makefile*" ! -name Kbuild ! -name "*config" ! -name ".git*" ! -name "*.rst" ! -name "*.txt" | xargs file | grep ELF | grep -v eBPF | grep stripped | cut -f 1 -d : | while read elf_binary ; do
  rm -f -v $elf_binary
done
# Strip any remaining binaries:
find . -type f ! -name "*.c" ! -name "*.h" ! -name "*.S" ! -name "*.dts*" ! -name "Makefile*" ! -name Kbuild ! -name "*config" ! -name ".git*" ! -name "*.rst" ! -name "*.txt" | xargs file | grep -e "executable" -e "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null

# Install package description:
cd $TMPBUILD/package-kernel-source
install -vpm644 $CWD/slack-descs/kernel-source install/slack-desc

# Apply some of the generic Slackware packaging policies:
slackslack  # chown -R root:root, chmod -R og-w, slack644docs

echo " + Running makepkg for 'kernel-source'"
slackmp # run makepkg

#EOF
