#!/bin/bash # Version: 1.3 GSB Section SlackBuild. # Copyright (c) 2007 Darren 'Tadgy' Austin # # Licenced under the terms of the GNU General Public Licence version 3. # # The list of packages in this section, in the order they should be built. PACKAGES=" xxx xxx xxx " # Section name. # This should not need to be changed unless the auto detection fails. SECTION="$( echo ${BASH_SOURCE#*/} | cut -d. -f2 )" # Usage. function usage() { cat << EOF Usage: ${0##*/} [options] Options: --help Show this help screen. --list List the packages which will be built in this section. --force A package will not be built if a package of the same name is already installed, or any of the pre-requisite packages are not installed. This option over-rides the checks and attempts a build (which will probably fail) anyway. --no-skip During the build process, packages that are up to date (ie, the package version and build numbers match the coresponding SlackBuild) will not be rebuilt. This option forces packages to be rebuilt regardless of the version and build numbers. This does not affect the pre-build checks for installed packages (see --force). --no-metafiles Do not create the .txt and .md5 files for each package which would usually be produced during a build. --no-prune Normally, when a package is built and copied to the destination directory, any previous package(s) of the same name are deleted - it is assumed the new package is to replace any which were built previously. This option prevents previous packages being deleted from the destination directory, possibly leaving more than one package of the same name (but with different version or build numbers) laying around. --no-cleanup By default, any source, temporary build and package directories will be deleted once the package is built. This option prevents those files from being removed. --no-install Build packages but don't install them. This should only be used for testing individual SlackBuilds as it WILL cause serious problems - some package builds may rely on another package being auto installed first. Options are passed down to the next level SlackBuild where appropriate. EOF } function list_packages() { local PACKAGE echo "The following packages are built in this section, listed in processing order:" ( for PACKAGE in $PACKAGES do echo -n "$PACKAGE, " done ) | sed -e 's/, $//' | fmt -w 74 | sed -e 's/^/ /g' } function find_package_files() { # $1 = Directory to look for files in [required] # $2 = Package name or regex to match. An empty string matches all. # $3 = Package version or regex to match. An empty string matches all. # $4 = Package architecture or regex to match. An empty string matches all. # $5 = Package build tag or regex to match. An empty string matches all. # $6 = File extension or regex to match. An empty string means no extension. # Note: Remember to escape any regex characters used in fixed strings. [ -z "$1" ] || [ ! -d "$1" ] && return 1 find $1 -maxdepth 1 -mindepth 1 2>/dev/null | \ egrep "^.*/(${2:-.*})(-${3:-[^-]*})(-${4:-[^-]*})(-${5:-[^-.]*})($6)$" 2>/dev/null return $? } function runtime() { # $1 = Number of seconds to convert to readable text [required] [ -z "$1" ] && return 1 local D=$(( $1 / 86400 )) local H=$(( ($1 - ($D * 86400)) / 3600 )) local M=$(( ($1 - ($D * 86400) - ($H * 3600)) / 60 )) local S=$(( $1 - ($D * 86400) - ($H * 3600) - ($M * 60) )) if [ $D -gt 0 ]; then echo -n "${D}d, ${H}h ${M}m ${S}s" else echo -n "${H}h, ${M}m ${S}s" fi return 0 } function gen_pkg_txt() { # $1 = Package file to process [required]. [ -z "$1" ] || [ ! -e "$1" ] && return 1 tar xzOf $1 install/slack-desc 2>/dev/null | \ grep -v "^#" | egrep "[[:alnum:]\+]+\:" >${1%.tgz}.txt return $? } function gen_pkg_md5() { # $1 = Package file to process [required]. [ -z "$1" ] || [ ! -e "$1" ] && return 1 ( cd $( dirname $1 ) && md5sum $( basename $1 ) >$1.md5 ) return $? } # Make sure we are in the right directory (you can never trust users..) cd $( cd ${BASH_SOURCE%/*} ; pwd ) # If the user created an options file, read it. [ "$OPTIONSREAD" != "1" -a -r ../gsb.options ] && { . ../gsb.options export OPTIONSREAD=1 } # Environment. export TMP=${TMP:-/tmp} export PKGDEST=${PKGDEST:-$TMP/gsb-tree/packages} export LOGSDIR=${LOGSDIR:-$TMP/gsb-buildlogs} # Option defaults. NOSKIP=0 NOMETAFILES=0 NOPRUNE=0 NOINSTALL=0 # Sanity check (in case Steve forgets to add packages again :P). [ $( echo "$PACKAGES" | wc -w ) != \ $( find . -type d ! -name .svn -maxdepth 1 -mindepth 1 | wc -w ) ] && { echo echo "*********************************************************************" echo "** Error: the number of packages in the PACKAGES list is different" echo "** to the number of package directories in this section." echo "** Some packages may not have been added to the PACKAGES list." echo "*********************************************************************" exit 1 } # Parse command line arguments. while [ $# -gt 0 ]; do if [ "$1" = "-help" ] || [ "$1" = "--help" ]; then usage exit 0 elif [ "$1" = "-list" ] || [ "$1" = "--list" ]; then list_packages exit 0 elif [ "$1" = "-force" ] || [ "$1" = "--force" ]; then SLACKBUILD_ARGS="${SLACKBUILD_ARGS:+"$SLACKBUILD_ARGS "}--force" shift elif [ "$1" = "-no-cleanup" ] || [ "$1" = "--no-cleanup" ]; then SLACKBUILD_ARGS="${SLACKBUILD_ARGS:+"$SLACKBUILD_ARGS "}--no-cleanup" shift elif [ "$1" = "-no-skip" ] || [ "$1" = "--no-skip" ]; then NOSKIP=1 shift elif [ "$1" = "-no-metafiles" ] || [ "$1" = "--no-metafiles" ]; then NOMETAFILES=1 shift elif [ "$1" = "-no-prune" ] || [ "$1" = "--no-prune" ]; then NOPRUNE=1 shift elif [ "$1" = "-no-install" ] || [ "$1" = "--no-install" ]; then NOINSTALL=1 shift else echo "${0##*/}: Unknown option: $1" echo "Try: $0 --help" exit 1 fi done # Temporary space, package and log file storage. mkdir -p $TMP mkdir -p $PKGDEST mkdir -p $LOGSDIR mkdir -p $PKGDEST/$SECTION mkdir -p $LOGSDIR/$SECTION echo echo "*********************************************************************" echo "** Building section '$SECTION'..." echo "*********************************************************************" # Process packages. ( for PACKAGE in $PACKAGES do echo echo "*********************************************************************" echo "*** Processing package '$PACKAGE'..." echo "*********************************************************************" # Sanity checks. [ ! -e "$PACKAGE/$PACKAGE.SlackBuild" ] && { echo echo "*********************************************************************" echo "*** Error: '$PACKAGE.SlackBuild' not found." echo "*********************************************************************" exit 1 } [ ! -x "$PACKAGE/$PACKAGE.SlackBuild" ] && { echo echo "*********************************************************************" echo "*** Error: '$PACKAGE.SlackBuild' is not executable." echo "*********************************************************************" exit 1 } # Get package version and build numbers from the package SlackBuild. declare PACKAGE_$( egrep -m 1 "^VERSION=.*" $PACKAGE/$PACKAGE.SlackBuild ) declare PACKAGE_$( egrep -m 1 "^BUILD=.*" $PACKAGE/$PACKAGE.SlackBuild ) # Check that we got a version and build. [ -z "${PACKAGE_VERSION//-/_}" ] || [ -z "$PACKAGE_BUILD" ] && { echo echo "*********************************************************************" echo "*** Error: failed to get VERSION or BUILD from '$PACKAGE.SlackBuild'" echo "*********************************************************************" exit 1 } # Check if the package has been built previously. SKIP_BUILD=0 find_package_files "$PKGDEST/$SECTION" "${PACKAGE//+/\+}" \ "${PACKAGE_VERSION//-/_}" "" "$PACKAGE_BUILD" "\.tgz" >/dev/null && { if [ "$NOSKIP" = "0" ]; then # The package is up to date, no need to rebuild it. SKIP_BUILD=1 else echo echo "*********************************************************************" echo "*** Removing '$PACKAGE' package files from tree..." echo "*********************************************************************" rm -f $( find_package_files "$PKGDEST/$SECTION" "${PACKAGE//+/\+}" \ "${PACKAGE_VERSION//-/_}" "" "$PACKAGE_BUILD" "\.tgz|\.txt|\.tgz\.md5" | \ tr '\n' ' ' ) fi } # Remove the package if it's installed. # Note: this is done even with an "update" build so that the system is # refreshed from the package in the tree. find_package_files "/var/log/packages" "${PACKAGE//+/\+}" "" "" "" "" \ >/dev/null && { echo echo "*********************************************************************" echo "*** Removing installed package '$PACKAGE'..." echo "*********************************************************************" removepkg $( basename $PACKAGE ) } # Build package if required. if [ "$SKIP_BUILD" = "0" ]; then echo echo "*********************************************************************" echo "*** Building package '$PACKAGE'..." echo "*********************************************************************" ( cd $PACKAGE && export PKGDEST=$PKGDEST/$SECTION && ./$PACKAGE.SlackBuild $SLACKBUILD_ARGS 2>&1 ) | \ tee $LOGSDIR/$SECTION/$PACKAGE-$( date +%Y%m%d-%H%M%S ).log ERR=${PIPESTATUS[0]} [ "$ERR" != "0" ] && { echo echo "*********************************************************************" echo "*** Error: '$PACKAGE' build failed." echo "*********************************************************************" exit $ERR } else echo echo "*********************************************************************" echo "*** Skipping build of '$PACKAGE' - package up to date." echo "*********************************************************************" fi PRUNE_FILES="$( find_package_files "$PKGDEST/$SECTION" "${PACKAGE//+/\+}" \ "" "" "" "\.tgz|\.txt|\.tgz\.md5" | grep -v "$( find_package_files \ "$PKGDEST/$SECTION" "${PACKAGE//+/\+}" "${PACKAGE_VERSION//-/_}" "" \ "$PACKAGE_BUILD" "\.tgz" )" | tr '\n' ' ' )" [ ! -z "$PRUNE_FILES" ] && { if [ "$NOPRUNE" = "0" ]; then echo echo "*********************************************************************" echo "*** Pruning old '$PACKAGE' package files from tree..." echo "*********************************************************************" rm -f $PRUNE_FILES else echo echo "*********************************************************************" echo "*** Warning: not pruning any old '$PACKAGE' files." echo "*********************************************************************" fi } if [ "$NOMETAFILES" = "0" ]; then echo echo "*********************************************************************" echo "*** Creating metafiles for '$PACKAGE'..." echo "*********************************************************************" gen_pkg_txt "$( find_package_files "$PKGDEST/$SECTION" "${PACKAGE//+/\+}" \ "${PACKAGE_VERSION//-/_}" "" "$PACKAGE_BUILD" "\.tgz" )" && gen_pkg_md5 "$( find_package_files "$PKGDEST/$SECTION" "${PACKAGE//+/\+}" \ "${PACKAGE_VERSION//-/_}" "" "$PACKAGE_BUILD" "\.tgz" )" || { echo echo "*********************************************************************" echo "*** Error: failed to create metafiles for '$PACKAGE'." echo "*********************************************************************" exit 1 } else echo echo "*********************************************************************" echo "*** Warning: not creating metafiles for '$PACKAGE'." echo "*********************************************************************" fi if [ "$NOINSTALL" = "0" ]; then echo echo "*********************************************************************" echo "*** Installing '$PACKAGE'..." echo "*********************************************************************" upgradepkg --install-new $( find_package_files $PKGDEST/$SECTION \ "${PACKAGE//+/\+}" "${PACKAGE_VERSION//-/_}" "" "$PACKAGE_BUILD" "\.tgz" ) || { echo echo "*********************************************************************" echo "*** Error: failed to install '$PACKAGE'." echo "*********************************************************************" exit 1 } else echo echo "*********************************************************************" echo "*** Warning: not installing '$PACKAGE'." echo "*********************************************************************" fi done echo echo "*********************************************************************" echo "** Finished building section '$SECTION'." echo "*********************************************************************" echo "** This sections packages can be found in '$PKGDEST/$SECTION'." echo "** Individual build logs can be found in '$LOGSDIR/$SECTION'." echo "** Package files and build logs can be deleted if not required." echo "*********************************************************************" echo "** Section build time was $( runtime $SECONDS )." echo "*********************************************************************" ) 2>&1 | tee $LOGSDIR/$SECTION-$(date +%Y%m%d-%H%M%S).log # Return the exit status from the sub-shell, not the tee command. exit ${PIPESTATUS[0]}