#!/bin/bash
shopt -s extglob

# x11.SlackBuild
# Heavily based on the original Slackware build scripts,
# Modified by Stuart Winter <mozes@slackware.com>
################################################################################
#
# Copyright 2007  Patrick Volkerding, Sebeka, MN, 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.
#
# To build only a single package group, specify it as $1, like:
# ./x11.SlackBuild lib
# To build only a single package, specify both the source directory
# and the name of the package, like:
# ./x11.SlackBuild lib libX11
################################################################################
# Note: This build script (unlike x11.SlackBuild on x86) always upgrades and
#       installs (or reinstalls) the packages that it has just created.  This
#       is because this is the easiest way I've found to build and maintain X
#       since the ARM port began.  There is no choice since I haven't merged
#       the choice logic from x86 into this version of the script.
#       You're expected to run this script on a disposable build server.
################################################################################

echo "Command line: $@"

# 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
SLACK_X_BUILD_DIR=$TMPBUILD

# Create a location to store build failure stamps:
mkdir -vpm755 $PORTCWD/build-logs/$SLKPORTARCH/fails

# Functions:
pkgbase() {
  PKGEXT=$(echo $1 | rev | cut -f 1 -d . | rev)
  case $PKGEXT in
  'gz' )
    PKGRETURN=$(basename $1 .tar.gz)
    ;;
  'bz2' )
    PKGRETURN=$(basename $1 .tar.bz2)
    ;;
  'lzma' )
    PKGRETURN=$(basename $1 .tar.lzma)
    ;;
  'xz' )
    PKGRETURN=$(basename $1 .tar.xz)
    ;;
  *)
    PKGRETURN=$(basename $1)
    ;;
  esac
  echo $PKGRETURN
}

no_usr_share_doc() {
  # If there are docs, move them:
  if [ -d usr/share/doc ]; then
    mkdir -pm755 usr/doc
    mv -vf usr/share/doc/* usr/doc
    rmdir usr/share/doc
  fi
}

# Function to retrieve the package name.
# glibc-solibs-2.2-i386-1.t?z = glibc-solibs
function short_package_name () {
  local PACKAGENAME="$( echo $1 | rev | cut -d- -f4- | rev )"
  echo ${PACKAGENAME}
}

# Better have some binaries installed first, as this may not be
# in the "magic order".  I built mine by hand through trial-and-error
# before getting this script to work.  It wasn't that hard...  I think.  ;-)
( cd $CWD/src
  for x_source_dir in proto data util xcb lib app doc xserver driver font ; do
    # See if $1 is a source directory like "lib":
    if [ ! -z "$1" ]; then
      if [ ! "$1" = "${x_source_dir}" ]; then
        continue
      fi
    fi
    PKG=${SLACK_X_BUILD_DIR}/package-${x_source_dir}
    rm -rf $PKG
    mkdir -p $PKG
    ( cd $x_source_dir
      for x_pkg in *.tar.?z* ; do
        # Reset $PKGARCH to its initial value:
        PKGARCH=$ARCH
        PKGNAME=$(echo $x_pkg | rev | cut -f 2- -d - | rev)
        # Perhaps $PKGARCH should be something different:
        if grep -wq "^$PKGNAME" ${CWD}/noarch ; then
          PKGARCH=noarch
        fi
        if grep -wq "^$PKGNAME" ${CWD}/package-blacklist ; then
          continue
        fi
        cd $SLACK_X_BUILD_DIR
        # If $2 is set, we only want to build one package:
        if [ ! -z "$2" ]; then
          if [ "$2" = "$PKGNAME" ]; then
            # Set $PKG to a private dir for the modular package build:
            PKG=$SLACK_X_BUILD_DIR/package-$PKGNAME
            rm -rf $PKG
            mkdir -p $PKG
          else
            continue
          fi
        else
          echo
          echo "Building from source ${x_pkg}"
          echo
        fi
        if grep -wq "^$PKGNAME" ${CWD}/modularize ; then
          # Set $PKG to a private dir for the modular package build:
          PKG=$SLACK_X_BUILD_DIR/package-$PKGNAME
          rm -rf $PKG
          mkdir -p $PKG
        fi

        # Clean out any previous build failure stamp for this package:
        rm -f $PORTCWD/build-logs/$SLKPORTARCH/fails/${PKGNAME}

        # Now, if there's a local Slackware ARM version (which may be an alternate
        # version if the one in Slackware won't build), let's find it:
        # (this is very rare - which is why the logic of this bit of
        # code is awful; a real hack).
        if [ -f $PORTCWD/src/${x_source_dir}/${PKGNAME}-*.t*z ]; then
           echo "******************************************************"
           echo "*** Found local copy $PORTCWD/src/${x_source_dir}/${PKGNAME}*.t?z ****"
           echo "******************************************************"
           x_pkg=$( basename $PORTCWD/src/${x_source_dir}/${PKGNAME}-*.t*z )
           LOCATIONCWD=$PORTCWD
         else
           LOCATIONCWD=$CWD
        fi

        # Let's figure out the version number on the modular package:
        MODULAR_PACKAGE_VERSION=$(echo $x_pkg | rev | cut -f 3- -d . | cut -f 1 -d - | rev)
        rm -rf $(pkgbase $x_pkg)
#        tar xvvf $CWD/src/${x_source_dir}/${x_pkg} || exit 1
        tar xvvf $LOCATIONCWD/src/${x_source_dir}/${x_pkg} || exit 1
        cd $(pkgbase $x_pkg) || exit 1
        slackhousekeeping

        # Refresh libtool to support latest architectures:
        slackupdatelibtool

        echo "*** Modular package version: $MODULAR_PACKAGE_VERSION ***"

        # If any patches are needed, call this script to apply them:
        if [ -r $CWD/patch/${PKGNAME}.patch ]; then
          . $CWD/patch/${PKGNAME}.patch
        fi
        # And then any local Slackware ARM patches:
        if [ -r $PORTCWD/patch/${PKGNAME}.patch ]; then
          . $PORTCWD/patch/${PKGNAME}.patch
        fi

        # Set the compile options for the $ARCH being used:
        PKGARCH=$ARCH # ARCH is set from arm/build
        . $PORTCWD/arch.use.flags

        # ./configure, using custom configure script if needed:
        # autoreconf
        # Check if we have a $PKG specific Slackware ARM configure script first:
        if [ -r $PORTCWD/configure/${PKGNAME} ]; then
           echo "*************************************************************************"
           echo "*** Using local package specific configure: $PORTCWD/configure/${PKGNAME}"
           echo "*************************************************************************"
           . $PORTCWD/configure/${PKGNAME}
           # No, perhaps a Slackware x86 one?
           elif [ -r $CWD/configure/${PKGNAME} ]; then
                echo "*****************************************************************************"
                echo "*** Using master source package specific configure: $CWD/configure/${PKGNAME}"
                echo "*****************************************************************************"
                # . $CWD/configure/${PKGNAME}
                # We need to add "gnueabihf" otherwise building doesn't
                # work for the EABI ARM port:
                sed -e 's?$ARCH-slackware-linux?${SLK_ARCH_HOST}?g' $CWD/configure/${PKGNAME} > armconfigure
                # No autoconf "configure" script shipped by the vendor? try and make one.
                [ ! -x ./configure ] && autoreconf -vif
               . armconfigure
            else
                echo "*******************************************************************"
                echo "*** Using master source default configure: $CWD/configure/${PKGNAME}"
                echo "*******************************************************************"
                # This is the default configure script:
                # . $CWD/configure/configure
                sed -e 's?$ARCH-slackware-linux?${SLK_ARCH_HOST}?g' $CWD/configure/configure > armconfigure
                # No autoconf "configure" script shipped by the vendor? try and make one.
                [ ! -x ./configure ] && autoreconf -vif
                . armconfigure
        fi

        # Run any pre-configure scripts - for example, to patch -Werror to -Wall.
        # We can't put sed commands within the "patch" script because if autoconf needs to run,
        # it'll create a new Makefile.
        if [ -r $PORTCWD/pre-configure/${PKGNAME}.pre-configure ]; then
           echo "*** Sourcing local pre-configure script"
           . $PORTCWD/pre-configure/${PKGNAME}.pre-configure
        fi

        # Run make, using custom make script if needed:
        # Check if we have a $PKG specific Slackware ARM make file first:
        if [ -r $PORTCWD/make/${PKGNAME} ]; then
           . $PORTCWD/make/${PKGNAME}
           # No, perhaps a Slackware x86 one?
         elif [ -r $CWD/make/${PKGNAME} ]; then
              . $CWD/make/${PKGNAME}
          else
            # This is the default make && make install routine:
            # I had make -j1 here for xorg 7.2 but I don't know why - whether
            # anything more broke on ARM... let's see!
            if ! make $NUMJOBS ; then
               echo "******* $PKGNAME FAILED MAKE *******"
               touch $PORTCWD/build-logs/$SLKPORTARCH/fails/${PKGNAME}
               continue
            fi
        fi

        # Install into package:
        make install DESTDIR=$PKG
        if [ ! -z "$MODULAR_PACKAGE_VERSION" ]; then
          mkdir -p $PKG/usr/doc/${PKGNAME}-${MODULAR_PACKAGE_VERSION}
         else
           # Use the main X11 version number:
          mkdir -p $PKG/usr/doc/${PKGNAME}-${VERSION}
         fi
        cp -favv \
          AUTHORS* COPYING* INSTALL* README* NEWS* TODO* \
          $PKG/usr/doc/${PKGNAME}-*/

        # Trim down a "ChangeLog" file:
        if [ ! -z "$MODULAR_PACKAGE_VERSION" ]; then
           changelogliposuction ChangeLog $PKGNAME $MODULAR_PACKAGE_VERSION
         else
           changelogliposuction ChangeLog $PKGNAME $VERSION
        fi

        # Get rid of zero-length junk files:
        ( cd $PKG/usr/doc
          find . -type f -size 0 -exec rm --verbose "{}" \;
          rmdir --verbose * )

        # Strip binaries:
        ( cd $PKG
          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 --strip-unneeded 2> /dev/null
          find . | xargs file | grep "current ar archive" | grep ELF | cut -f 1 -d : | xargs strip -g 2> /dev/null
        )

        # If there's any special post-install things to do, do them:
        if [ -r $CWD/post-install/${PKGNAME}.post-install ]; then
          RUNSCRIPT=$(mktemp -p $TMP) || exit 1
          cat $CWD/post-install/${PKGNAME}.post-install | sed -e "s#usr/lib#usr/lib${LIBDIRSUFFIX}#g" > $RUNSCRIPT
          . $RUNSCRIPT
          rm -f $RUNSCRIPT
        fi
        # If there are Slackware ARM specific post-install things, do them:
        if [ -r $PORTCWD/post-install/${PKGNAME}.post-install ]; then
          . $PORTCWD/post-install/${PKGNAME}.post-install
        fi

        # If this package requires some doinst.sh material, add it here:
        if [ -r $CWD/doinst.sh/${PKGNAME} ]; then
          mkdir -p $PKG/install
          sed -e "s?usr/lib?usr/lib${LIBDIRSUFFIX}?g" $CWD/doinst.sh/${PKGNAME} >> $PKG/install/doinst.sh
        fi

        # If this is a modular package, build it here:
        if [ -d $SLACK_X_BUILD_DIR/package-$PKGNAME ]; then
           cd $PKG
           slackgzpages -i # compress man & info pages and delete usr/info/dir
           slack_delete_lafiles # delete usr/lib{,64}/*.la
           slackslack      # chown -R root:root, chmod -R og-w, slackchown, slack644docs
           no_usr_share_doc
           mkdir -p $PKG/install
           if [ -r $CWD/slack-desc/${PKGNAME} ]; then
              cat $CWD/slack-desc/${PKGNAME} > $PKG/install/slack-desc
            else
              touch $PKG/install/slack-desc-missing
           fi

           # Figure out the build number for this package:
           # Let's check if it's a local ARM package:
           if [ -s $PORTCWD/build-nums/localpkgs/${PKGNAME} ]; then
              source $PORTCWD/build-nums/localpkgs/${PKGNAME}
           elif [ -s $PORTCWD/build-nums/upstreampkgs/${PKGNAME} ]; then
              source $PORTCWD/build-nums/upstreampkgs/${PKGNAME}
           else
              # We could write out a setting, but we don't know if it's an
              # upstream or local package, so we'll use the version set in the
              # "arm/build" script and let the Sud version helper fix it up
              # next time.  This situation shouldn't happen so there's no need to
              # be clever here.
              echo "WARNING: Didn't find any stored package build settings - build=$BUILD"
              MODBUILD=$BUILD # inherited from arm/build script
           fi

          # Figure out how to 'makepkg' the package:
          if [ -r $CWD/makepkg/${PKGNAME} ]; then
             echo "**** Executing custom makepkg $CWD/makepkg/$PKGNAME ****"
             BUILD=$MODBUILD . $CWD/makepkg/${PKGNAME}
             # Install & upgrade the new packages just built (the makepkg script may also do this,
             # but we always did this on ARM.  If it's re-re-installed, that's ok).
             upgradepkg --reinstall --install-new ${SLACK_X_BUILD_DIR}/*.t?z
            # Delete the previous versions from the Slackware ARM tree:
            ( cd ${SLACK_X_BUILD_DIR}
              for i in *-[0-9]*.t?z ; do
                # Wipe old packages from the Slackware tree - this caters for packages who share
                # the same first name - eg xcb-util, xcb-util-foo
                ( PKGNAM=$( short_package_name $i ) /usr/share/slackdev/slackwipepkg )
              done )
            # Move the new packages into the Slackware ARM tree:
            ( cd ${SLACK_X_BUILD_DIR}
              mv -fv *.t?z $PKGSTORE/x/ )
          else
           echo "*** Did not find a modular package-specific makepkg; using defaults.. ***"
            makepkg -l y -c n ${SLACK_X_BUILD_DIR}/${PKGNAME}-${MODULAR_PACKAGE_VERSION}-${PKGARCH}-${MODBUILD}.txz
            # Install & upgrade the new packages just built:
            upgradepkg --reinstall --install-new ${SLACK_X_BUILD_DIR}/*.t?z
            # Delete the previous versions from the Slackware ARM tree:
            ( cd ${SLACK_X_BUILD_DIR}
              for i in *-[0-9]*.t?z ; do
                # Wipe old packages from the Slackware tree - this caters for packages who share
                # the same first name - eg xcb-util, xcb-util-foo
                ( PKGNAM=$( short_package_name $i ) /usr/share/slackdev/slackwipepkg )
              done )
            # Move the new packages into the Slackware ARM tree:
            ( cd ${SLACK_X_BUILD_DIR}
              mv -fv *.t?z $PKGSTORE/x/ )
          fi # "fi" from "if [ -r $CWD/makepkg/${PKGNAME} ]..."

        fi # "fi" from "if [ -d $SLACK_X_BUILD_DIR/package-$PKGNAME ]; then"

        # Reset $PKG to assume we're building the whole source dir:
        PKG=${SLACK_X_BUILD_DIR}/package-${x_source_dir}

      done

      # If we have anything here in /etc or /usr, then the build was not fully
      # modular and we should package up whatever's there as an x11-<sourcedir>
      # package:
      if [ -d ${SLACK_X_BUILD_DIR}/package-${x_source_dir}/etc -o -d ${SLACK_X_BUILD_DIR}/package-${x_source_dir}/usr ]; then

         # Build an "x11-<sourcedir>" package for anything that wasn't built modular:
         # It's safer to consider these to have binaries in them. ;-)
         PKGARCH=$ARCH
         cd $PKG
         slackgzpages -i # compress man & info pages and delete usr/info/dir
         slack_delete_lafiles # delete usr/lib{,64}/*.la
         slackslack      # chown -R root:root, chmod -R og-w, slackchown, slack644docs
         no_usr_share_doc

         # If there are post-install things to do for the combined package,
         # we do them here.  This could be used for things like making a
         # VERSION number for a combined package.  :-)
         if [ -r $CWD/post-install/x11-${x_source_dir}.post-install ]; then
            RUNSCRIPT=$(mktemp -p $TMP) || exit 1
            cat $CWD/post-install/x11-${x_source_dir}.post-install | sed -e "s#usr/lib#usr/lib${LIBDIRSUFFIX}#g" > $RUNSCRIPT
            . $RUNSCRIPT
            rm -f $RUNSCRIPT
         fi

         mkdir -p $PKG/install
         if [ -r $CWD/slack-desc/x11-${x_source_dir} ]; then
            cat $CWD/slack-desc/x11-${x_source_dir} > $PKG/install/slack-desc
          else
            touch $PKG/install/slack-desc-missing
         fi

         if [ -r $CWD/doinst.sh/x11-${x_source_dir} ]; then
          sed -e "s?usr/lib?usr/lib${LIBDIRSUFFIX}?g" $CWD/doinst.sh/x11-${x_source_dir} >> $PKG/install/doinst.sh
         fi

         # We only care about the build numbers in the local Slackware ARM tree
         # since the port is maintained independently:
         #if [ -r $CWD/build/x11-${PKGNAME} ]; then
         #  SRCDIRBUILD=$(cat $CWD/build/x11-${PKGNAME})

         # Note: we don't check for local package version details here because
         # the Slackware ARM port doesn't maintain any of these packages - they're
         # all modules that are handled by the build code above.
         if [ -r $PORTCWD/build-nums/upstreampkgs/x11-${PKGNAME} ]; then
            source $PORTCWD/build-nums/upstreampkgs/x11-${PKGNAME}
            SRCDIRBUILD=$MODBUILD # this isn't really the 'modular' build number but we'll use the same variable name.
           # SRCDIRBUILD=$(cat $CWD/build-nums/$SLKPORTARCH/x11-${PKGNAME})
          else
            SRCDIRBUILD=$BUILD # use the number from the arm/build script
         fi

         if [ -r $CWD/makepkg/${PKGNAME} ]; then
            echo "**** Executing custom makepkg $CWD/makepkg/${PKGNAME} ****"
            # In the old days we kept using tgz for a while.  This is a reminder of
            # how to edit those makepkg scripts:
            #sed -e 's?.txz?.tgz?g' $CWD/makepkg/${PKGNAME} > ${SLACK_X_BUILD_DIR}/${PKGNAME}.makepkg
            #BUILD=$MODBUILD . ${SLACK_X_BUILD_DIR}/${PKGNAME}.makepkg
            # But for Slackware 15.0 we'll use the upstream scripts which drop their pkgs in to $SLACK_X_BUILD_DIR
            BUILD=$MODBUILD . $CWD/makepkg/${PKGNAME}
            # Install & upgrade the new packages just built:
            upgradepkg --reinstall --install-new ${SLACK_X_BUILD_DIR}/*.t?z
            # Delete the previous versions from the Slackware ARM distributable tree:
            ( cd ${SLACK_X_BUILD_DIR}
              for i in *-[0-9]*.t?z ; do
                # Wipe old packages from the Slackware tree - this caters for packages who share
                # the same first name - eg xcb-util, xcb-util-foo
                ( PKGNAM=$( short_package_name $i ) /usr/share/slackdev/slackwipepkg )
              done )
            # Move the new packages into the Slackware ARM distributable tree:
            ( cd ${SLACK_X_BUILD_DIR}
              mv -fv *.t?z $PKGSTORE/x/ )
         else
            makepkg -l y -c n ${SLACK_X_BUILD_DIR}/x11-${x_source_dir}-${VERSION}-${PKGARCH}-${SRCDIRBUILD}.txz
            # Install & upgrade the new packages just built:
            upgradepkg --reinstall --install-new ${SLACK_X_BUILD_DIR}/*.t?z
            # Delete the previous versions from the Slackware ARM distributable tree:
            ( cd ${SLACK_X_BUILD_DIR}
              for i in *-[0-9]*.t?z ; do
                # Wipe old packages from the Slackware tree - this caters for packages who share
                # the same first name - eg xcb-util, xcb-util-foo
                ( PKGNAM=$( short_package_name $i ) /usr/share/slackdev/slackwipepkg )
              done )
            # Move the new packages into the Slackware ARM tree:
            ( cd ${SLACK_X_BUILD_DIR}
              mv -fv *.t?z $PKGSTORE/x/ )
         fi

      fi # "fi" from "if [ -d ${SLACK_X_BUILD_DIR}/package-${x_source_dir}/etc -o -d ${SLACK_X_BUILD_DIR}/package-${x_source_dir}/usr ]; then"

   )
done )

#echo
#echo "***************************************************************"
#echo "** REMEMBER: The finished packages are in the temporary build *"
#echo "**           space:                                           *"
#echo "** $SLACK_X_BUILD_DIR "
#echo
