Added the extra substitutions in the pkginfo file to pack_info also made sure all the necessary variables are defined with a legal value.
444 lines
13 KiB
Plaintext
444 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 $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
|
|
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]=$srcdir/${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
|
|
$RM -rf $srcdir/$topsrcdir
|
|
else
|
|
echo "No unpacked source to scrub"
|
|
fi
|
|
;;
|
|
'stage') if [ -d $stagedir -a "$stagedir" != "/" ]; then
|
|
$RM -rf $stagedir # This is very dangerous!
|
|
$MKDIR $stagedir
|
|
else
|
|
error $E_BAD_DIR clean
|
|
fi
|
|
;;
|
|
'meta') $RM -f $metadir/prototype*
|
|
$RM -f $metadir/pkginfo
|
|
$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
|
|
}
|