#!/bin/bash
ulimit -s unlimited
shopt -s extglob

# grub.SlackBuild
# Heavily based on the original Slackware build scripts,
# Modified by Stuart Winter for Slackware ARM.
#
# Copyright 2013-2025  Patrick J. Volkerding, Sebeka, Minnesota, USA
# 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.
#
# Modified 2016 by Eric Hameleers <alien@slackware.com> for Slackware Live Edition.

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

# Paths to skeleton port's source & real Slackware source tree:
slackset_var_cwds

# Detect whether we're building for /patches:
# This function sets the variable 'SLACKPATCHING'
slack_findpkgstore_is_stablerelease

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

# Architecture-specific settings:
case $ARCH in
   aarch64)
      LIBDIRSUFFIX="64"
      EFI_FLAGS=" --with-platform=efi --target=${SLK_ARCH_BUILD} --program-prefix= "
      # Remove -fPIC from CFLAGS set by slackkit's config
      SLKCFLAGS="${SLKCFLAGS/-fPIC/}";;
esac

# If you use stack-protector, then grub will not work with legacy BIOS:
STACKPROTECT=${STACKPROTECT:---enable-stack-protector=no}

# Extract source:
tar xvvf $CWD/$PKGNAM-$VERSION.tar.!(*sign|*asc|*sig)
cd $PKGNAM-*/ || failextract
slackhousekeeping

# Refresh libtool to support latest architectures:
slackupdatelibtool

# Apply patches:
# Accept /boot/initrd.gz as a valid initrd name (obsolete?):
cat $CWD/initrd_naming.patch | patch -p1 --verbose || exit 1

# Set default gfxterm font:
cat $CWD/grub.gfxterm.font.diff | patch -p1 --verbose || exit 1

# Fix alignment error with gcc8:
cat $CWD/0198-align-struct-efi_variable-better.patch | patch -p1 --verbose || exit 1

# Skip processing any files in /etc/grub.d/ that end in .new or .orig:
cat $CWD/0001-skip-new-and-orig-files-in-etc-grub.d.patch | patch -p1 --verbose || exit 1

# From Arch, add a couple more GRUB_COLOR options:
cat $CWD/0001-00_header-add-GRUB_COLOR_-variables.patch | patch -p1 --verbose || exit 1

# Also from Arch, support drop-in config bits in /etc/default/grub.d/:
cat $CWD/0003-support-dropins-for-default-configuration.patch | patch -p1 --verbose || exit 1

# Fix 2.12 release with upstream commit (won't compile otherwise):
cat $CWD/b835601c7639ed1890f2d3db91900a8506011a8e.patch | patch -p1 --verbose || exit 1

# For Slackware, opt-out of having our operating system renamed:
cat $CWD/10_linux.osname.patch | patch -p1 --verbose || exit 1

# Allow defining an initrd fallback name with the
# GRUB_INITRD_FALLBACK_NAME variable in /etc/default/grub.
# Commented out by default.
cat $CWD/0004-initrd_fallback_name.patch | patch -p1 --verbose || exit 1

# Support displaying only kernels that are files, only kernels that are
# symlinks, or both. This is set with the GRUB_DISPLAY_KERNEL_FILETYPES
# variable in /etc/default/grub:
cat $CWD/0005-GRUB_DISPLAY_KERNEL_FILETYPES.patch | patch -p1 --verbose || exit 1

# Add a warning to the README in /etc/grub.d/ so that users know that the
# standard files in here will be overwritten with every upgrade:
cat $CWD/0006-warn-grub.d-overwrites-docs.patch | patch -p1 --verbose || exit 1

# This double space at the top of the menu just looks bad.
cat $CWD/0333-dont-double-space-header.patch | patch -p1 --verbose || exit 1

# Revert a patch that breaks legacy boot. This was added to fix LLVM's lld, but
# it breaks linking with ld.bfd (while confusingly blaming the problem on ld.gold
# which we no longer have.) This also requires the autoreconf -vif below.
cat $CWD/0001-configure-Check-linker-for-image-base-support.patch | patch -R -p1 --verbose || exit 1

# Revert this one as well:
cat $CWD/0001-configure-Print-a-more-helpful-error-if-autoconf-arc.patch | patch -R -p1 --verbose || exit 1

# Still won't compile. Someday they'll remember how to cut a new release.
#touch grub-core/extra_deps.lst

# Regenerate build system to fix dependency on outdated automake:
autoreconf -vif

build_grub() {
  EFI_DO="$*"
  # Configure:
  CFLAGS="$SLKCFLAGS" \
  ./configure \
     --prefix=/usr \
     --libdir=/usr/lib${LIBDIRSUFFIX} \
     --sysconfdir=/etc \
     --localstatedir=/var \
     --infodir=/usr/info \
     --mandir=/usr/man \
     --with-dejavufont=/usr/share/fonts/TTF/DejaVuSans.ttf \
     --disable-werror \
     $STACKPROTECT \
     $EFI_DO || failconfig

  # Build:
  make clean || failmake
  make $NUMJOBS || make || failmake
  # Install into package:
  make install DESTDIR=$PKG || failinstall

  # Clear $EFI_DO :
  unset EFI_DO
}

# Build with 64bit settings for AArch64:
build_grub $EFI_FLAGS || failmake
# Regular build:
build_grub || failmake

# Add custom 09_slackware_linux config. Thanks to Richard Cranium for the
# initial version, and Daedra for making it POSIX compliant:
#install -vpm755 $CWD/09_slackware_linux $PKG/etc/grub.d/09_slackware_linux

# Preserve files in /etc/grub.d/:
for file in $PKG/etc/grub.d/*_* ; do
  mv -fv ${file} ${file}.new
done

# Add an update-grub script ala Ubuntu:
#install -vpm755 $CWD/update-grub $PKG/usr/sbin/update-grub
# Install the ARM version which only writes the new GRUB binary rather than
# editing the config file(s):
install -vpm755 $PORTCWD/sources/update-grub $PKG/usr/sbin/

# Since every other grub command is of the form "grub-{command}", add a symlink
# so that "grub-update" also works:
ln -vsf update-grub $PKG/usr/sbin/grub-update

# Put bash-completion file in system directory:
mkdir -vpm755 $PKG/usr/share/bash-completion/completions/
mv -fv $PKG/etc/bash_completion.d/grub \
       $PKG/usr/share/bash-completion/completions/grub
rmdir --parents $PKG/etc/bash_completion.d 2>/dev/null

# Install default options file:
mkdir -vpm755 $PKG/etc/default/grub.d
install -vpm644 $CWD/etc.default.grub $PKG/etc/default/grub.new
# Add a hint:
echo "Files in this directory must end in .cfg to be processed." > $PKG/etc/default/grub.d/README

# Create a directory for grub.cfg:
mkdir -p $PKG/boot/grub

# Add fonts, if found on the system:
FONT_SIZE=${FONT_SIZE:-20}
mkdir -p $PKG/boot/grub/fonts
if [ -r /usr/share/fonts/TTF/DejaVuSansMono.ttf ]; then
   $PKG/usr/bin/grub-mkfont -o $PKG/boot/grub/fonts/dejavusansmono.pf2 -av \
   -s $FONT_SIZE /usr/share/fonts/TTF/DejaVuSansMono.ttf
   $PKG/usr/bin/grub-mkfont -o $PKG/boot/grub/fonts/dejavusansmonobold.pf2 -abv \
   -s $FONT_SIZE /usr/share/fonts/TTF/DejaVuSansMono.ttf
fi
if [ -r /usr/share/fonts/TTF/Hack-Regular.ttf ]; then
   $PKG/usr/bin/grub-mkfont -o $PKG/boot/grub/fonts/hack.pf2 -av \
   -s $FONT_SIZE /usr/share/fonts/TTF/Hack-Regular.ttf
   $PKG/usr/bin/grub-mkfont -o $PKG/boot/grub/fonts/hackbold.pf2 -abv \
   -s $FONT_SIZE /usr/share/fonts/TTF/Hack-Regular.ttf
fi

# We put the fonts in /boot/grub but make symlinks in /usr/share/grub:
( cd $PKG/boot/grub/fonts
  for font in *.pf2 ; do
    ln -vsf /boot/grub/fonts/$font $PKG/usr/share/grub/$font
  done )

# Slackware ARM modifications:
# Enable finding the symlink to the AArch64 Kernel.
# Note that this won't find armv10 Kernels but yet we're not even on armv9 yet ;-)
sed -i 's?for i in /boot/vmlinuz-\*?for i in /boot/vmlinuz-\* /boot/Image-armv\??g' $PKG/etc/grub.d/10_linux.new

# Stop people using 'grub-mkconfig' since it'll break their GRUB config, and is unnecessary
# since we deploy a working one within the Slackware Installer:
sed -i '/set -e/a\[ -z "$GRUBMKCONFIG_ALLOWEXEC" ] && { echo "$0 should not be used on ARM. Edit /boot/grub/grub.cfg manually if required."; exit 1 ;}' $PKG/usr/sbin/grub-mkconfig

# Add a documentation directory:
mkdir -vpm755 $PKG/usr/doc/${PKGNAM}-$VERSION
cp -fav \
    AUTHORS BUGS COPYING* INSTALL NEWS README* THANKS TODO \
    $PKG/usr/doc/${PKGNAM}-$VERSION
changelogliposuction ChangeLog $PKGNAM $VERSION # Trim down a "ChangeLog" file

# Apply generic Slackware packaging policies:
cd $PKG
slackstripall        # strip all .a archives and all ELFs
#slackstriprpaths     # strip rpaths
slack_delete_lafiles # delete usr/lib{,64}/*.la
slackgzpages -i      # compress man & info pages and delete usr/info/dir
slackslack           # set standard Slackware file/dir permissions and ownerships
slackdesc            # install slack-desc and doinst.sh

# Add our local post install script modifications:
cat $PORTCWD/sources/doinst.sh >> $PKG/install/doinst.sh

slackmp -p           # run makepkg --prepend -l y -c n

# Perform any final checks on the package:
cd $PKG
slackhlinks     # search for any hard links
