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

# binutils.SlackBuild
# by Stuart Winter <mozes@slackware.com> for the Slackware porting Project.
# Heavily based on the original Slackware build script.
# 30-May-2004
#
# Copyright 2005-2016  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.

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

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

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

# Determine extra configurations for this architecture:
case $ARCH in
   arm)     SLKCFLAGS="$SLKCFLAGS -g -marm -fPIC"
            # -werror Needed for i486 but doesn't harm on ARM
            # --enable-relro=yes and --enable-lto is used for a few ARM builds.
            SLKCONFARGS="--disable-werror --enable-deterministic-archives --enable-relro=yes --enable-lto" ;;
   aarch64) SLKCFLAGS="${SLKCFLAGS} -g -fPIC"
            SLKCONFARGS="--disable-werror --enable-deterministic-archives --enable-relro=yes --enable-lto" ;;
esac

# For use in dir names.  Slackware x86 script uses $TARGET, we use the same
# SLK_ARCH_TARGET is set in /usr/share/slackkit/buildkit.sh

# Set to ld.gold or ld.bfd:
DEFAULT_LD=ld.bfd

# Extract source:
# It's easier to stick with what Debian are doing.  I've been bitten too many
# times in the past by weirdness with binutils.
#tar xvvf $PORTCWD/sources/$PKGNAM*$VERSION*tar*z*
#tar xvvf $PORTCWD/binutils-2.35.1-x86SlackBuild/$PKGNAM*$VERSION.tar.!(*sign|*asc|*sig)
tar xvvf $CWD/$PKGNAM*$VERSION.tar.!(*sign|*asc|*sig)
cd $PKGNAM* || exit 1
slackhousekeeping

# Apply Slackware patches:
echo "*** Applying patches ***"
# These were shipped empty and will need to be regenerated:
rm -f binutils/doc/*.1 binutils/doc/*.man gprof/gprof.1 ld/ld.1 gas/doc/as.1

# Export the demangle.h header file (I suspect this is obsolete...):
zcat $CWD/patches/binutils-export-demangle.h.patch.gz | patch -p1 --verbose || exit 1

# Don't check to see if "config.h" was included in the installed headers:
zcat $CWD/patches/binutils-no-config-h-check.patch.gz | patch -p1 --verbose || exit 1

# Set %version to something halfway meaningful:
zcat $CWD/patches/binutils-version.patch.gz | patch -p1 --verbose || exit 1
sed -i -e 's/%''{release}/slack15/g' bfd/Makefile{.am,.in}

# Use the "unsigned long long" type for pointers on hosts where long is a
# 32-bit type but pointers are a 64-bit type.  Necessary because users expect
# to be able to install both the x86 and x86_64 versions of binutils on the
# same machine, so they need identical versions of the bfd.h header file.
zcat $CWD/patches/binutils-use-long-long.patch.gz | patch -p1 --verbose || exit 1

# Work around a bug caused by binutils using an ancient libtool:
zcat $CWD/patches/binutils-libtool-lib64.patch.gz | patch -p1 --verbose || exit 1

# Various regression fixes:
zcat $CWD/patches/binutils-2.27-aarch64-ifunc.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-CVE-2019-1010204.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-bfd-close-fds.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-do-not-link-with-static-libstdc++.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-dwarf-5-dir0.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-filename-in-error-messages.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-fix-testsuite-failures.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-gold-i386-gnu-property-notes.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-gold-mismatched-section-flags.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-gold-warn-unsupported.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-missing-man-pages.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-readelf-other-sym-info.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-revert-PLT-elision.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-special-sections-in-groups.patch.gz | patch -p1 --verbose || exit 1
zcat $CWD/patches/binutils-testsuite-fixes.patch.gz | patch -p1 --verbose || exit 1

# Thanks to Fedora:
# Dependencies are not set up to rebuild the configure files
# in the subdirectories.  So we just rebuild the ones we care
# about after applying the configure patches
pushd libiberty
autoconf
popd
pushd intl
autoconf
popd

#
# Apply local patches:
# https://src.fedoraproject.org/rpms/binutils/
#
# From Debian:
#if [ -f $PORTCWD/sources/${PKGNAM}_*diff* ]; then
#   echo "*** Applying patches from Debian ***"
#   ( xz -dc $PORTCWD/sources/$PKGNAM*diff* | patch -p1 ) || exit 1
##    grep -A99 "# patches taken from the trunk" debian/patches/series | egrep -v "^#" | while read pf ; do
#       for pf in \
#       \
#        branch-updates.diff \
#        branch-version.diff \
#        \
#        ; do
#       auto_apply_patch debian/patches/$pf || exit 1
#   done
#fi
#for pf in \
#  \
#  binutils-2.28-ignore-gold-duplicates.patch \
#  \
#   ; do
#     auto_apply_patch $PORTCWD/sources/${pf}.xz || exit 1
#   done
# This one has patches lower down in the set which rely on those above it to have been
# applied, so auto patch level dry-run detection above doesn't work:
#xz -dc $PORTCWD/sources/binutils-2.26-lto.patch.xz | patch -p1 --verbose || exit 1

# Configure:
CFLAGS="$SLKCFLAGS" \
CPPFLAGS="$SLKCFLAGS" \
CXXFLAGS="$SLKCFLAGS" \
./configure \
   \
   $SLKCONFARGS \
   \
   --prefix=/usr \
   --mandir=/usr/man \
   --infodir=/usr/info \
   --libdir=/usr/lib${LIBDIRSUFFIX} \
   --with-docdir=/usr/doc/$PKGNAM-$VERSION \
   --disable-compressed-debug-sections \
   --enable-targets=i386-efi-pe,${SLK_ARCH_TARGET},x86_64-pep \
   --enable-install-libiberty \
   --enable-shared \
   --enable-plugins \
   --enable-threads \
   --enable-gold=yes \
   --enable-ld=default \
   --enable-initfini-array \
   --enable-64-bit-bfd \
   --build=${SLK_ARCH_BUILD} || failconfig
# Not for ARM:
#   --enable-multilib \

# Build:
#
# Use "tooldir=/usr" to avoid internal references to the /usr/${SLK_ARCH_TARGET}/
# directory. While binutils won't actually use that directory after this,
# we'll still create it since some people have made local use of it.
# Note that this will place ldscripts in /usr/lib, even on $ARCH that
# use LIBDIRSUFFIX=64. According to Ian Lance Taylor, the ldscripts have
# been built into the linker for quite some time and the ones in the
# filesystem aren't actually loaded. For the most part they are now
# documentation and it doesn't matter where they reside.
make tooldir=/usr $NUMJOBS || make tooldir=/usr || exit 1

# Install into package:
make tooldir=/usr install DESTDIR=$PKG || exit 1

# Using tooldir=/usr also makes the /usr/${SLK_ARCH_TARGET}/lib${LIBDIRSUFFIX}
# directory obsolete, and the build will no longer install it. But since
# some people might be making local use of that directory, we'll install
# it anyway:
mkdir -p $PKG/usr/${SLK_ARCH_TARGET}/lib${LIBDIRSUFFIX}
# Same with /usr/${SLK_ARCH_TARGET}/bin:
mkdir -p $PKG/usr/${SLK_ARCH_TARGET}/bin

# Add a symlink since binutils's version of strings used to be called
# "strings-GNU" on Slackware, and it's possible that people have scripts
# that use that name:
( cd $PKG/usr/bin ; ln -vsf strings strings-GNU )

## Copy demangle.h, since some things might be looking for it in /usr/include,
## and others in /usr/include/libiberty:
#if [ -e $PKG//usr/include/libiberty/demangle.h -a ! -e $PKG//usr/include/demangle.h ]; then
#  cp -a $PKG//usr/include/libiberty/demangle.h $PKG//usr/include/demangle.h
#fi

# COMMENTED OUT, since a valid use case was provided for windres on Linux.
# None of these tools are very large, and unless they can be shown to be
# non-functional, there's no good reason to exclude them.
## Remove Windows specific tools / docs (if they exist):
#rm -f $PKG/usr/bin/{dlltool,nlmconv,windres,windmc}
#rm -f $PKG/usr/man/man1/{dlltool,nlmconv,windres,windmc}*

# If the requested default linker is present, make it the default:
# Set the link differently on the system to change the default at runtime.
if [ -r $PKG/usr/bin/$DEFAULT_LD ]; then
  ( cd $PKG/usr/bin ; rm -f ld ; ln -sf $DEFAULT_LD ld )
fi

# Remove some unneeded man pages, and then compress the rest
rm -f $PKG/usr/man/man1/{dlltool*,windres*,windmc*}
( cd $PKG/usr/man
  find . -type f -exec gzip -9 {} \;
  for i in $(find . -type l) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
)
# Remove unneeded binaries - these are for Windows:
# This is probably a bit agressive actually, since it's only "windres" that doesn't
# work ("cannot detect architecture") and causes builds to fail.
#rm -fv $PKG/usr/bin/{windmc,dlltool,dllwrap,windres}
#rm -fv $PKG/usr/*-slackware-linux*/bin/dlltool
rm -fv $PKG/usr/bin/windres

# Copy docs:
mkdir -p $PKG/usr/doc/binutils-$VERSION
cp \
  $CWD/release.binutils-* \
  COPYING* ChangeLog.linux MAI* README* \
  $PKG/usr/doc/binutils-$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      # chown -R root:root, chmod -R og-w, slackchown, slack644docs
slackdesc       # install slack-desc and doinst.sh
slackmp         # run makepkg -l y -c n

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

cat << EOF

######################################################################
Now rebuild oprofile because it links to libbfd (part of this package)
######################################################################

EOF
