buildpkg/buildpkg.packaging.solaris
2009-12-19 14:38:41 +01:00

510 lines
15 KiB
Plaintext

#
# Function library for buildpkg framework
# It adds support for creating Solaris packages in 'sysv' format
#
# Define tool programs
# *only* platform specific tools should be listed here
# generic tools go in buildpkg.functions
PKGMK=/usr/bin/pkgmk
PKGTRANS=/usr/bin/pkgtrans
# Override generic location
STRIP=/usr/ccs/bin/strip
# /usr/ccs/bin/strip destroys the symbol table in static archives
# So this is disabled by default
dostrip_static=0
# Setup default args for strip. They match SGU 4.0 from Solaris 8
# Change these if you're using strip from GNU Binutils (recommended)
strip_elf_args="" # GNU default is -g
strip_shared_args="" # GNU default is --strip-unneeded
strip_static_args="" # GNU default is -g
META_CLEAN="prototype prototype.in pkginfo files.tmp"
# Define defaults
# pkginfo information.
# The following 3 vars will be used when constructing the pkginfo file
# Override as necessary.
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`
# Default pkginfo.in file
pkginfo=$buildpkgbase/scripts/pkginfo.in
# Variables that control functionality
usedepend=1 # default to looking for a depend file in $metadir
usescripts=1 # default to add pre/post scripts if available
usespace=1 # default to looking for a space file in $metadir
ignore_unpackaged_files=0 # default to check for unpackaged files in the stage area
# Solaris doesn't know how to handle any kind of compressed manpages
gzman=0
# Host specific configuration
[ -r $buildpkgbase/scripts/config.`hostname`.solaris ] && . $buildpkgbase/scripts/config.`hostname`.solaris
# Distfiles should be named like this
# <name>-<version>-<pkgver>.sb-<os>-<cpu>-<pkgdirdesig>
# ie: libmad-0.14.2b-1.sb-sol5.8-sparcv9-local
# We hardquote it so that we can control when we want it
# evaluated (using _upls)
distfile='$secname-$version-$secver.sb-$os-$cpu-$pkgdirdesig'
#####################################################
# "external" functions
#####################################################
# make_pkg(): Create the final package
# params: $1 = meta file suffix
#
make_pkg()
{
if [ $# -lt 1 ]; then
error $E_MISSING_ARGS make_pkg
fi
local secname=$1
local prototype=prototype.$secname
local secver=$(get_pkgrev $secname)
local dfile=$(_upls $distfile)
local pname=$(get_pkgname $secname)
echo "Creating package and transferring it to datastream format"
$PKGMK -r `pwd` -d $buildpkgbase/$pkgdir -o -f $metadir/$prototype
$PKGTRANS -o -s $buildpkgbase/$pkgdir $distdir/$dfile $pname
echo "Done. Package was created as $dfile"
}
# pack_info(): Create the pkginfo file
# params: $1 = metafile suffix
# 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()
{
if [ $# -lt 1 ]; then
error $E_MISSING_ARGS pack_info
fi
local secname=$1
pstamp="$os-$($UNAME -n)`date '+%Y%m%d%H%M'`"
$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" \
-e "s#%%pstamp%%#$pstamp#g" \
$pkginfo > $metadir/pkginfo.$secname
}
# list_pkgs(): Find all the section names of all defined pkgs
# params: none
list_pkgs()
{
local i
local it
# We can't rely on shell expansion here since we would be burned if * is empty!
for i in $($LS -1 $metadir/prototype.* 2>/dev/null)
do
it=$($BASENAME $i)
echo ${it##prototype.}
done
}
# add_meta_file(): add a metafile entry to the prototype file
# params: $1 = keyword $2 = filename $3 = metafile suffix
# Additions will be done to the file $metadir/prototype
add_meta_file()
{
if [ $# -lt 3 ]; then
error $E_MISSING_ARGS add_meta_file
fi
local secname=$3
if [ -r "$2" ]; then
echo "i $1=$2" >> $metadir/prototype.$secname
else
error $E_BAD_FILE add_meta_file
fi
}
# add_scripts(): Add scripts to prototype
# params: $1 = metafile suffix
add_scripts()
{
if [ $# -lt 1 ]; then
error $E_MISSING_ARGS add_scripts
fi
local secname=$1
# If a dependency file is available then use it
[ -r $metadir/depend.$secname -a $usedepend -eq 1 ] && add_meta_file depend "$metadir/depend.$secname" $secname
# If a space file is available then use it
[ -r $metadir/space.$secname -a $usespace -eq 1 ] && add_meta_file space "$metadir/space.$secname" $secname
if [ $usescripts -eq 1 ]; then
[ -r $metadir/preinstall.$secname ] && add_meta_file preinstall "$metadir/preinstall.$secname" $secname
[ -r $metadir/postinstall.$secname ] && add_meta_file postinstall "$metadir/postinstall.$secname" $secname
[ -r $metadir/preremove.$secname ] && add_meta_file preremove "$metadir/preremove.$secname" $secname
[ -r $metadir/postremove.$secname ] && add_meta_file postremove "$metadir/postremove.$secname" $secname
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_meta
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
}
# add_proto(): Add entries to prototype file
# params: $1 = permission $2 = owner $3 = group $4 = filespec $5 = metafile suffix
# $5 is usually the section header from pkgdef
# Additions will be done to the file $metadir/prototype.$pkgname
add_proto()
{
if [ $# -lt 5 ]; then
error $E_MISSING_ARGS add_proto
fi
local i
local defperm=$1
local owner=$2
local group=$3
local fspec=$(_upls $4)
local secname=$5
local FILES=$($FIND $fspec -type f -print|$TEE -a $metadir/files.tmp)
OIFS=$IFS
IFS="
"
for i in $FILES
do
IFS=$OIFS
if [ "$defperm" == "-" ]; then
permlist=$($LS -l "$i" | $CUT -d " " -f 1)
perm=$(compute_octal $permlist)
fi
echo "f none $i $perm $owner $group" >> $metadir/prototype.$secname
done
IFS=$OIFS
# Handle symlinks
local FILES=$($FIND $fspec -type l -print|$TEE -a $metadir/files.tmp)
OIFS=$IFS
IFS="
"
for i in $FILES
do
IFS=$OIFS
if [ "$defperm" == "-" ]; then
permlist=$($LS -l "$i" | $CUT -d " " -f 1)
perm=$(compute_octal $permlist)
fi
local temp=`$LS -l "$i"|$CUT -d '>' -f 2`
local symval=${temp# }
echo "s none $i=$symval $perm $owner $group" >> $metadir/prototype.$secname
done
IFS=$OIFS
# Handle directories
local FILES=$($FIND $fspec -type d -print|$TEE -a $metadir/files.tmp)
OIFS=$IFS
IFS="
"
for i in $FILES
do
IFS=$OIFS
if [ "$defperm" == "-" ]; then
permlist=$($LS -ld "$i" | $CUT -d " " -f 1)
perm=$(compute_octal $permlist)
fi
echo "d none $i $perm $owner $group" >> $metadir/prototype.$secname
done
IFS=$OIFS
# Handle hardlinks - FIXME!
}
# add_dir(): Add a single dir to prototype file
# params: $1 = perms $2 = owner $3 = group $4 = dir $5 = metafile suffix
add_dir()
{
if [ $# -lt 5 ]; then
error $E_MISSING_ARGS add_dir
fi
local defperm=$1
local owner=$2
local group=$3
local dir=$(_upls $4)
local secname=$5
if [ "$defperm" == "-" ]; then
permlist=$($LS -ld "$dir" | $CUT -d " " -f 1)
perm=$(compute_octal $permlist)
fi
echo "d none $dir $perm $owner $group" >> $metadir/prototype.$secname
echo "$dir" >> $metadir/files.tmp
}
# parse_pkgdef(): Read in $metadir/pkgdef
# params: none
# This will parse the package descriptions in
# pkgdef that tells us how many packages there
# should be and what they include.
parse_def()
{
local section=0
local foundfiles=0
local secname=""
local secpos=0
local legalend=0
while read line
do
case ${line:0:1} in
'#') ;;
'[')
if [ $section -eq 1 ]; then
error $E_BAD_SECTION_BEGIN parse_def
else
section=1
secname="${line:1:((${#line}-2))}"
legalend=0
fi
;;
'')
if [ $section -eq 0 ]; then
error $E_BAD_SECTION_END parse_def
else
section=0 # Finished this section
foundfiles=0 #
legalend=1 # We encountered a syntacticly correct section end
# Add scripts if requested
add_scripts $secname
fi
;;
*)
equalindex=$(expr index "$line" =)
if [ ! $equalindex -eq 0 ]; then
case "${line:0:(($equalindex-1))}" in
'pkgname')
pkgname="$(_upls ${line:$equalindex:${#line}})"
;;
'name')
name="$(_upls ${line:$equalindex:${#line}})"
;;
'pkgcat')
pkgcat="$(_upls ${line:$equalindex:${#line}})"
;;
'pkgvendor')
pkgvendor="$(_upls ${line:$equalindex:${#line}})"
;;
'pkgdesc')
pkgdesc="$(_upls ${line:$equalindex:${#line}})"
;;
'pkgver')
pkgver="$(_upls ${line:$equalindex:${#line}})"
;;
esac
else # Perhaps we hit 'files'?
if [ "${line:0:5}" == "files" ]; then
triplet="${line:6:((${#line}-5-2))}"
defaultperms=$(echo $triplet | $AWK -F, '{ print $1 }')
defaultuid=$(echo $triplet | $AWK -F, '{ print $2 }')
defaultgid=$(echo $triplet | $AWK -F, '{ print $3 }')
foundfiles=1
pack_info $secname # Create pkginfo
# Start the prototype file by adding the pkginfo file
add_meta_file pkginfo "$metadir/pkginfo.$secname" $secname
else
if [ $foundfiles -eq 1 ]; then # We already found the 'files' line so this must be the filelist
if [ "${line:0:4}" == "dir " ]; then
add_dir $defaultperms $defaultuid $defaultgid "${line:4}" $secname # Add dir entry
else
add_proto $defaultperms $defaultuid $defaultgid "$line" $secname # Build protype file from filespec
fi
fi
fi
fi
;;
esac
done < $metadir/pkgdef
# If there is no blank line at the end of a pkgdef section (if there is only one section that is very
# likely) then we end up here without having executed the 'section end' actions (case '' above)
if [ $legalend -eq 0 ]; then
if [ $section -eq 0 ]; then
error $E_BAD_SECTION_END parse_def
else
section=0 # Finished this section
foundfiles=0 #
# Add scripts if requested
add_scripts $secname
fi
fi
}
# check_unpackaged(): Check if there are unpackaged files in the stage area
# params: none
check_unpackaged()
{
local upf
local i
local indent4=" "
$FIND . -type f -print|$SED -e 's/\.\///g' > $tmpdir/files.tmp
$FIND . -type l -print|$SED -e 's/\.\///g' >> $tmpdir/files.tmp
$FIND . -type d -print|$SED -e 's/\.\///g'|$GREP -v '^\.' >> $tmpdir/files.tmp
$SORT $metadir/files.tmp|$UNIQ > $tmpdir/f1
$SORT $tmpdir/files.tmp > $tmpdir/f2
upf="$($CAT $tmpdir/f1 $tmpdir/f2 | $SORT | $UNIQ -u)"
if [ ! -z "$upf" ]; then
echo "There are unpackaged files in the stagedir:"
for i in $upf
do
echo "${indent4}${i}"
done
$RM -f $tmpdir/f1 $tmpdir/f2
if [ "$ignore_unpackaged_files" -eq 0 ]; then
error $E_UNPACKAGED_FILES check_unpackaged
fi
fi
$RM -f $tmpdir/f1 $tmpdir/f2
}
# get_pkgname(): Extract pkgname (PKG) from a pkginfo file
# params: $1 = metafile suffix
get_pkgname()
{
local secname=$1
if [ -r $metadir/pkginfo.$secname ]; then
local pn=$($GREP PKG $metadir/pkginfo.$secname)
local pname=$(_upls ${pn##PKG=})
echo $pname
fi
}
# get_pkgrev(): Extract pkgrev (REV part of VERSION field) from pkginfo file
# params: $1 = metafile suffix
get_pkgrev()
{
local secname=$1
local verfield="$($GREP VERSION $metadir/pkginfo.$secname|$SED -e 's/"//g')"
local secver=$(_upls ${verfield#*REV=})
echo $secver
}
# do_strip_bin(): Strip binaries
# params: none
do_strip_bin()
{
echo "Stripping ELF binaries..."
for f in `$FIND . -type f \( -perm -0100 -o -perm -0010 -o -perm -0001 \) -exec $FILE {} \; | \
$GREP -v ' dynamic lib ' | \
$SED -n -e 's/^\(.*\):[ ]*ELF.*, not stripped/\1/p'`; do
$STRIP $strip_elf_args $f || :
done
}
# do_strip_shared(): Strip shared libraries
# params: none
do_strip_shared()
{
echo "Stripping ELF shared objects..."
# Strip ELF shared objects (see brp-strip-shared from RPM)
# Please note we don't restrict our search to executable files because
# our libraries are not (should not be, at least) +x.
for f in `$FIND . -type f -a -exec $FILE {} \; | \
grep ' dynamic lib ' | \
$SED -n -e 's/^\(.*\):[ ]*ELF.*, not stripped/\1/p'`; do
$STRIP $strip_shared_args $f
done
}
# do_strip_static(): Strip static archives
# params: none
do_strip_static()
{
echo "Stripping static archives..."
# Strip static libraries. (see brp-strip-static-archive from RPM)
for f in `$FIND . -type f -a -exec $FILE {} \; | \
$GREP 'current ar archive' | \
$SED -n -e 's/^\(.*\):[ ]*current ar archive,.*/\1/p'`; do
$STRIP $strip_static_args $f
done
}
#####################################################
# Define generic functions for different build stages
#####################################################
# generic_pack(): Build package using files from 'install' stage
# params: none
# 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* shortroot=1.
generic_pack()
{
if [ "$1" == "shortroot" ]; then
error $E_ARG_OBSO generic_pack
fi
clean meta
if [ "$shortroot" -eq 1 ]; then
if [ -d "${stagedir}/${_mandir}" ]; then
setdir ${stagedir}/${_mandir}
[ "$catman" -eq 1 ] && fix_man
[ "$gzman" -eq 1 ] && compress_man
fi
if [ -d "${stagedir}/${_infodir}" ]; then
setdir ${stagedir}${topinstalldir}${dir_prefix}/${_infodir}
[ "$gzinfo" -eq 1 ] && compress_info
fi
setdir "$stagedir"
else
if [ -d "${stagedir}${topinstalldir}${dir_prefix}/${_mandir}" ]; then
setdir ${stagedir}${topinstalldir}${dir_prefix}/${_mandir}
[ "$catman" -eq 1 ] && fix_man
[ "$gzman" -eq 1 ] && compress_man
fi
if [ -d "${stagedir}${topinstalldir}${dir_prefix}/${_infodir}" ]; then
setdir ${stagedir}${topinstalldir}${dir_prefix}/${_infodir}
[ "$gzinfo" -eq 1 ] && compress_info
fi
setdir "${stagedir}${prefix}"
fi
parse_def
check_unpackaged
# Create a list of all the packages that we are going to build
for i in $(list_pkgs)
do
make_pkg $i
done
}