#!/bin/bash

# build glibc-$VERSION for Slackware
# by Patrick J. Volkerding <volkerdi@slackware.com>
#
# Modified by Stuart Winter <stuart@armedslack.org> for ARMedslack.
# 

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

# Paths to skeleton port's source & real Slackware source tree:
export CWD=$SLACKSOURCE/$PKGSERIES/$PACKAGE
export PORTCWD=$PWD

# Determine the CFLAGS for the known architectures:
case $PORTARCH in
   arm)       SLKCFLAGS="-g -O2 -march=armv3 -mtune=xscale" 
              # StrongARM RiscPC has no FPU h/w (emulation is done in the Kernel):
              ARCH_CONFARGS="--with-fp=no" 
              ;;
   powerpc)   SLKCFLAGS="-g -O2 -march=? -mtune=?" ;;
esac

# Function to extract Debian packaged glibc source:
# No - no longer using Debian packaged stuff.  It's too much work!
function extractglibcsource () {
  cd $TMPBUILD
  rm -rf glibc*
  # tar zxvvf $PORTCWD/sources/glibc_${VERSION}.orig.tar.gz
  # cd glibc*

  # Unpack the debian diff:
  # DEBDIFFVER=13 # previous working version was 7 - for Debian source:
  # DEBDIFFVER=6 
  # zcat $PORTCWD/sources/glibc_${VERSION}-*${DEBDIFFVER}.diff.gz | patch -p1

  # Apply patches from the Debian diff (also extracts glibc source & overlays linuxthreads & libidn):
  # make -f debian/rules patch

  # Ensure sensible ownerships & permissions:
  # slackhousekeeping 

  # Change into the glibc source dir:
  # cd build-tree/glibc-$VERSION

  # Overlay libidn.  This used to be extracted with make debian/rules patch
  # but no longer it seems.
  # tar jxvvf ../../glibc-libidn-$VERSION.tar.bz2 || failextract
  # tar jxvvf ../../glibc-linuxthreads-$VERSION.tar.bz2 || failextract

  # Unpack the main from the Slackware source tree:
  tar jxvvf $CWD/glibc-$VERSION.tar.bz2
  cd glibc*
  tar jxvvf $CWD/glibc-libidn-$VERSION.tar.bz2
  tar jxvvf $CWD/glibc-linuxthreads-$VERSION.tar.bz2
  find . -type d -name CVS -print0 | xargs -0 rm -rf

  # Apply Slackware-specific patches:
  #
  # Use old-style locale directories rather than a single (and strangely
  # formatted) /usr/lib/locale/locale-archive file:
  # [ This is a Slackware-specific patch from glibc-2.3.4 (introduced in glibc-2.3.3's SlackBuild) ]
  zcat $CWD/glibc.locale.no-archive.diff.gz | patch -p1 --verbose || failpatch
  #
  # Fix XMMS/X crash caused by interaction with nVidia drivers:
  zcat $CWD/glibc.tls.crashfix.diff.gz | patch -p1 --verbose || failpatch
  # Fix NIS netgroups:
  zcat $CWD/glibc.nis-netgroups.diff.gz | patch -p1 --verbose || failpatch
  # Evidently glibc never expected Linux kernel versions to be in the
  # format 1.2.3.4.  This patch makes glibc consider the kernel version
  # to be only the first three digit groups found, and drops any
  # trailing non-digit characters:
  zcat $CWD/glibc.kernelversion.diff.gz | patch -p1 --verbose || failpatch
  # Support ru_RU.CP1251 locale:
  zcat $CWD/glibc.ru_RU.CP1251.diff.gz  | patch -p1 --verbose || failpatch
  # Support sa_IN locale:
  zcat $CWD/glibc.sa_IN.diff.gz         | patch -p1 --verbose || failpatch

  # Apply ARM specific patches: these are taken from Debian's diff.
  patch -p0 --fuzz=20 --verbose < $PORTCWD/sources/arm/cvs-float-byteorder.diff   || failpatch
  patch -p1 --fuzz=20 --verbose < $PORTCWD/sources/arm/cvs-gcc4-inline.diff       || failpatch
  patch -p1 --fuzz=20 --verbose < $PORTCWD/sources/arm/cvs-gcc4.1-raise.diff      || failpatch
  patch -p0 --fuzz=20 --verbose < $PORTCWD/sources/arm/cvs-socket-weakalias.diff  || failpatch
  patch -p0 --fuzz=20 --verbose < $PORTCWD/sources/arm/local-dwarf2-buildfix.diff || failpatch
  patch -p0 --fuzz=20 --verbose < $PORTCWD/sources/arm/local-ioperm.diff          || failpatch
  patch -p0 --fuzz=20 --verbose < $PORTCWD/sources/arm/local-no-hwcap.diff        || failpatch
  patch -p0 --fuzz=20 --verbose < $PORTCWD/sources/arm/local-softfloat.diff       || failpatch
  patch -p1           --verbose < $PORTCWD/sources/arm/local-version-sanity.diff  || failpatch

# if [ $CVSVER = 2.3.6 ]; then
    # Update the timezone information, or a lot of people will be
    # very unhappy...
    ( cd timezone
      tar xzf $CWD/tzdata2006k.tar.gz
      chown root:root *
      mv yearistype.sh yearistype
      chmod 644 *
      chmod 755 yearistype
      mkdir tzcode
      cd tzcode
      tar xzf $CWD/tzcode2006k.tar.gz
      chown -R root:root .
      chmod 644 *
      cp -a *.c *.h ..
    )
#  else
#    exit 1
#  fi
  
  # Create a separate build directory:
  mkdir build_dir
  cd build_dir
}

# For dual NPTL/linuxthreads support we need one set of 2.4 kernel sources
# and another set of 2.6 kernel sources under /usr/src/.  This specifies the
# exact versions we want to use for compilation:
# I remember now why I still use headers from Linux 2.4.21 - the others give
# "waitpid: function not implemented".
# I'm glad I've got a good memory otherwise I'd have spent about a finding the same
# solution to this same problem I had with previous glibc versions when I changed
# to a newer Kernel.
HEADERSTWOFOUR=2.4.21
HEADERSTWOSIX=2.6.18
#HEADERSTWOSIX=2.6.14.6

## Where are our Kernel headers?
#if [ -d /scratchbox ]; then
#   # I can't get glibc to build against Linux 2.4 headers, so I keep linux 2.6 kicking 
#   # around inside my sbox home area:
#   LHEADERS=$HOME/linux-2.6.2/include 
# else
#   # We're building natively and the headers are where they should be, and what's more
#   # glibc happily compiles with them.
#   LHEADERS=/usr/include
#fi

# Temporary build locations:
export TMPBUILD=$TMP/build-$PACKAGE
# This is the initial $DESTDIR:
export PKG=$TMP/package-glibc-incoming-tree
# We need another tmp initial $DESTDIR for the NPTL version now, too:
export PNPTL=$TMP/package-glibc-incoming-tree-nptl
mkpkgdirs # Delete & re-create temporary directories then cd into $TMPBUILD

# Then we'll compile the following packages from it:
PGLIBC=$TMP/package-glibc
PSOLIBS=$TMP/package-glibc-solibs
PZONE=$TMP/package-glibc-zoneinfo
PI18N=$TMP/package-glibc-i18n
PPROFILE=$TMP/package-glibc-profile
PDEBUG=$TMP/package-glibc-debug

# Empty & create these locations first:
for dir in $PKG $PGLIBC $PSOLIBS $PZONE $PI18N $PPROFILE $PDEBUG $PNPTL ; do
    rm -rf $dir
    mkdir -p $dir
done

# Create an incoming directory structure for glibc to be built into:
mkdir -p $PKG/{var/{run/nscd,db/nscd},lib,sbin,usr/{bin,lib,sbin,include,doc,man,share}}
# And for PNPTL:
mkdir -p $PNPTL/{var/{run/nscd,db/nscd},lib,sbin,usr/{bin,lib,sbin,include,doc,man,share}}

# Extract our pre-made Linux Kernel include files.
# All I did for these was extract the source, copy the config file in place and
# run make oldconfig, then tar up the include dir.
mkdir -p $TMPBUILD/headers{2.4,2.6}/include
echo "Extracting Linux 2.4 Kernel headers into $TMPBUILD"
tar jxf $PORTCWD/sources/arm/kernel-headers-${HEADERSTWOFOUR}.tar.bz2 -C $TMPBUILD/headers2.4
echo "Extracting Linux 2.6 Kernel headers into $TMPBUILD"
tar jxf $PORTCWD/sources/arm/kernel-headers-${HEADERSTWOSIX}.tar.bz2 -C $TMPBUILD/headers2.6/include

################# Build linuxthreads version of glibc #############################
echo "[**] Building linuxthreads version of glibc (Linux 2.4) [**]"

# Extract, patch the source & cd into the build dir:
extractglibcsource

# Configure:
# Kernel 2.4.22 is what we currently have on the Iyonix.
CFLAGS="$SLKCFLAGS" \
../configure $ARCH_CONFARGS \
   --prefix=/usr \
   --enable-add-ons=libidn,linuxthreads \
   --with-tls \
   --without-__thread \
   --without-cvs \
   --build=$ARCH-slackware-linux \
   --host=$ARCH-slackware-linux \
   --enable-kernel=2.4.22 \
   --with-headers=$TMPBUILD/headers2.6/include \
   --target=$ARCH-slackware-linux || failconfig

#   --with-headers=$TMPBUILD/headers2.4/include \
#   --enable-kernel=2.4.1 \

# Build:
make || failmake

# Install into local package:
make install install_root=$PKG

# Build locale data:
make localedata/install-locales install_root=$PKG

################# Build nptl version of glibc #############################
#echo "[**] Building NPTL version of glibc (Linux 2.6) [**]"

## Extract, patch the source & cd into the build dir:
#extractglibcsource

## Configure:
#CFLAGS="$SLKCFLAGS" \
#../configure $ARCH_CONFARGS \
#   --prefix=/usr \
#   --enable-add-ons=libidn,nptl \
#   --enable-kernel=2.6.4 \
#   --with-tls \
#   --with-__thread \
#   --without-cvs \
#   --with-headers=$TMPBUILD/headers2.6/include \
#   --build=$ARCH-slackware-linux \
#   --host=$ARCH-slackware-linux \
#   --target=$ARCH-slackware-linux || failconfig

# Build:
#make || failmake

## Install into local package:
#make install install_root=$PNPTL

## Build locale data:
# This is still commented from the real slackbuild:
#make localedata/install-locales install_root=$PNPTL

# Relocate the NPTL libraries in /lib/tls/incoming:
#( cd $PNPTL/lib
#  mkdir -p $PKG/lib/tls/incoming
#  mv * $PKG/lib/tls/incoming
#  mv $PKG/lib/tls/incoming/libSegFault.so $PKG/lib/tls )

# Put some of the NPTL versions of the libraries into /usr/lib/nptl/
# in case something needs to links against them:
#( cd $PNPTL/usr/lib
#  mkdir -p $PKG/usr/lib/nptl
#  cp -a libc.a libpthread.a libpthread_nonshared.a librt.a $PKG/usr/lib/nptl
#  cp -a $CWD/nptl-so/* $PKG/usr/lib/nptl
#  chown root:root $PKG/usr/lib/nptl/*.so
#  chmod 644 $PKG/usr/lib/nptl/*.so
#  ( cd $PKG/usr/lib/nptl
#    strip -g *
#    ln -sf /lib/tls/librt-${VERSION}.so librt.so )
#)

# Extract unique NPTL headers to put in /usr/include/nptl/:
#cd $TMP
#rm -f nptl-includelist
#( cd $PNPTL
#  find usr/include -type f >> $TMP/nptl-includelist )
## Next, make a copy of the different includes:
#rm -rf $TMP/nptl-includes
#mkdir -p $TMP/nptl-includes
#for file in `cat $TMP/nptl-includelist` ; do
#  # Make a copy of any header found only in NPTL:
#  if [ ! -r $PKG/$file ] ; then
#    ( cd $PNPTL
#      echo $file uniq
#      cp -a --parent $file $TMP/nptl-includes )
#  # Otherwise, make a copy if the files are different:
#  elif ! diff --brief $PKG/$file $PNPTL/$file 1> /dev/null 2> /dev/null ; then
#    ( cd $PNPTL
#      echo $file diff
#      cp -a --parent $file $TMP/nptl-includes )
#  fi
#done

## Now add these files in $PKG:
#mkdir $PKG/usr/include/nptl
#cp -a $TMP/nptl-includes/usr/include/* $PKG/usr/include/nptl

##########################################################################

# The prevailing standard seems to be putting unstripped libraries in
# /usr/lib/debug/ and stripping the debugging symbols from all the other
# libraries except the profiling ones:
mkdir -p $PKG/usr/lib/debug
cp -a $PKG/lib/l*.so*  $PKG/usr/lib/debug
cp -a $PKG/usr/lib/*.a $PKG/usr/lib/debug
# Don't need debug+profile:
( cd $PKG/usr/lib/debug ; rm -f *_p.* )

# Strip:
strip -g $PKG/lib/l*.so*
strip -g $PKG/usr/lib/l*.so*
strip -g $PKG/usr/lib/lib*.a

# Back into the source dir to get docs and stuff:
# From the building using Debian sources:
#cd $TMPBUILD/glibc-*/build-tree/glibc-$VERSION
# Slackware/clean sources:
cd $TMPBUILD/glibc-*

# We'll automatically install the config file for the Name Server Cache Daemon.
# Perhaps this should also have some commented-out startup code in rc.inet2...
mkdir -p $PKG/etc
cat nscd/nscd.conf > $PKG/etc/nscd.conf.new

# Install some scripts to help select a timezone:
mkdir -p $PKG/var/log/setup
cp -a $CWD/timezone-scripts/setup.timeconfig $PKG/var/log/setup
chown root:root $PKG/var/log/setup/setup.timeconfig
chmod 755 $PKG/var/log/setup/setup.timeconfig
mkdir -p $PKG/usr/sbin
cp -a $CWD/timezone-scripts/timeconfig $PKG/usr/sbin
chown root:root $PKG/usr/sbin/timeconfig
chmod 755 $PKG/usr/sbin/timeconfig

## Install docs:
( mkdir -p $PKG/usr/doc/$PACKAGE-$VERSION/linuxthreads
  cp -a BUGS CONFORMANCE COPYING COPYING.LIB FAQ INSTALL INTERFACE LICENSES \
        NAMESPACE NEWS NOTES PROJECTS README README.libm \
        $PKG/usr/doc/$PACKAGE-$VERSION
  cd linuxthreads
  cp -a Banner FAQ.html LICENSE README README.Xfree3.2 linuxthreads.texi \
        Examples $PKG/usr/doc/$PACKAGE-$VERSION/linuxthreads
  cd man
  mkdir -p $PKG/usr/man/man3
  for file in *.man ; do
    cat $file | gzip -9c > $PKG/usr/man/man3/`basename $file .man`.3.gz
  done 
  find $PKG/usr/doc/glibc-$VERSION -type d | xargs chmod 755 
  find $PKG/usr/doc/glibc-$VERSION -type f | xargs chmod 644 )

# Don't forget to add the /usr/share/zoneinfo/localtime -> /etc/localtime symlink! :)
if [ ! -r $PKG/usr/share/zoneinfo/localtime ]; then
   ( cd $PKG/usr/share/zoneinfo ; ln -sf /etc/localtime . )
fi

# Start fakeroot server:
start_fakeroot

# Slackware policy:
( cd $PKG
  # root:root
  slackchown 

  # 644 docs:
  slack644docs

  # Strip most binaries:
  find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
  find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip -g 2> /dev/null

  # gzip man & info pages:
  slackgzpages -i

  # This is junk
  rm -f etc/ld.so.cache
  rm sbin/sln
  find . -name "*.orig" -exec rm -f {} \; 

  # These contain scratchbox paths when built inside sbox:
  sed -i '1s/.*/#!\/bin\/bash/' usr/bin/xtrace usr/bin/tzselect )

##################################
# OK, time to make some packages #
##################################

# Delete old package versions?
if [ "${DELETEOLDPKGS}" = "Yes" ]; then
   rm -f $PKGSTORE/a/glibc-{zoneinfo,solibs}*
   rm -f $PKGSTORE/l/glibc-*
   rm -f $PKGSTORE/l/glibc-{debug,profile}*
#   rm -f $PKGSTORE/../extra/glibc-extra-packages/glibc-{debug,profile}*
fi

# glibc-zoneinfo.  We will start with an easy one to avoid breaking a sweat.  ;-)
cd $PZONE
# Install some scripts to help select a timezone:
mkdir -p $PZONE/var/log/setup
cp -a $CWD/timezone-scripts/setup.timeconfig $PZONE/var/log/setup
chown root:root $PZONE/var/log/setup/setup.timeconfig
chmod 755 $PZONE/var/log/setup/setup.timeconfig
mkdir -p $PZONE/usr/sbin
cp -a $CWD/timezone-scripts/timeconfig $PZONE/usr/sbin
chown root:root $PZONE/usr/sbin/timeconfig
chmod 755 $PZONE/usr/sbin/timeconfig
mkdir -p $PZONE/install
install -m644 $CWD/slack-desc.glibc-zoneinfo $PZONE/install/slack-desc
install -m644 $CWD/doinst.sh-glibc-zoneinfo $PZONE/install/doinst.sh
mkdir -p $PZONE/usr/share
# Fix a long standing bug in the install script:
# woohoo. Now it's in the install script! :)
# perl -pi -e 'print "ldconfig -r .\n" if /chroot \./' $PZONE/install/doinst.sh
cd $PZONE/usr/share
cp -a --verbose $PKG/usr/share/zoneinfo .
cd $PZONE
mkdir -p $PZONE/etc
# This is already hard-coded into doinst.sh (like it'll be there anyway ;-):
rm -f etc/localtime
# Set Slackware root:root package policy:
slackchown
# Wrap it up:
makepkg -l y -c n $PKGSTORE/a/glibc-zoneinfo-$VERSION-noarch-$BUILD.tgz

# glibc-profile:
cd $PPROFILE
mkdir -p usr/lib install
# Might as well just grab these with 'mv' to simplify things later:
mv $PKG/usr/lib/lib*_p.a usr/lib
# Profile libs should be stripped.  Use the debug libs to debug...
( cd usr/lib ; strip -g *.a )
install -m644 $CWD/slack-desc.glibc-profile install/slack-desc
# Set Slackware root:root policy:
slackchown
#makepkg -l y -c n $PKGSTORE/../extra/glibc-extra-packages/glibc-profile-$VERSION-$ARCH-$BUILD.tgz
makepkg -l y -c n $PKGSTORE/l/glibc-profile-$VERSION-$ARCH-$BUILD.tgz

# No longer packaged now Slackware uses glibc-2.3.3:
## glibc-debug:
#cd $PDEBUG
#mkdir -p usr/lib
## Might as well just grab these with 'mv' to simplify things later:
#mv $PKG/usr/lib/debug usr/lib
#mkdir install
#install -m644 $CWD/slack-desc.glibc-debug install/slack-desc
#makepkg -l y -c n $PKGSTORE/../extra/glibc-extra-packages/glibc-debug-$VERSION-$ARCH-$BUILD.tgz

# glibc-i18n:
cd $PI18N
mkdir -p usr/lib
rm -rf usr/lib/locale
cp -a $PKG/usr/lib/locale usr/lib
mkdir -p usr/share
cp -a $PKG/usr/share/i18n usr/share
cp -a $PKG/usr/share/locale usr/share
mkdir install
install -m644 $CWD/slack-desc.glibc-i18n install/slack-desc
# Set Slackware root:root policy:
slackchown
makepkg -l y -c n $PKGSTORE/l/glibc-i18n-$VERSION-noarch-$BUILD.tgz

# glibc-solibs:
cd $PSOLIBS
mkdir -p etc/profile.d
cp -a $CWD/profile.d/* etc/profile.d
chown -R root:root etc
chmod 755 etc/profile.d/*
mkdir -p lib
cp -a $PKG/lib/* lib
( cd lib
  mkdir incoming
  mv *so* incoming
  mv incoming/libSegFault.so . )
( cd lib/tls
  mkdir incoming
  mv *so* incoming
  mv incoming/libSegFault.so . )
mkdir -p usr
cp -a $PKG/usr/bin usr
mv usr/bin/ldd .
rm usr/bin/*
mv ldd usr/bin
mkdir -p usr/lib
# The gconv directory has a lot of stuff, but including it here will save some problems.
# Seems standard elsewhere.
cp -a $PKG/usr/lib/gconv usr/lib
# Another manpage abandoned by GNU...
#mkdir -p usr/man/man1
#cp -a $PKG/usr/man/man1/ldd.1.gz usr/man/man1
mkdir -p usr/libexec
cp -a $PKG/usr/libexec/pt_chown usr/libexec
# Same usr.bin deal:
cp -a $PKG/sbin .
mv sbin/ldconfig .
rm sbin/*
mv ldconfig sbin
mkdir install
install -m644 $CWD/slack-desc.glibc-solibs install/slack-desc
# install -m644 $CWD/doinst.sh-glibc-solibs install/doinst.sh
# We need to remove the NPTL stuff from the install script until such
# time as NPTL exists on ARM.
install -m644 $PORTCWD/doinst.sh-glibc-solibs install/doinst.sh

# Ditch links:
find . -type l -exec rm {} \;
# Delete the old one package?
if [ "${DELETEOLDPKGS}" = "Yes" ]; then
   rm -f $PKGSTORE/a/glibc-solibs-* 
fi
# Set Slackware root:root policy:
slackchown
# Build the package:
makepkg -l y -c n $PKGSTORE/a/glibc-solibs-$VERSION-$ARCH-$BUILD.tgz

# And finally, the complete "all-in-one" glibc package is created
# from whatever was leftover:
cd $PGLIBC
mv $PKG/* .
mkdir -p etc/profile.d
cp -a $CWD/profile.d/* etc/profile.d
chown -R root:root etc
chmod 755 etc/profile.d/*
# Ditch links (these are in doinst.sh-glibc):
find . -type l -exec rm {} \;
mkdir install
install -m644 $CWD/slack-desc.glibc install/slack-desc
#install -m644 $CWD/doinst.sh-glibc install/doinst.sh
# We need to remove the NPTL stuff from the install script until
# such time as ARM supports NPTL.
install -m644 $PORTCWD/doinst.sh-glibc install/doinst.sh

( cd lib
  mkdir incoming
  mv *so* incoming
  mv incoming/libSegFault.so . )

# This stuff is &&'d together because ARMedslack has no NPTL yet, so we end up
# without a /lib/tls, and the 'mkdir incoming' gets made in / and never deleted
# 
( cd lib/tls && mkdir incoming && mv *so* incoming && mv incoming/libSegFault.so . )

# Set Slackware package ownership (root:root) policy:
slackchown
# Build the package:
makepkg -l y -c n $PKGSTORE/l/glibc-$VERSION-$ARCH-$BUILD.tgz

# Done!
