# Function library for buildpkg framework # It adds support for creating Irix packages in 'inst' format # Copyright (C) 2003-2012 Tom G. Christensen # 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 . # Written by Tom G. Christensen . # # Define tool programs # *only* platform specific packaging tools should be listed here # generic tools go in buildpkg.functions GENDIST="/usr/sbin/gendist" GENDIST_OPTS="-nostrip" SHOWPRODS="/usr/sbin/showprods" SHOWFILES="/usr/sbin/showfiles" # This is the hostname command we'll want on Irix HOSTNAME=/usr/bsd/hostname # Configuration vars imageconf=$buildpkgscripts/image.conf subsysconf=$buildpkgscripts/subsys.conf idbfile=$metadir/$topdir.idb specfile=$metadir/$topdir.spec depends=$metadir/depends replaces=$metadir/replaces updates=$metadir/updates opsfile=$metadir/ops hidefile=$metadir/hide showfilescache=/tmp/sf.cache # Preformat manpages since Irix is not likely to have nroff available symlinkman=1 # resolve .so links or formatting/compressing will fail catman=1 # Compress manpages gzman=1 compressman=0 # strip? dostrip=1 dostrip_static=0 # Atleast std. Irix strip seems to mangle archives if strip -f is used # Setup default args for strip. They match /usr/bin/strip in Irix 6.2 # -f is undocumented on 5.3 and renders DSOs unlinkable. # Change these if you're using strip from GNU Binutils (*not* recommended) strip_elf_args="" # GNU default is -g strip_shared_args="-f" # GNU default is -g strip_static_args="-f" # GNU default is -g # Other usedepend=1 # Don't use depend file even if it's available usescripts=1 # Don't add ops even if they're available useupdates=1 # Enable/disable the use of an updates file if available ignore_unpackaged_files=0 # default to check for unpackaged files in the stage area include_source=0 # Include source[x] in the opt.src subsystem and not just patch[x] useautodir=1 # Enable or disable the auto_dir run # vendor & contact information to be added in relnotes pkgedby="Tom G. Christensen" email="irixpkg@jupiterrise.com" # ver_width controls the width of the pkgversion numbers created # do *not* change this blindly # inst uses an INT value for the version number which can atmost be # 2,147,483,647 that means it's not safe to extend the version number # beyond 9 digits. With 10 digits a version starting with 22.xxxx will overflow # the INT and crash inst. ver_width=9 # Some versioning causes trouble with the normal version transformation (like 2.8->2.10) # which ends up as 210 (2.10) < 280 (2.8) which is wrong # This control will turn on zero prefixing of single digit version components in a version string # so that 0210 (2.10) > 0208 (2.8). # The default is on but be aware that it can also give problems with version transformation (like 2.08->2.1) # which ends up as 0208 (2.08) > 0201 (2.1). useextendedver=1 # Use run_configure generic_configure=0 # Check config.log for nono libs check_ac=1 configlog=config.log # override as necessary # If you need to override any autoconf values put them in this string # ie. ac_cv_lib_sun_mntent=no etc. ac_overrides="" # Run this command for the configure stage __configure="./configure" # When using autodeps sometimes we get undesired dependencies # add them to this var to have them filtered out ignore_deps="" # When matching dependencies with packages should we resolve # symlinks before looking in the showfilescache? # Requires readlink from GNU coreutils. # Should be 1 for Irix 5.3 deps_resolve_symlinks=0 # If not using gcc then please set this to 1½ mipspro=0 # Comment these declarations to get it to run with ksh declare -a pc # Array of product categories (image.subsys) declare -a pd # Array of matching descriptions declare -a ps # Array of subsystem properties - default or nodefault declare -a pctop # Array of toplevel product categories (image) declare -a pdtop # Array of matching descriptions declare -a reqs # Array of subsystems with prereqs declare -a reqp # Array of prereqs (should match up with reqs) declare -a replacess # Array of subsystems that replaces another declare -a replacepkg # Array of what is replaced (should match up with replacess) declare -a updates # Array of subsystems that updates another declare -a updatepkg # Array of what is updated (should match up with updatess) declare -a hide # Files that should be "hidden" with nohist declare -a opfiles # Files that should have an ops associated declare -a opscript # Ops to associate with opfiles #override defaults pkgprefix=tgc_ pkgname=$pkgprefix$topdir os=irix`${__uname} -r` _os=$(${__uname} -sr|${__sed} -e 's/ //g' -e 's/\.//g' -e 's/IRIX64/IRIX/g'|${__tr} '[A-Z]' '[a-z]') cpu=mips3 configure_args='--prefix=$prefix --mandir=${prefix}/${_mandir} --infodir=${prefix}/${_infodir}' META_CLEAN="$topdir.spec $topdir.idb files.tmp ${depends##*/}_auto ${depends##*/}_all sums" # Host specific configuration [ -r $buildpkgscripts/config.$($HOSTNAME -s).irix ] && . $buildpkgscripts/config.$($HOSTNAME -s).irix distfile='$topdir-$version-$pkgver.tgc-$os-$cpu-$pkgdirdesig.tardist' ##################################################### # Internal helper functions ##################################################### indent4=" " indent8=" " indent12=" " indent16=" " indent24=" " # fix_ver(): "normalize" a version-pkgver pair # params: $1=version # Removes any '.' and '-' characters from a version string # It also extends the width to $ver_width by moving the package revision # to the far right and padding with zeroes inbetween. fix_ver() { local numpad local extendedwidth local extendedver="" local i local version=$1 local rev=${version##*-} local ver=$(echo ${version%%-*} | ${__sed} -e 's/-//g' -e 's/[a-zA-Z]//g') if [ $useextendedver -eq 1 ]; then ### experimental ### zero prefixes all single digits in a versionstring OIFS=$IFS IFS=". " for i in $ver do if [ ${#i} -eq 1 ]; then extendedver=${extendedver}0${i} else extendedver=${extendedver}${i} fi done ver=$extendedver fi if [ $useextendedver -eq 0 ]; then # Remove the dots ver=$(echo $ver | ${__sed} -e 's/\.//g') fi let "numpad = $ver_width - ${#ver} - ${#rev}" [ $numpad -lt 0 ] && error $E_BAD_VERSION fix_ver while [ $numpad -gt 0 ] do ver="${ver}0" let "numpad = $numpad - 1" done ver="${ver}${rev}" echo $ver } # spec_header() # param: $1=product name $2=description spec_header() { echo "product $1" echo "$indent4 id \"$2\"" } spec_footer() { echo "endproduct" } # spec_img_header() # param: $1=image name $2=image description $3=version spec_img_header() { local nver=$(fix_ver $3) echo "$indent4 image $1" echo "$indent8 id \"$2\"" echo "$indent8 version $nver" echo "$indent8 order 9999" } # spec_img_footer() spec_img_footer() { echo "$indent4 endimage" } # spec_subsys_header() # param: $1=image $2=subsys $3=description $4=subsys property spec_subsys_header() { echo "$indent8 subsys $2 $4" echo "$indent12 id \"$3\"" echo "$indent12 exp $pkgname.$1.$2" } # spec_subsys_req_header() # param: none spec_subsys_req_header() { echo "$indent16 prereq (" } # spec_subsys_req() # param: $1=prereq spec_subsys_req() { echo "$indent24 $1" } # spec_subsys_req_footer() # param: none spec_subsys_req_footer() { echo "$indent24"")" } # spec_subsys_replaces() # param: $1 = subsystem that is replaced spec_subsys_replaces() { echo "$indent12 replaces $1" } # spec_subsys_updates() # param: $1 = subsystem that is updated spec_subsys_updates() { echo "$indent12 updates $1" } # spec_subsys_footer() # param: none spec_subsys_footer() { echo "$indent8 endsubsys" } # check_ops(): Is there an opscript associated with $1 # param: $1=file to check check_ops() { local file="$1" local return="" if [ "$usescripts" -eq 0 ]; then echo $return fi #echo "file is $file" >> /tmp/debug for ((i=0; $i < ${#opfiles[@]}; i++)) do #echo "opfiles $i is ${opfiles[$i]}" >> /tmp/debug if [ "${opfiles[$i]}" == "$file" ]; then return="${opscript[$i]}" fi done echo $return } # fix_fname(): Sanitize filename # param: $1=filename to fix # The purpose is to "fix" filenames that gendist won't like # ie. names with space are a no-no. fix_fname() { local name="$1" local return # Replace ' ' with '_' return=$(echo $name|${__sed} -e 's/ /_/g') echo $return } # add_files() # Create IDB entries for all files in a specfic product category # Takes the following parameters # $1 = dirname to descend into # $2 = product_category to assign files # $3 = permissions to set on the files we find # $4 = user # $5 = group # $6 = special attribute add_files() { local fspec=$(_upls $1) local prodcat=$2 local defperm=$3 local owner=$4 local group=$5 local specattr=$6 local slash='' local topinstd=${topinstalldir:1} [ ! "$topinstalldir" == "/" ] && slash='/' #="${topinstalldir}/" # This is a workaround # Sometimes $topinstalldir:1 returns garbage when topinstalldir=/ [ "$topinstalldir" = "/" ] && topinstd="" local FILES=$(${__find} $fspec -type f -print|${__tee} -a $metadir/files.tmp) OIFS=$IFS # We play IFS tricks so we can handle filenames with embedded spaces 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 doop=$(check_ops "$i") fname=$(fix_fname "$i") if [ ! -z "$doop" ]; then if [ ! -z "$specattr" ]; then specattr="$specattr $doop" else specattr=$doop fi fi if [ ! -z "$specattr" ]; then echo "f $perm $owner $group ${topinstd}${slash}$fname $i ${pkgname}.${prodcat} $specattr" >>$idbfile else echo "f $perm $owner $group ${topinstd}${slash}$fname $i ${pkgname}.${prodcat}" >>$idbfile fi specattr="" # If there's more than one file we must reset specattr to avoid polluting the next entries 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) else perm=$defperm fi local temp=`${__ls} -l "$i"|${__cut} -d '>' -f 2` local symval=${temp# } fname=$(fix_fname "$i") echo "l $perm $owner $group ${topinstd}${slash}$fname $i ${pkgname}.${prodcat} symval($symval)" >>$idbfile done IFS=$OIFS } # add_dir(): Add a single dir entry to the IDB file # params: $1=dir $2=subsys $3=default permissons $4=defuid $5=defgid # Currently ops and specattr are unimplemented for dirs add_dir() { local fspec=$(_upls $1) local prodcat=$2 local defperm=$3 local owner=$4 local group=$5 local topinstd="$topinstalldir" #[ ! "$topinstalldir" == "/" ] && topinstalldir="${topinstalldir}/" [ ! "$topinstd" = "/" ] && topinstd="${topinstd:1}/" # This is a workaround # Sometimes $topinstalldir:1 returns garbage when topinstalldir=/ [ "$topinstd" = "/" ] && topinstd="" # Note that dir blablah is *not* added to $metadir/files.tmp #local FILES=$(${__find} $fspec -type d -print) local FILES=$fspec 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 fname=$(fix_fname "$i") echo "d $perm $owner $group ${topinstd}$fname $i ${pkgname}.${prodcat}" >>$idbfile done IFS=$OIFS } # fetch_imageconf(): Fetch a list of toplevel image entries with descriptions # params: none # Discard the ones that we don't have any subsystems for fetch_imageconf() { local pctopidx=0 local numloops=${#pc[@]} local i=0 while read image desc do for ((i=0; i < $numloops; i++)) do temp="${pc[$i]%%.*}" if [ "$image" == "$temp" ]; then pctop[$pctopidx]=$image pdtop[$pctopidx]=$desc let "pctopidx = $pctopidx + 1" break # We found a match no need to loop further fi done done < $imageconf } # fetch_subsysdesc(): Fetch a list of subsystem descriptions # params: none fetch_subsysdesc() { local i=0 local numloops=${#pc[@]} local ss local sp local desc while read ss sp desc do for ((i=0; i < $numloops; i++)) # Find subsystem... do if [ "${pc[$i]}" = "$ss" ]; then pd[$i]="$desc" if [ "$sp" == "nodefault" ]; then ps[$i]="" else ps[$i]=$sp fi break # Found it, skip to the next line fi done done < $subsysconf } # fetch_depends(): Fetch a list of subsystems and their prereqs # params: none # fetch_depends() { local reqidx=0 local havedep=0 [ -r ${depends} ] && ${__cat} ${depends} > ${depends}_all [ -r ${depends}_auto ] && ${__cat} ${depends}_auto >> ${depends}_all # Are there any deps we should ignore? if [ -n "$ignore_deps" ]; then local j local cmd for j in $ignore_deps do cmd="$(echo $j | ${__sed} -e 's;\.;\\\.;g')" ${__gsed} -i "/$cmd/d" ${depends}_all done fi if [ -r ${depends}_all ]; then while read ss reqpkg reqvers do havedep=0 if [ "$reqvers" == "auto" ]; then # auto create depend on $reqpkg # Check if it's an internal depend # There's no real safe way to check but we will assume # That if there's only a single . in the $reqpkg then it's internal local deplen=$((${#reqpkg}-1)) # String length -1 (a single dot) # Now if $deplen is longer than the same string with all dots removed # then we know there was more than one dot and we can assume it's # not an internal depend if [ $deplen -gt "$(/bin/echo -n "$reqpkg" | ${__tr} -d '.' | wc -c)" ]; then # External depend # Grab version nver="$($SHOWPRODS -n $reqpkg | ${__grep} $reqpkg | ${__awk} '{ print $3 }')" req="$reqpkg $nver maxint" havedep=1 else nver=$(fix_ver "$version-$pkgver") req="$pkgname.$reqpkg $nver $nver" havedep=1 fi else # When rebuilding a package we want to avoid the autodeps # from adding deps on the already installed parts. # Internal deps must be handled in depends with the auto keyword # or chaos will ensue. # We will try to check if the package name in the autodep matches the # package we're building if [ ! "${reqpkg%%.*}" == "$pkgname" ]; then req="$reqpkg $reqvers" havedep=1 else echo "skipping depend: $ss $reqpkg $reqvers" fi fi # Only increment and update arrays if we actually add the dep if [ $havedep -gt 0 ]; then reqs[$reqidx]=$ss reqp[$reqidx]=$req let "reqidx = $reqidx + 1" fi done < ${depends}_all fi } # fetch_replaces(): Fetch information about subsystem replacements # params: none # fetch_replaces() { local reqidx=0 if [ -r ${replaces} ]; then while read ss replpkg reqvers do if [ "$reqvers" == "auto" ]; then reqvers="0 maxint" # Replace all versions of a subsystem fi replacess[$reqidx]=$ss replacepkg[$reqidx]="$replpkg $reqvers" let "reqidx = $reqidx + 1" done < ${replaces} fi } # fetch_updates(): Fetch information about subsystem updates # params: none # fetch_updates() { local reqidx=0 if [ -r ${updates} ]; then while read ss updpkg reqvers do if [ "$reqvers" == "auto" ]; then reqvers="0 maxint" # Update all versions of a subsystem fi updatess[$reqidx]=$ss updatepkg[$reqidx]="$updpkg $reqvers" let "reqidx = $reqidx + 1" done < ${updates} fi } # fetch_ops(): Fetch ops # params: none # Populates the firstop and lastop variables # and the opfiles and opscript arrays fetch_ops() { if [ -r $opsfile ]; then opsidx=0 while read optype op do case $optype in 'firstop') firstop="$op" ;; 'lastop') lastop="$op" ;; esac opfiles[$opsidx]=$optype opscript[$opsidx]=$op let "opsidx = $opsidx + 1" done < $opsfile 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.*/\1/p'`; do echo "strip_bin: $f" ${__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.*/\1/p'`; do echo "strip_shared: $f" ${__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 echo "strip_static: $f" ${__strip} $strip_static_args $f done } ################################## # "external" functions ################################## # create_idb(): Create the .idb file # params: none # Create idb file and insert any firstop/lastops # Note that parse_def does most of the work. create_idb() { fetch_ops parse_def local temp # hackish - FIXME perhaps? local pcpos=${#pc[@]} # First vacant position in the subsys list array $pc if [ -d "${stagedir}${metainstalldir}src" ]; then # We have a srcdir which means we have patches, so add them to the idb file add_files "${metaprefix}src" opt.src - root sys "" pc[$pcpos]="opt.src" let "pcpos = pcpos + 1" fi # We unconditionally assume that relnotes are installed now that we # always use the global template as a fallback in auto_rel local relmetadir=${stagedir}${metainstalldir}relnotes/$topdir-$version-$pkgver ${__mkdir} -p $relmetadir echo "" > ${relmetadir}/${topdir}.txt add_files "${metaprefix}relnotes" opt.relnotes - root sys "" pc[$pcpos]="opt.relnotes" let "pcpos = pcpos + 1" # spec & idb files are added unconditionally pc[$pcpos]="opt.dist" # Add entries for the spec & idb files (opt.dist), they will be installed later, after they've actually been created echo "f 0644 root sys ${metainstalldir:1}dist/$topdir-$version-$pkgver/$topdir.idb ${metaprefix}dist/$topdir-$version-$pkgver/$topdir.idb ${pkgname}.opt.dist" >>$idbfile echo "f 0644 root sys ${metainstalldir:1}dist/$topdir-$version-$pkgver/$topdir.spec ${metaprefix}dist/$topdir-$version-$pkgver/$topdir.spec ${pkgname}.opt.dist" >>$idbfile echo "${metaprefix}dist/$topdir-$version-$pkgver/$topdir.idb" >> $metadir/files.tmp echo "${metaprefix}dist/$topdir-$version-$pkgver/$topdir.spec" >> $metadir/files.tmp # Go through each subsys and add any missing dir entries # This must go here, after the idb file is created and before # doing the final sort on the idb file. if [ $useautodir -eq 1 ]; then for temp in $(${__awk} '{ print $7 }' $idbfile | ${__sort} -u) do auto_dir $temp done fi ${__sort} +4u -6 < $idbfile > $metadir/idbtemp lines=$(wc -l < $metadir/idbtemp) if [ ! -z "$firstop" ]; then echo "$(head -1 $metadir/idbtemp) $firstop" > $metadir/idbtemp2 tail +2 $metadir/idbtemp >> $metadir/idbtemp2 else mv $metadir/idbtemp $metadir/idbtemp2 fi if [ ! -z "$lastop" ]; then let "lines=$lines - 1" echo "$(head -$lines $metadir/idbtemp2)" > $idbfile echo "$(tail -1 $metadir/idbtemp2) $lastop" >> $idbfile else mv $metadir/idbtemp2 $idbfile fi ${__rm} -f $metadir/idbtemp $metadir/idbtemp2 } # create_spec(): Create the .spec file. # params: none # Uses name, pkgname & pkgver variables # Iterate through pctop and for each iteration find # all entries in pc belonging to that image # create_spec() { fetch_imageconf fetch_subsysdesc fetch_depends fetch_replaces [ $useupdates -eq 1 ] && fetch_updates spec_header $pkgname "$name $version-${pkgver}${shortdesc}" > $specfile local pcsize=${#pc[@]} local pctopsize=${#pctop[@]} local reqidlist for ((i=0; i < $pctopsize; i++)) do local pcidx=0 spec_img_header ${pctop[$i]} "${pdtop[$i]}" $version-$pkgver >> $specfile while [ "$pcidx" -lt "$pcsize" ] do rv=`${__expr} match "${pc[$pcidx]}" ''${pctop[$i]}\\\.''` if [ ! "$rv" -eq 0 ]; then # We got a hit! spec_subsys_header ${pctop[$i]} `echo ${pc[$pcidx]}|${__cut} -d . -f 2` "${pd[$pcidx]}" "${ps[$pcidx]}" >> $specfile # Add 'replaces' statements spec_subsys_replaces self >> $specfile replacepkgsize=${#replacepkg[@]} if [ "$replacepkgsize" -ge 1 ]; then # Atleast one replaces statement needed for ((j=0; j < $replacepkgsize; j++)) do if [ "${replacess[$j]}" = "${pc[$pcidx]}" ]; then spec_subsys_replaces "${replacepkg[$j]}" >> $specfile fi done fi # Add 'updates' statements updatepkgsize=${#updatepkg[@]} if [ "$updatepkgsize" -ge 1 ]; then # Atleast one updates statement needed for ((j=0; j < $updatepkgsize; j++)) do if [ "${updatess[$j]}" = "${pc[$pcidx]}" ]; then spec_subsys_updates "${updatepkg[$j]}" >> $specfile fi done fi # Find 'prereq' statements reqsize=${#reqs[@]} unset reqidlist # Zero the array reqidlidx=0 for ((j=0; j < $reqsize; j++)) do if [ "${reqs[$j]}" == "${pc[$pcidx]}" ]; then reqidlist[$reqidlidx]=$j let "reqidlidx=$reqidlidx + 1" fi done # Add 'prereq' statements reqidlsize=$reqidlidx if [ "$reqidlsize" -ge 1 ]; then spec_subsys_req_header >> $specfile for ((j=0; j < $reqidlsize; j++)) do id=${reqidlist[$j]} spec_subsys_req "${reqp[$id]}" >> $specfile done spec_subsys_req_footer >> $specfile fi spec_subsys_footer >> $specfile fi let "pcidx = $pcidx + 1" done spec_img_footer >> $specfile done spec_footer >> $specfile } # make_dist(): Create inst image # params: none # Run gendist to create the instimage make_dist() { if [ "$1" == "shortroot" ]; then error $E_ARG_OBSO make_dist fi local sbase=${stagedir}${topinstalldir} local disttmp=/tmp/disttmp$$ ${__mkdir} $disttmp local dfile=$(_upls $distfile) $GENDIST $GENDIST_OPTS -rbase $topinstalldir -sbase $sbase -idb $idbfile -spec $specfile -dist $disttmp setdir $disttmp ${__vtar} -cf $distdir/$dfile $pkgname* setdir stage ${__rm} -rf $disttmp echo "Done. Package was created as $dfile" } # 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 index=0 local found=0 local i=0 local equalindex="" 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 fi ;; *) equalindex=$(expr index "$line" "\=") if [ $equalindex -ne 0 ]; then case "${line:0:(($equalindex-1))}" in 'pkgname') pkgname="$(_upls ${line:$equalindex:${#line}})" ;; 'name') name="$(_upls ${line:$equalindex:${#line}})" ;; 'pkgver') pkgver="$(_upls ${line:$equalindex:${#line}})" ;; 'subsys') subsys="$(_upls ${line:$equalindex:${#line}})" found=0 for i in ${pc[@]} # If $subsys is already there then don't add it again do if [ "$i" = "$subsys" ]; then found=1 break # It's already there so skip out fi done if [ $found -eq 0 ]; then pc[$index]=$subsys let "index = $index + 1" fi ;; 'shortdesc') shortdesc="$(_upls ${line:$equalindex:${#line}})" if [ ! -z "$shortdesc" ]; then shortdesc=" - $shortdesc" fi ;; esac else # Perhaps we hit 'files'? if [ "${line:0:5}" == "files" ]; then triplet="${line:6:((${#line}-5-2))}" defaultperms=$(_upls $(echo $triplet | ${__awk} -F, '{ print $1 }')) defaultuid=$(_upls $(echo $triplet | ${__awk} -F, '{ print $2 }')) defaultgid=$(_upls $(echo $triplet | ${__awk} -F, '{ print $3 }')) foundfiles=1 else if [ $foundfiles -eq 1 ]; then # We already found the 'files' line so this must be the filelist if [ "${line:0:5}" == "hide " ]; then specattr="nohist" line=${line:5} fi if [ "${line:0:4}" == "dir " ]; then add_dir "${line:4}" $subsys $defaultperms $defaultuid $defaultgid # Add dir entry to idb file else add_files "$line" $subsys $defaultperms $defaultuid $defaultgid "$specattr" # Build idb file from filespec fi specattr="" # Reset special attribute 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 ${__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 } # auto_src(): Automatically place any patches and srcfiles into the stagedir # params: none # Grabs the original source and any patches and shoves them into # ${metainstalldir}src/$topdir-$version-$pkgver for adding to the opt.src subsystem auto_src() { local distsrcdir="${stagedir}${metainstalldir}src/$topdir-$version-$pkgver" # Add patches local numpatch=${#patch[@]} local pnum=0 if [ "$numpatch" -gt 0 ]; then ${__mkdir} -p $distsrcdir for ((pnum=0; pnum < $numpatch; pnum++)) do 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]=$(get_source_absfilename ${patch[$pnum]}) fi # We are now sure that $patch[$pnum] contains file with absolute path if [ -r ${patch[$pnum]} ]; then # file is readable echo "Copying patch[$pnum] - ${patch[$pnum]}" ${__cp} -p ${patch[$pnum]} $distsrcdir else error $E_BAD_FILE patch fi else echo "Patch $pnum has empty filename" fi done fi # Add sourcecode if [ $include_source -eq 1 ]; then ${__mkdir} -p $distsrcdir local numsource=${#source[@]} local snum=0 for ((snum=0; $snum < $numsource; snum++)) do local absfile=$(get_source_absfilename ${source[$snum]}) ${__cp} -p $absfilename $distsrcdir done fi } # rel_conf_sub(): Put configure_args into the relnotes template # params: none # The set_configure_args command will call this function to # substitute %%CONFIGURE%% in the relnotes template at the # time of expansion. rel_conf_sub() { local rn local i for i in relnotes relnotes.${_os} do [ -r ${metadir}/${i} ] && rn=$i done # Duplicated code from auto_rel :( # compute configure info for relnotes local cf="$(_upls $configure_args)" [ -n "$ac_overrides" ] && local aco="$(echo $ac_overrides | ${__tr} ' ' '\n' | ${__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%\\*}" # end if [ -r ${metadir}/${rn} ]; then ${__sed} -e "s;%%CONFIGURE%%;$fullcf;g" \ ${metadir}/${rn} > ${metadir}/${rn}.txt fi } # set_configure_args(): Stuff new arguments into configure_args # params: $1 = configure arguments # If you want non-default configure_args put into relnotes # automatically, then use this function to set them instead # of overriding the configure_args variable directly. set_configure_args() { configure_args="$1" rel_conf_sub } # identify_compiler(): This outputs information about the compiler # params: $1 = { log } # This generates the compiler information used in relnotes and logging identify_compiler() { local mycc if [ $mipspro -eq 0 ]; then [ -n "$CC" ] && mycc=$CC || mycc=gcc [ "$1" = "log" ] && $mycc -v local compiler="$($mycc -v 2>&1 | ${__sed} -n '/^gcc/p')" else # not gcc if [ "$_os" = "irix53" ]; then local compiler="Irix 5.3 IDO" else local compiler="$(cc -version 2>&1)" fi if [ "$CXX" = "g++" ]; then # SGI cc with gnu g++ local compiler_temp="$(g++ -v 2>&1 | ${__sed} -n '/^gcc/ s/gcc/g++/p')" local compiler="$((echo $compiler; echo $compiler_temp) | ${__awk} '{ printf "%s\\n",$0 }')" local compiler="${compiler%\\*}" fi fi [ -z "$1" ] && echo "$compiler" } # auto_rel(): Fix up and add releasenotes to stagedir # params: none # 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 i local rn local my_ac_overrides="$platform_ac_overrides $ac_overrides" for i in relnotes relnotes.${_os} relnotes.txt relnotes.${_os}.txt; do [ -r ${metadir}/${i} ] && rn=${metadir}/${i} done if [ -z ${rn} ]; then echo "auto_rel: Using global relnotes template" rn=$buildpkgscripts/relnotes.template.irix fi local relmetadir=${stagedir}${metainstalldir}relnotes/$topdir-$version-$pkgver # compute configure info for relnotes local cf="$(_upls $configure_args)" [ -n "$my_ac_overrides" -a $no_configure -eq 0 ] && local aco="$(for ar in $my_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%\\*}" # end local pkgnam_temp=$(${__grep} 'pkgname=' $metadir/pkgdef) local pkgnam=$(_upls ${pkgnam_temp#pkgname=*}) local vendor_temp=$(${__grep} 'pkgvendor=' $metadir/pkgdef) local vendor=$(_upls ${vendor_temp#pkgvendor=*}) local packager="${pkgedby} <${email}>" # Compute SHA1 sums for all source entries local snum local path local file local source_sha1sum local temp_source_sha1sum="" for ((snum=0; $snum < ${#source[@]}; snum++)) do path="$(get_source_path ${source[$snum]})" file="$(get_source_filename ${source[$snum]})" (cd "$path"; ${__sha1sum} "$file") >> $metadir/sums done [ -r "$metadir/sums" ] && temp_source_sha1sum="$(cat $metadir/sums | ${__awk} '{ printf "%s\\n",$0 }')" source_sha1sum="${temp_source_sha1sum%\\*}" # End of SHA1 sum computing 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%\\*}" if [ -r ${depends}_all ]; then local temp_deps="$(${__cat} ${depends}_all | ${__grep} -v $pkgnam | ${__grep} $pkgprefix | ${__sed} -e "s/.*${pkgprefix}//" | ${__cut} -d. -f1 | ${__sort} -u | ${__awk} '{ printf "%s\\n",$0 }')" else local temp_deps="" fi 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%%;$(identify_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/${topdir}.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}$ $metadir/ChangeLog)" ]; then error $E_MISSING_CHGLOGV auto_rel fi echo >> "$relmetadir/${topdir}.txt" cat $metadir/ChangeLog >> "$relmetadir/${topdir}.txt" else error $E_MISSING_CHGLOG auto_rel fi } # 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 # Currently there's no way to tell what would be the right # permissions and uid/gid for auto_dir added directories. # These are good defaults, if there are directories that need specific # permissions or uid/gid then they should be added to the pkgdef file # instead. local autodir_perms="755" local autodir_uid="root" local autodir_gid="sys" local fdirs local ddirs local i local j fdirs=$(${__grep} $secname $idbfile | ${__awk} '/^[fl]/ { print $6 }' | ${__sed} -e 's,\(.*\)/.*$,\1,' | ${__sort} -u) ddirs=$(${__grep} $secname $idbfile | ${__awk} '/^d/ { print $6 }' | ${__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)" add_dir "$path_comp" ${secname#.*} $autodir_perms $autodir_uid $autodir_gid # Add dir entry echo "auto_dir: Adding $path_comp for $secname" fi done done } # auto_dist(): Add idb & spec files to stagedir # params: none # This will copy the newly created idb & spec files to # the stagedir under ${metainstalldir}dist/$topdir-$version-$pkgver auto_dist() { local distmetadir=${stagedir}${metainstalldir}dist/$topdir-$version-$pkgver ${__mkdir} -p $distmetadir ${__cp} $idbfile $distmetadir ${__cp} $specfile $distmetadir } # dep_pkg_name: Given a filename it will look it up and find the subsystemname # Params: A list of filenames # Uses the showfiles cache to find the subsystemnames that the input filenames # belong to. dep_pkg_name() { local pkg while read files do for i in $files do [ -L "$i" -a $deps_resolve_symlinks -eq 1 ] && i=$(${__readlink} -f "$i") pkg=$(${__grep} " ${i:1}$" $showfilescache 2>/dev/null) if [ -n "$pkg" ]; then #echo "Found $i in $pkg" >> /tmp/depdebug echo "$pkg" fi done done } # extract_deps: Given a subsystem it will extract the dependencies # params: $1 = subsystem name (like tgc_xxx.sw.lib) # It goes through the idb file and finds all the files # associated with a given subsystem. It will then compute # the dependencies and return the package names for the dependencies. extract_deps() { # Can't use setdir since it has output cd ${stagedir}${topinstalldir} # Grab the filelist and classify files local filelist=$(${__grep} $1 $idbfile | ${__awk} '{ print $6 }') local exelist=$(echo $filelist | ${__xargs} ${__file} | ${__egrep} -v ":.* (commands|script) " | ${__grep} ":.*executable" | ${__cut} -d: -f1) local scriptlist=$(echo $filelist | ${__xargs} ${__file} | ${__egrep} ":.* (commands|script) " | ${__cut} -d: -f1) local liblist=$(echo $filelist | ${__xargs} ${__file} | ${__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 Irix ldd # ${__ldd} $f | ${__grep} \= | ${__awk} -F' ' '{ print $3 }' | ${__cut} -d\ -f2 # Ariel Faigons perl5 ldd ${__ldd} $f | ${__grep} \= | ${__grep} -v 'not found' | ${__sed} -e 's/.*=> //g' done | ${__sort} -u | dep_pkg_name | ${__awk} '{ print $4 }' | ${__sort} -u fi # Compute dependencies for dynamic libraries if [ -n "$liblist" ]; then for f in $liblist; do [ -r $f ] || continue # Generic Irix ldd #${__ldd} $f | ${__grep} \= | ${__awk} -F' ' '{ print $3 }' | ${__cut} -d\ -f2 # Ariel Faigon's perl5 ldd ${__ldd} $f | ${__grep} \= | ${__grep} -v 'not found' | ${__sed} -e 's/.*=> //g' done | ${__sort} -u | dep_pkg_name | ${__awk} '{ print $4 }' | ${__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 | ${__awk} '{ print $4 }' | ${__sort} -u fi } # auto_deps(): Compute dependencies # params: none # This will go through the idb file and identify the subsystems. # It will then call extract_deps() to get the packagenames of the # dependencies. The dependencies will be added to $metadir/depends_auto. auto_deps() { local i local j local deps local subsystems # Populate showfiles cache $SHOWFILES -l > $showfilescache subsystems="$(${__awk} '{ print $7 }' < $idbfile | ${__sort} -u | ${__grep} sw)" for i in $subsystems do deps="$(extract_deps $i)" for j in $deps do echo "${i#*.} $j $($SHOWPRODS -n $j | ${__grep} $j | ${__awk} '{ print $3 }') maxint" done done | ${__sort} -u | grep $pkgprefix > ${depends}_auto rm -f $showfilescache } # run_configure(): Do the configure part of the build stage # params: none # run_configure() { local my_ac_overrides="$platform_ac_overrides $ac_overrides" #eval "$my_ac_overrides ./configure $(_upls $configure_args)" local acvar for acvar in $my_ac_overrides do export $acvar done $__configure $(_upls $configure_args) if [ $check_ac -gt 0 ]; then local out="$(check_ac warn $configlog)" if [ -n "$out" ]; then echo $out error $E_BAD_LIBS run_configure fi fi } # 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). generic_pack() { if [ "$1" == "shortroot" ]; then error $E_ARG_OBSO generic_pack fi clean meta if [ -d ${stagedir}${prefix}/${_mandir} ]; then setdir "${stagedir}${prefix}/${_mandir}" [ "$symlinkman" -eq 1 ] && symlink_man [ "$catman" -eq 1 ] && fix_man [ "$gzman" -eq 1 -o "$compressman" -eq 1 -o "$packman" -eq 1 ] && compress_man fi if [ -d ${stagedir}${prefix}/${_infodir} ]; then setdir "${stagedir}${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. setdir ${stagedir}${topinstalldir} # 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}/" auto_src # Add any patches create_idb auto_deps create_spec auto_rel # Fix up and add releasenotes auto_dist # Add idb & specfiles to stagedir check_unpackaged make_dist } # Simple helpers for build.sh irix53() { [ "$_os" = "irix53" ]; } irix62() { [ "$_os" = "irix62" ]; } irix65() { [ "$_os" = "irix65" ]; } # vim: set filetype=sh : # # vim: set sts=4 : # # vim: set shiftwidth=4 : #