Vim provides updates to major release through source patches, we don't want those in src/ since we didn't create them. With patchdir we can easily control where patches should be located. Made clean() tell what it does.
449 lines
13 KiB
Plaintext
449 lines
13 KiB
Plaintext
#
|
|
# Global function library for buildpkg
|
|
#
|
|
# This file is designed to be sourced by pr. package buildscripts
|
|
#
|
|
|
|
# Variables that *must* be overridden pr. package
|
|
# They are used to construct paths and more so they
|
|
# must have sane values
|
|
# topdir= The toplevel dir name under $buildpkgbase
|
|
# It is also used pr. default in the pkgname
|
|
# and it is also used pr. default as the toplevel name inside the sourcetar ($topsrcdir)
|
|
# version= source version ie. 0.14.2b
|
|
# pkgver= the package revision, an increasing number is recommended but a date could be used instead
|
|
# source[0..x] = source filenames - source[0] *must* be defined and contain a legal filename
|
|
# pr. default we will look for source[0] relative to $srcfiles
|
|
# A filename that begin with / will be treated as absolute paths
|
|
# Note! only source[0] will be automatically unpacked
|
|
# patch[0..x] = patch filenames - if patch[0] is undefined then generic_prep won't attempt to patch the source
|
|
# pr. default we expect these to be listed relative to $patchdir (default $srcdir)
|
|
# filenames that begin with / will be treated as absolute paths
|
|
# All patching will be done from *within* $srcdir/$topsrcdir directory with patch -p1
|
|
# patches must be in uncompressed format
|
|
|
|
# Define tool programs
|
|
PKGMK=/usr/bin/pkgmk
|
|
PKGTRANS=/usr/bin/pkgtrans
|
|
PKGPROTO=/usr/bin/pkgproto
|
|
STRIP=/usr/ccs/bin/strip
|
|
UNAME=/usr/bin/uname
|
|
TAR=/usr/local/bin/tar # GNU tar please!
|
|
BZIP2=/usr/bin/bzip2
|
|
GZIP=/usr/bin/gzip
|
|
PATCH=/usr/local/bin/patch # GNU patch 2.5 or better please!
|
|
RM=/usr/bin/rm
|
|
MKDIR=/usr/bin/mkdir
|
|
MAKE_PROG=/usr/local/bin/make # GNU make please!
|
|
FIND=/usr/bin/find # Solaris find - GNU find will require changes to the script
|
|
XARGS=/usr/bin/xargs
|
|
CAT=/usr/bin/cat
|
|
AWK=/usr/bin/nawk # This must be nawk or GNU awk - /usr/bin/awk will *not* work
|
|
SED=/usr/bin/sed
|
|
|
|
# Define defaults
|
|
buildpkgbase=${HOME}/buildpkg
|
|
stagedir=$buildpkgbase/$topdir/stage
|
|
srcdir=$buildpkgbase/$topdir/src
|
|
patchdir=$srcdir # Allow the possibility of easily putting a load of patches in a different location
|
|
metadir=$buildpkgbase/$topdir/meta
|
|
distdir=$buildpkgbase/distfiles
|
|
topsrcdir=$topdir-$version # it may be necessary to override this
|
|
|
|
srcfiles=$buildpkgbase/srcfiles
|
|
|
|
topinstalldir=/usr/local
|
|
prefix=$topinstalldir
|
|
|
|
# pkginfo information.
|
|
# The following 5 vars will be used when constructing the pkginfo file
|
|
# Override as necessary.
|
|
pkgname=SB$topdir # overriding this will be common
|
|
name=$topdir # as will this ditto
|
|
pkgcat="application" # A reasonable default
|
|
pkgvendor="http://change/me/please"
|
|
pkgdesc="mumble mubmle... hmm someone forgot to fill this out!"
|
|
|
|
cpu=sparcv9
|
|
os=sol`$UNAME -r`
|
|
pkgdirdesig=${topinstalldir##/*/} # topinstalldir suffix
|
|
|
|
# Distfiles should be named like this
|
|
# <name>-<version>-<pkgver>.sb-<os>-<cpu>-<pkgdirdesig>
|
|
# ie: libmad-0.14.2b-1.sb-sol5.8-sparcv9-local
|
|
distfile=$topdir-$version-$pkgver.sb-$os-$cpu-$pkgdirdesig
|
|
|
|
# Define error codes and texts
|
|
E_MISSING_STAGEDIR=30
|
|
E_MISSING_ARGS=31
|
|
E_BAD_FILE=32
|
|
E_PATCH_FAILED=33
|
|
E_BAD_DIR=34
|
|
E_BAD_UNPACK=35
|
|
E_BAD_COMPRESS=36
|
|
E_BAD_CONFIG=37
|
|
E_BAD_MAKE=38
|
|
E_BAD_CLEANOPTIONS=39
|
|
E_BAD_STRIP=40
|
|
E_BAD_ARGS=41
|
|
|
|
error_txt[$E_BAD_FILE]="File not found"
|
|
error_txt[$E_PATCH_FAILED]="Patch failed"
|
|
error_txt[$E_BAD_DIR]="Directory not found"
|
|
error_txt[$E_BAD_UNPACK]="Unable to decompress sourcearchive"
|
|
error_txt[$E_BAD_COMPRESS]="Unknown compression method"
|
|
#error_txt[$E_BAD_CONFIG]="configure failed"
|
|
#error_txt[$E_BAD_MAKE]="make failed"
|
|
error_txt[$E_MISSING_ARGS]="A required argument was missing"
|
|
error_txt[$E_BAD_ARGS]="An illegal argument was passed"
|
|
|
|
#####################################################
|
|
# Helper functions
|
|
#####################################################
|
|
|
|
# error(): exit with errorcode and possibly a message
|
|
# params: $1 = errorcode $2 = name of caller
|
|
error()
|
|
{
|
|
if [ -n "${error_txt[$1]}" ]; then
|
|
echo "$2: ${error_txt[$1]}"
|
|
fi
|
|
exit $1
|
|
}
|
|
|
|
# setdir(): switch to a directory, but check destination first
|
|
# params: $1=dir to cd to [source|stage] can be used as shortcuts
|
|
# Switches to the directory in $1 but first checks if the destination exists
|
|
setdir()
|
|
{
|
|
local dir=$1
|
|
case $dir in
|
|
'source') dir="$srcdir/$topsrcdir";;
|
|
'stage') dir="$stagedir";;
|
|
esac
|
|
echo "Switching to $dir"
|
|
if [ -z "$dir" ]; then
|
|
error $E_BAD_DIR setdir
|
|
fi
|
|
if [ -d "$dir" ]; then
|
|
cd "$dir"
|
|
else
|
|
error $E_BAD_DIR setdir
|
|
fi
|
|
}
|
|
|
|
# patch(): patch unpacked source
|
|
# params: $1 = patch number (arrayindex) $2 = patch params (defaults to -p1)
|
|
# It will verify the existence of the patch file passed to it and
|
|
# exit gracefully if it cannot be found.
|
|
# An empty $2 argument will be treated as undefined and mapped to -p1
|
|
patch()
|
|
{
|
|
local pnum=$1
|
|
local arg2=$2
|
|
local pparam=${arg2:-"-p1"}
|
|
|
|
setdir source
|
|
|
|
if [ ! -z ${patch[$pnum]} ]; then # They didn't give us an empty string
|
|
if [ "${patch[$pnum]:0:1}" != "/" ]; then # We have a relative pathname
|
|
# expand to absolute
|
|
patch[$pnum]=$patchdir/${patch[$pnum]}
|
|
fi # We are now sure that $patch[$pnum] contains file with absolute path
|
|
echo "Processing patch[$pnum] - ${patch[$pnum]}"
|
|
if [ -r ${patch[$pnum]} ]; then # file is readable
|
|
$PATCH -Es $2 < ${patch[$pnum]}
|
|
if [ $? -ne 0 ]; then
|
|
error $E_PATCH_FAILED patch
|
|
fi
|
|
else
|
|
error $E_BAD_FILE patch
|
|
fi
|
|
else
|
|
echo "Patch $pnum has empty filename"
|
|
fi
|
|
}
|
|
|
|
# unpack(): Unpack source
|
|
# params: $1 = source number (arrayindex)
|
|
# It will detect filetype and unpack
|
|
# .tar, .tgz, .gz, .bz2 and .Z supported
|
|
unpack()
|
|
{
|
|
local snum=$1
|
|
|
|
setdir $srcdir
|
|
if [ "${source[$snum]:0:1}" != "/" ]; then # We have a relative pathname
|
|
# expand to absolute
|
|
source[$snum]=$srcfiles/${source[$snum]}
|
|
fi # We are now sure that ${source[$snum]} contains file with absolute path
|
|
echo "Unpacking ${source[$snum]}"
|
|
if [ -r ${source[$snum]} ]; then # file is readable
|
|
local absfilename=${source[$snum]}
|
|
local filename=${absfilename##/*/} # Strip down to the filename
|
|
local suffix=${filename##*.} # Strip down to filename suffix (strip down to the last .)
|
|
|
|
# Determine filetype and unpack
|
|
case $suffix in
|
|
'tar') $TAR -xf ${source[$snum]};;
|
|
'gz') $GZIP -dc ${source[$snum]} | $TAR -xf -;;
|
|
'bz2') $BZIP2 -dc ${source[$snum]} | $TAR -xf -;;
|
|
'Z') $GZIP -dc ${source[$snum]} | $TAR -xf -;;
|
|
'tgz') $GZIP -dc ${source[$snum]} | $TAR -xf -;;
|
|
*) error $E_BAD_COMPRESS unpack
|
|
esac
|
|
if [ $? -ne 0 ]; then
|
|
error $E_BAD_UNPACK unpack
|
|
fi
|
|
else
|
|
error $E_BAD_FILE unpack
|
|
fi
|
|
}
|
|
|
|
# clean(): Scrub build environment
|
|
# params: $1=stage|source|distclean
|
|
clean()
|
|
{
|
|
case $1 in
|
|
'source') if [ -d "$srcdir/$topsrcdir" ]; then
|
|
echo "Removing $srcdir/$topsrcdir"
|
|
$RM -rf $srcdir/$topsrcdir
|
|
else
|
|
echo "No unpacked source to scrub"
|
|
fi
|
|
;;
|
|
'stage') if [ -d $stagedir -a "$stagedir" != "/" ]; then
|
|
echo "Emptying $stagedir"
|
|
$RM -rf $stagedir # This is very dangerous!
|
|
$MKDIR $stagedir
|
|
else
|
|
error $E_BAD_DIR clean
|
|
fi
|
|
;;
|
|
'meta') echo "Removing $metadir/prototype*"
|
|
$RM -f $metadir/prototype*
|
|
echo "Removing $metadir/pkginfo"
|
|
$RM -f $metadir/pkginfo
|
|
echo "Removing $buildpkgbase/$topdir/$pkgname"
|
|
$RM -rf $buildpkgbase/$topdir/$pkgname
|
|
;;
|
|
|
|
'distclean') clean source
|
|
clean stage
|
|
clean meta
|
|
;;
|
|
*) error $E_BAD_CLEANOPTION clean
|
|
esac
|
|
}
|
|
|
|
# strip(): strip binaries in stagedir
|
|
# params: none
|
|
# Automatically switches to $stagedir
|
|
# On exit cwd is $stagedir
|
|
strip()
|
|
{
|
|
setdir stage
|
|
$FIND . -type f -perm -700 | $XARGS $STRIP
|
|
# if [ $? -ne 0 ]; then
|
|
# error $E_BAD_STRIP strip
|
|
# if
|
|
}
|
|
|
|
|
|
# make_pkg(): Create the final package
|
|
# params: none
|
|
#
|
|
make_pkg()
|
|
{
|
|
echo "Creating package and transferring it to datastream format"
|
|
$PKGMK -r `pwd` -d $buildpkgbase/$topdir -o -f $metadir/prototype
|
|
$PKGTRANS -o -s $buildpkgbase/$topdir $distdir/$distfile $pkgname
|
|
echo "Done. Package was created as $distfile"
|
|
}
|
|
|
|
# pack_info(): Create the pkginfo file
|
|
# params: none
|
|
# Will create the pkginfo file with pkginfo.in as a template
|
|
# Both the template and the result will be in $metadir
|
|
# Substitutions will be done on pkgname,version,pkgver,name & topinstalldir
|
|
# they will be replaced with the value of their variable counterparts
|
|
pack_info()
|
|
{
|
|
$SED -e "s#%%pkgname%%#$pkgname#g" \
|
|
-e "s#%%version%%#$version#g" \
|
|
-e "s#%%pkgcat%%#$pkgcat#g" \
|
|
-e "s#%%pkgvendor%%#$pkgvendor#g" \
|
|
-e "s#%%pkgver%%#$pkgver#g" \
|
|
-e "s#%%name%%#$name#g" \
|
|
-e "s#%%topinstalldir%%#$topinstalldir#g" \
|
|
-e "s#%%pkgdesc%%#$pkgdesc#g" \
|
|
$metadir/pkginfo.in > $metadir/pkginfo
|
|
}
|
|
|
|
# prototype(): Create a prototype file for pkgmk
|
|
# params: $1 = owner $2 = group $3 = [script|noscript]
|
|
# $1 & $2 will list the owner and group that is to be applied to all files
|
|
# pkginfo and depend (if it exists) will automatically be added to prototype file
|
|
# $3 will define whether or not to automatically include any post/pre scripts found
|
|
# in $topdir/meta. Pr. default postinstall,preinstall,postremove,preremove are the filenames
|
|
# it will look for.
|
|
# $3 can be omitted and in that case prototype will behave as if $3=noscript
|
|
prototype()
|
|
{
|
|
local owner=$1
|
|
local group=$2
|
|
|
|
$FIND . -print|$PKGPROTO > $metadir/prototype.in
|
|
$CAT $metadir/prototype.in | $AWK -v owner="$owner" -v group="$group" \
|
|
'{ $5=owner; $6=group; print; }' > $metadir/prototype
|
|
|
|
add_meta_file pkginfo "$metadir/pkginfo"
|
|
|
|
# If a dependency file is available then use it
|
|
[ -r $metadir/depend ] && add_meta_file depend "$metadir/depend"
|
|
|
|
case $3 in
|
|
'script') [ -r $metadir/preinstall ] && add_meta_file preinstall "$metadir/preinstall"
|
|
[ -r $metadir/postinstall ] && add_meta_file postinstall "$metadir/postinstall"
|
|
[ -r $metadir/preremove ] && add_meta_file preremove "$metadir/preremove"
|
|
[ -r $metadir/postremove ] && add_meta_file postremove "$metadir/postremove"
|
|
;;
|
|
'noscript') ;;
|
|
esac
|
|
}
|
|
|
|
# add_meta_file(): add a metafile entry to the prototype file
|
|
# params: $1 = keyword $2 = filename
|
|
# Additions will be done to the file $metadir/prototype
|
|
add_meta_file()
|
|
{
|
|
local arg1=${1-'x'}
|
|
if [ "$arg1" == "x" ]; then
|
|
error $E_MISSING_ARGS add_meta_file
|
|
fi
|
|
local arg2=${2-'x'}
|
|
if [ "$arg2" == "x" ]; then
|
|
error $E_MISSING_ARGS add_meta_file
|
|
fi
|
|
if [ -r "$arg2" ]; then
|
|
echo "i $arg1=$arg2" >> $metadir/prototype
|
|
else
|
|
error $E_BAD_FILE add_meta_file
|
|
fi
|
|
}
|
|
# add_file(): add a file entry to the prototype file
|
|
# params: $1 = owner $2 = group $3 = permissions $4 = filename
|
|
# Additions will be done to the file $metadir/prototype
|
|
# $4 must be relative to $stagedir$prefix (or just $stagedir if using shortroot)
|
|
# We will not check for the existence of $4
|
|
add_file()
|
|
{
|
|
local arg1=${1-'x'}
|
|
if [ "$arg1" == "x" ]; then
|
|
error $E_MISSING_ARGS add_metae
|
|
fi
|
|
local arg2=${2-'x'}
|
|
if [ "$arg2" == "x" ]; then
|
|
error $E_MISSING_ARGS add_meta
|
|
fi
|
|
local arg3=${3-'x'}
|
|
if [ "$arg2" == "x" ]; then
|
|
error $E_MISSING_ARGS add_meta
|
|
fi
|
|
if [ -r "$arg4" ]; then
|
|
echo "f none $arg4 $3 $1 $2" >> $metadir/prototype
|
|
else
|
|
error $E_BAD_FILE add_meta_file
|
|
fi
|
|
}
|
|
|
|
#####################################################
|
|
# Define generic functions for different build stages
|
|
#####################################################
|
|
|
|
# generic_prep(): Unpack source and apply any patches
|
|
# params: none
|
|
generic_prep()
|
|
{
|
|
clean source
|
|
unpack 0
|
|
|
|
# Verify that ${patch[$pnum]} is defined
|
|
local pver=${patch[0]-'x'}
|
|
if [ "$pver" == "x" ]; then
|
|
return # it was undefined
|
|
else
|
|
local numpatch=${#patch[@]}
|
|
local i=0
|
|
# Argh! - The C-style for loop doesn't work in bash-2.0.3 as distributed
|
|
# with Solaris 8 :( (it works just fine on Redhat Linux 7.3, bash 2.0.5a)
|
|
# for ((i=0; i < numpatch; i++))
|
|
# do
|
|
# patch $i -p1
|
|
# done
|
|
while [ $i -lt $numpatch ]
|
|
do
|
|
patch $i -p1
|
|
let i=i+1
|
|
done
|
|
fi
|
|
}
|
|
|
|
# generic_build(): Take the necessary steps to build already prepared source
|
|
# params: none
|
|
generic_build()
|
|
{
|
|
setdir source
|
|
|
|
./configure --prefix=$prefix
|
|
if [ $? -ne 0 ]; then
|
|
error $E_BAD_CONFIG generic_build
|
|
fi
|
|
$MAKE_PROG
|
|
if [ $? -ne 0 ]; then
|
|
error $E_BAD_MAKE generic_build
|
|
fi
|
|
}
|
|
|
|
# generic_install(): Install already built source
|
|
# params: $1 = destvar
|
|
# destvar is the variable that make should override to install into the staging
|
|
# area. default is DESTDIR, possible common alternatives are prefix and PREFIX
|
|
generic_install()
|
|
{
|
|
local destvar=DESTDIR
|
|
local arg1=${1-'x'}
|
|
if [ "$arg1" != "x" ]; then
|
|
destvar=$arg1 # $1 was defined
|
|
fi
|
|
clean stage
|
|
setdir source
|
|
$MAKE_PROG $destvar=$stagedir install
|
|
if [ $? -ne 0 ]; then
|
|
error $E_BAD_MAKE generic_install
|
|
fi
|
|
strip
|
|
}
|
|
|
|
# generic_pack(): Build package using files from 'install' stage
|
|
# params: $1 - indicating whether or not the root is complete as described below
|
|
# We expect generic_install to have made $stagedir the "root" dir
|
|
# in that all paths below will be complete (ie. /usr/local/bin and not
|
|
# just bin) *unless* $1=shortroot.
|
|
generic_pack()
|
|
{
|
|
clean meta
|
|
# Verify if $1 is defined
|
|
local arg1=${1-'x'}
|
|
case $arg1 in
|
|
'x') setdir "$stagedir$prefix" # arg1 was undefined
|
|
;;
|
|
'shortroot') setdir "$stagedir"
|
|
;;
|
|
'*') error $E_BAD_ARGS generic_pack
|
|
esac
|
|
pack_info
|
|
prototype root bin script
|
|
make_pkg
|
|
}
|