buildpkg/buildpkg.packaging.solaris
Tom G. Christensen 82dcedd482 Add 'nice' os tagging to PSTAMP
Default permissions weren't being used when generating prototype files
Keep track of packages and make each one gets the proper pkginfo file added
to the prototype file.
pkgdef entries should now be relative to $topinstalldir.
2009-12-19 14:38:42 +01:00

522 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=`$UNAME -r`
# Courtesy of nba (see dm2conv/solaris/mkpkg.sh)
case $os in
5.[0123456]|5.5.1)
os=sol`echo $os | sed s/5./2./`
;;
5.*)
os=sol`echo $os | sed s/5.//`
;;
*)
echo I do not know how; exit 1;;
esac
# 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)
else
perm=$defperm
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)
else
perm=$defperm
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)
else
perm=$defperm
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
local hasaddedpkginfo=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
hasaddedpkginfo=0
# 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
if [ $hasaddedpkginfo -eq 0 ]; then
# start a new package
pack_info $secname # Create pkginfo
# Start the prototype file by adding the pkginfo file
add_meta_file pkginfo "$metadir/pkginfo.$secname" $secname
hasaddedpkginfo=1
fi
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 [ -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}"
# pkgdef should list files relative to topinstalldir
setdir "${stagedir}${topinstalldir}"
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
}