buildpkg/buildpkg.packaging.solaris
2012-05-26 10:54:42 +02:00

995 lines
32 KiB
Plaintext

# Function library for buildpkg framework
# It adds support for creating Solaris packages in 'sysv' format
# Copyright (C) 2003-2010 Tom G. Christensen <tgc@jupiterrise.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Written by Tom G. Christensen <tgc@jupiterrise.com>.
#
# 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 depend.*.auto depend.*.all sums sums.*"
# Define defaults
# pkginfo information.
# Override as necessary.
pkgcat="application" # A reasonable default
pkgvendor="http://change/me/please"
pkgdesc="mumble mubmle... hmm someone forgot to fill this out!"
# vendor & contact information
pkgedby="Tom G. Christensen"
email=swpkg@jupiterrise.com
arch=`uname -p`
os=sunos`${__uname} -r`
# Default pkginfo.in file
pkginfo=$buildpkgscripts/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
usecompver=1 # default to add compver if available in $metadir
ignore_unpackaged_files=0 # default to check for unpackaged files in the stage area
deps_resolve_symlinks=0 # Set to 1 to resolve symlinks before computing deps (requires GNU readlink)
create_versioned_deps=1 # Set to 1 to create versioned dependencies
version_all_deps=0 # Set to 1 to add version on *all* deps, even SUNW (if enabled)
include_all_deps=1 # Set to 1 to create deps on packages regardless of vendor
# To exclude a dependency, add its name to this variable
ignore_deps=""
# Solaris doesn't know how to handle any kind of compressed manpages
gzman=0
# If not using gcc then please set this to 1
suncc=0
# Try and get it right from the beginning on Solaris
_mandir=share/man
_infodir=share/info
# Default configure args
configure_args='--prefix=$prefix --mandir=${prefix}/${_mandir} --infodir=${prefix}/${_infodir}'
# Host specific configuration
[ -r $buildpkgscripts/config.`hostname`.solaris ] && . $buildpkgscripts/config.`hostname`.solaris
# Distfiles should be named like this
# <name>-<version>-<pkgver>.sb-<os>-<arch>-<pkgdirdesig>
# ie: libmad-0.14.2b-1.sb-sol5.8-sparc-local
# We hardquote it so that we can control when we want it
# evaluated (using _upls)
distfile='$secname-$version-$secver.tgc-$os-$arch-$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
local pstamp="$os-$(${__uname} -n)`date '+%Y%m%d%H%M'`"
# Check length of pkgname and name to make sure we're within limits
[ ${#pkgname} -gt 9 ] && error $E_SVR4_PKG_OVERFLOW pack_info
[ ${#name} -gt 256 ] && error $E_SVR4_NAME_OVERFLOW pack_info
${__sed} -e "s#%%pkgname%%#$pkgname#g" \
-e "s#%%version%%#$version#g" \
-e "s#%%pkgcat%%#$pkgcat#g" \
-e "s#%%pkgvendor%%#$pkgvendor - packaged by $pkgedby#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" \
-e "s#%%email%%#$email#g" \
-e "s#%%maxinst%%#$maxinst#g" \
-e "s#%%arch%%#$arch#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
if [ $usedepend -eq 1 ]; then
[ -r $metadir/depend.$secname ] && cat $metadir/depend.$secname > $metadir/depend.${secname}.all
[ -r $metadir/depend.${secname}.auto ] && cat $metadir/depend.${secname}.auto >> $metadir/depend.${secname}.all
add_meta_file depend "$metadir/depend.${secname}.all" $secname
fi
# If a compver file is available then use it
[ -r $metadir/compver.$secname -a $usecompver -eq 1 ] && add_meta_file compver "$metadir/compver.$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
}
# auto_rel(): Fix up and add releasenotes to stagedir
# params: $1 = secname
# This will make some substitutions on a release note template
# and then copy the result to $stagedir/${metainstalldir}relnotes/$topdir-$version-$pkgver.txt
auto_rel()
{
local secname=$1
local i
local rn
for i in relnotes relnotes.${_os} relnotes.$secname relnotes.${_os}.$secname
do
[ -r ${metadir}/${i} ] && rn=${metadir}/$i
done
# No local relnotes use global template
if [ ! -r "${rn}" ]; then
echo "auto_rel: Using global relnotes template"
rn=$buildpkgscripts/relnotes.template.irix
fi
local relmetadir=${stagedir}${metainstalldir}relnotes/$secname-$version-$pkgver
### compute configure info for relnotes
local cf="$(_upls $configure_args)"
[ -n "$ac_overrides" ] && local aco="$(for ar in $ac_overrides; do echo $ar; done | ${__awk} '{ printf "%s \\\\ \\n",$0 }')"
local temp_fullcf="$(echo "$__configure $cf" | ${__awk} '{ printf "%s\\n",$0 }')"
temp_fullcf="$(echo "${aco}${temp_fullcf}")"
# Remove trailing whitespace and \n
local fullcf="${temp_fullcf%\\*}"
###
### compute compiler info for relnotes
if [ $suncc -eq 0 ]; then
#local compiler_temp="$(gcc --version 2>&1 | ${__sed} -n '1,1p')"
#local compiler="gcc ${compiler_temp##* }"
local compiler="$(gcc -v 2>&1 | ${__sed} -n '/^gcc/ s/ version//p')"
else # not gcc
local compiler="$(cc -version 2>&1)"
if [ "$CXX" = "g++" ]; then
# SUN cc with gnu g++
local compiler_temp="$(g++ --version 2>&1 | ${__sed} -n '1,1p')"
local compiler="$((echo $compiler; echo g++ ${compiler_temp##* }) | ${__awk} '{ printf "%s\\n",$0 }')"
local compiler="${compiler%\\*}"
fi
fi
###
local pkgnam=$(get_pkgname $secname)
local vendor=$(get_pkgvendor $secname)
local packager="${pkgedby} <${email}>"
### Compute SHA1 sums for all source entries
local s
local path
local file
local source_sha1sum
local temp_source_sha1sum=""
# older bash 2.x doesn't like C-style for loops (observed on Solaris 2.x)
#for ((snum=0; $snum < ${#source[@]}; s++))
local snum=0
while [ $snum -lt ${#source[@]} ]
do
path="$(get_source_path ${source[$snum]})"
file="$(get_source_filename ${source[$snum]})"
(cd "$path"; ${__sha1sum} "$file") >> $metadir/sums.${secname}
let snum=snum+1
done
[ -r "$metadir/sums.${secname}" ] && temp_source_sha1sum="$(cat $metadir/sums.${secname} | ${__awk} '{ printf "%s\\n",$0 }')"
source_sha1sum="${temp_source_sha1sum%\\*}"
### End of SHA1 sum computing
### Extract environtment variables
local temp_extracted_env="$(${__sed} -e 's/export /echo ENV /g' ${buildpkgbase}/${pkgdir}/build.sh >> /tmp/env.sh; bash /tmp/env.sh|${__grep} ^ENV|${__sed} -e 's/ENV //g'|${__awk} '{ printf "%s\\n",$0 }' && ${__rm} -f /tmp/env.sh)"
# Remove trailing \n
local extracted_env="${temp_extracted_env%\\*}"
###
### Add dependencies
local temp_deps="$(${__cat} $metadir/depend.$secname.all | ${__sed} -e '/^$/d;/^ /d' | ${__sort} -u | ${__awk} '{ printf "%s\\n",$0 }')"
local deps="${temp_deps%\\*}"
###
${__mkdir} -p $relmetadir
${__gsed} -e "s;%%PKGNAME%%;${pkgnam};g" \
-e "s;%%SOURCE_AND_VER%%;${topdir}-${version};g" \
-e "s;%%CONFIGURE%%;${fullcf};g" \
-e "s;%%COMPILER%%;${compiler};g" \
-e "s;%%VENDOR%%;${vendor};g" \
-e "s;%%PKGEDBY%%;${packager};g" \
-e "s;%%SOURCE_SHA1SUM%%;${source_sha1sum};g" \
-e "s;%%ENVIRONMENT%%;${extracted_env};g" \
-e "s;%%DEPENDENCIES%%;${deps};g" \
${rn} > "$relmetadir/${secname}.txt"
# Add a ChangeLog if it exists
if [ -r $metadir/ChangeLog ]; then
echo "auto_rel: Adding ChangeLog to relnotes"
# See if we can find an entry for this build otherwise complain
if [ -z "${__grep} ${version}-${pkgver}$" ]; then
echo "autorel: WARNING: Did not find ChangeLog entry for ${version}-${pkgver}!"
fi
echo >> "$relmetadir/${secname}.txt"
cat $metadir/ChangeLog >> "$relmetadir/${secname}.txt"
else
echo "auto_rel: WARNING: ChangeLog is missing!"
fi
### Add the relnotes to the prototype file
add_dir $defaultperms $defaultuid $defaultgid "${metaprefix}relnotes" $secname
add_proto $defaultperms $defaultuid $defaultgid "${metaprefix}relnotes/$secname-$version-$pkgver" $secname
}
# auto_dir(): Make sure all necessary dir entries are in prototype
# param: $1 = secname
# To avoid an endless amount of dir entries in the pkgdef this
# function will try to automatically determine all the needed
# entries and then add anyone missing
auto_dir()
{
local secname=$1
local fdirs
local ddirs
local i
local j
fdirs=$(${__awk} '/^[fs]/ { print $3 }' $metadir/prototype.$secname | ${__sed} -e 's,\(.*\)=.*$,\1,' | ${__sed} -e 's,\(.*\)/.*$,\1,' | ${__sort} -u)
ddirs=$(${__awk} '/^d/ { print $3 }' $metadir/prototype.$secname | ${__sort} -u)
for i in $fdirs
do
# Ugly, but we need to strip first in the while loop to be able to
# determine exit condition properly
local path_comp="$i/dummy"
local done=0
# for each fdir we verify that all path components have dir entries
# by checking with ddirs. If one is missing it is added
while [ $done -eq 0 ]
do
# To see if we're done the string must be the same after stripping
[ "$path_comp" = "${path_comp%/*}" ] && done=1
path_comp=${path_comp%/*}
#echo "auto_dir: Checking $path_comp"
local found=0
for j in $ddirs
do
if [ "$path_comp" = "$j" ]; then
found=1
break
fi
done
if [ "$found" -eq 0 ]; then
# No match, we must add an entry
ddirs="$(echo $ddirs $path_comp)"
### FIXME defaultperms, defaultuid and defaultgid as essentially uninitialized here!
add_dir $defaultperms $defaultuid $defaultgid "$path_comp" $secname # Add dir entry
echo "auto_dir: Adding $path_comp for $secname"
fi
done
done
}
# dep_pkg_name: Given a filename it will look it up and find the PKGNAME
# Params: A list of filenames
# For each file we use pkgchk -l -p to find the package containing it
dep_pkg_name()
{
local pkg
local i
while read files
do
for i in $files
do
[ -L "$i" -a $deps_resolve_symlinks -eq 1 ] && i=$(${__readlink} -f "$i")
pkg=$(pkgchk -l -p $i | ${__awk} '/^\t/ { print $1 }')
if [ -n "$pkg" -a $(echo $pkg | wc -l) -eq 1 ]; then
#echo "Found $i in $pkg" >> /tmp/depdebug
echo "$pkg"
else
echo "dep_pkg_name: $i returned more than one package" >> /tmp/depdebug
fi
done
done
}
# extract_deps(): Given a section name it will extract the dependencies
# params: $1 = section name (like libiconv)
# It goes through the prototype.$1 file and computes the dependencies
# for all files and returns the PKGINST attribute
extract_deps()
{
local secname=$1
# Can't use setdir since it has output
cd ${stagedir}${topinstalldir}
# Grab the filelist and classify files
local filelist=$(${__awk} '{ print $3 }' $metadir/prototype.$secname | ${__grep} '.')
local exelist=$(echo $filelist | ${__xargs} ${__file} | ${__egrep} -v ":.* (commands|script)" | ${__grep} -v "ar archive" | ${__grep} ":.*executable" | ${__cut} -d: -f1)
local scriptlist=$(echo $filelist | ${__xargs} ${__file} | ${__egrep} ":.* (commands|script)" | ${__cut} -d: -f1)
local liblist=$(echo $filelist | ${__xargs} ${__file} | ${__grep} -v "ar archive" | ${__grep} ":.*dynamic lib" | ${__cut} -d: -f1)
# Compute dependencies for executables
if [ -n "$exelist" ]; then
for f in $exelist; do
[ -r $f -a -x $f ] || continue
# Generic Solaris ldd
${__ldd} $f | ${__grep} -v 'not found' | ${__awk} '/\=/ { print $3 }'
done | ${__sort} -u | dep_pkg_name | ${__sort} -u
fi
# Compute dependencies for dynamic libraries
if [ -n "$liblist" ]; then
for f in $liblist; do
[ -r $f ] || continue
# Generic Solaris ldd
${__ldd} $f | ${__grep} -v 'not found' | ${__awk} '/\=/ { print $3 }'
done | ${__sort} -u | dep_pkg_name | ${__sort} -u
fi
# Compute dependencies for scripts
if [ -n "$scriptlist" ]; then
for f in $scriptlist; do
[ -r $f -a -x $f ] || continue
interp="$(${__head} -n 1 $f | ${__cut} -d\! -f2- | ${__sed} -e 's/ -.*//')"
if [ -L "$interp" ]; then
echo $(${__file} -h "$interp" | ${__sed} -e 's/.* to //')
else
if [ "$(echo $interp | ${__cut} -d' ' -f1)" = "/usr/bin/env" ]; then
echo "/usr/bin/env"
else
echo $interp
fi
fi
done | ${__sort} -u | dep_pkg_name | ${__sort} -u
fi
}
# auto_deps(): Compute dependencies
# params: $1 = section name $2 = pkgname
# It will call extract_deps() to get the packagenames of the
# dependencies. The dependencies will be added to $metadir/depend.$1.auto
auto_deps()
{
local j
local deps
local i
local ignore
local secname=$1
local pkgname=$(get_pkgname $secname)
local temp
deps="$(extract_deps $secname | ${__sort} -u)"
# We need to sort out any packages created from the same build
# Internal deps *must* be recorded in a depend file instead
for j in $(list_pkgs)
do
temp=$(get_pkgname $j)
deps=$(echo $deps | ${__sed} -e "s/$temp//")
done
# Parse any speciel depends
# We don't do ignore_deps processing for these deps
if [ -r $metadir/depend ]; then
local extra_pkgname # Package that should have the depend
local extra_dep_pkgname # The name of depend (either a pkgname or a secname)
local extra_dep_version # version of the depend (or auto keyword)
${__sed} -n "/^$pkgname /p" $metadir/depend |
while read extra_pkgname extra_dep_pkgname extra_dep_version
do
local internal_dep=0
for i in $(list_pkgs)
do
[ "$extra_dep_pkgname" = "$i" ] && internal_dep=1
done
if [ $internal_dep -eq 1 ]; then
echo "P $(get_pkgname $extra_dep_pkgname) $(get_pkgdesc $extra_dep_pkgname)"
else
echo "P $extra_dep_pkgname $(pkgparam $extra_dep_pkgname NAME)"
fi
if [ $create_versioned_deps -eq 1 ]; then
# create versioned_deps
if [ "$extra_dep_version" = "auto" ]; then
if [ $internal_dep -eq 1 ]; then
extra_dep_version="$(get_pkgversion $extra_dep_pkgname)"
extra_dep_pkgname=$(get_pkgname $extra_dep_pkgname) # For later use we can now resolve this permanently
else
extra_dep_version="$(pkgparam $extra_dep_pkgname VERSION)"
fi
fi
# Only for deps with $pkgprefix?
if [ $version_all_deps -eq 0 ]; then
[ -n "$(echo $extra_dep_pkgname | ${__grep} $pkgprefix)" ] && echo -e "\t($arch) $extra_dep_version"
else
echo -e "\t($arch) $extra_dep_version"
fi
fi
done > $metadir/depend.$secname.auto
fi
if [ $include_all_deps -eq 0 ]; then
deps=$(echo $deps | sed -n "/$pkgprefix/p")
fi
for j in $deps
do
ignore=0
for i in $ignore_deps
do
# if there's a match then set ignore flag and break the loop
[ "$i" = "$j" ] && ignore=1 && break
done
[ $ignore -eq 0 ] && echo "P $j $(pkgparam $j NAME)"
if [ $ignore -eq 0 -a $create_versioned_deps -eq 1 ]; then
# create versioned_deps
# Only for deps with $pkgprefix?
if [ $version_all_deps -eq 0 ]; then
[ -n "$(echo $j | ${__grep} $pkgprefix)" ] && echo -e "\t($arch) $(pkgparam $j VERSION)"
else
echo -e "\t($arch) $(pkgparam $j VERSION)"
fi
fi
done >> $metadir/depend.$secname.auto
}
# 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
local condexpr=""
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
# Set default value for maxinst for the new section
maxinst=1
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
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'|'shortdesc')
pkgdesc="$(_upls ${line:$equalindex:${#line}})"
;;
'pkgver')
pkgver="$(_upls ${line:$equalindex:${#line}})"
;;
'maxinst')
maxinst="$(_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
elif [ "${line:0:3}" = "if(" ]; then
# Conditional expression
condexpr=${line#if(}
condexpr=${condexpr%%)*}
if [ "x${!condexpr}" != "x" ]; then
# value of condexpr was defined so we should process the line as normal
add_proto $defaultperms $defaultuid $defaultgid "${line#if(*)}" $secname
fi
elif [ "${line:0:12}" = "default_docs" ]; then
add_proto $defaultperms $defaultuid $defaultgid "${line:12}${metaprefix}${_docdir}/${secname}-${version}" $secname # Add std. doc location
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 #
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} | ${__sed} -e '/^relnotes/d' | ${__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
}
# get_pkgversion(): Extract pkgversion (VERSION field) from pkginfo file
# params: $1 = metafile suffix
get_pkgversion()
{
local secname=$1
local verfield="$(${__grep} VERSION $metadir/pkginfo.$secname|${__sed} -e 's/"//g')"
local secver=$(_upls ${verfield##VERSION=})
echo $secver
}
# get_pkgdesc(): Extract pkgdesc from a pkginfo file
# params: $1 = metafile suffix
get_pkgdesc()
{
local secname=$1
if [ -r $metadir/pkginfo.$secname ]; then
local pd=$(${__grep} NAME $metadir/pkginfo.$secname)
local pdesc=$(_upls ${pd##NAME=})
echo $pdesc
fi
}
# get_pkgvendor(): Extract upstram vendor information from a pkginfo file
# params: $1 = metafile suffix
get_pkgvendor()
{
local secname=$1
if [ -r $metadir/pkginfo.$secname ]; then
local pv=$(${__sed} -n 's/VENDOR=\(.*\) - .*/\1/p' $metadir/pkginfo.$secname | ${__tr} -d '"')
echo $(_upls $pv)
fi
}
# compat(): Add a series of entries to a compver file
# params: $1 = secname $2 = version $3 = startrev $4 = endrev
compat()
{
local secname=$1
local compat_version=$2
local startrev=$3
local endrev=$4
local i
while [ $startrev -le $endrev ]
do
echo "$compat_version,REV=$startrev" >> $metadir/compver.${secname}
let "startrev=startrev+1"
done
}
# docs_for(): Add files from srcdir to specific package doc dir
# params: $1 = secname $2....x = files to copy
# Copies files from $srcdir to $_docdir/$secname-$version
docs_for()
{
local secname=$1
shift
local f
local ddir # Holds internal value of _docdir
if [ ! -z $# ]; then
setdir source
ddir=${stagedir}${prefix}/${_docdir}/${secname}-${version}
${__mkdir} -p $ddir
echo "Adding docs"
until [ -z "$1" ]
do
for f in $(_upls $1)
do
(${__tar} -cf - "$f")|(cd $ddir; ${__tar} -xvBpf -)
done
shift
done
fi
}
# 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
# pkgdef entries should always be relative to topinstalldir
# except for the auto ones - src,dist,relnotes
# In that case we use metaprefix to designate their position relative
# to topinstalldir (note metainstalldir can never be above topinstalldir)
# ie. topinstalldir=/usr/local/gcc & metainstalldir=/usr/local is a no no.
# but topinstalldir=/usr/local & metainstalldir=/usr/local is okay and is the
# default
# This mostly matters when we have topinstalldir=/ and prefix=/usr/local like
# with prngd and openssh
# Also note that metaprefix is entirely for internal use in create_idb when
# we create the "auto" entries.
# Determine at what level metainstalldir is compared to topinstalldir
metaprefix=${metainstalldir##$topinstalldir}
metaprefix="${metaprefix#/*}"
# If we have a path then we'll need a / appended
[ ! -z "$metaprefix" ] && metaprefix="${metaprefix}/"
# We need to add slash to the end of metainstalldir but *only* if
# metainstalldir is not /. We do this to avoid creating an absolute path
# which could happen with metainstalldir=/ if we unconditionally add /.
[ ! "$metainstalldir" = "/" ] && metainstalldir="${metainstalldir}/"
# pkgdef should list files relative to topinstalldir
setdir "${stagedir}${topinstalldir}"
parse_def
for i in $(list_pkgs)
do
auto_dir $i
done
check_unpackaged
# Create a list of all the packages that we are going to build
for i in $(list_pkgs)
do
auto_deps $i
add_scripts $i
auto_rel $i
make_pkg $i
done
}
# vim: set filetype=sh : #
# vim: set sts=4 : #
# vim: set shiftwidth=4 : #