diff options
Diffstat (limited to 'scripts/pkg-0.7.0')
-rwxr-xr-x | scripts/pkg-0.7.0 | 1928 |
1 files changed, 1928 insertions, 0 deletions
diff --git a/scripts/pkg-0.7.0 b/scripts/pkg-0.7.0 new file mode 100755 index 0000000..889a034 --- /dev/null +++ b/scripts/pkg-0.7.0 @@ -0,0 +1,1928 @@ +#!/bin/bash + +# pkg - Formilux package builder - version 0.7.0 - 2005-10-04 +# +# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau +# mailto: benoit@ant-computing.com,willy@ant-computing.com +# +# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt ) + +######## Please update this version ######## +PKG_VERSION=0.7.0 +############################################ + +## WARNING ## +# This version is not compatible with pkg scripts written for pre-0.2.0 versions + +# Usage: +# pkg <action> [ pkg [ pkg2 ] ] +# +# pkg newpkg [ new_pkg [ old_pkg ] ] +# [new_pkg]=[old_pkg] +# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1 +# pkg newpkg apache apache-1.3 +# pkg newpkg bash +# pkg newpkg gcc gcc-3*flx*.1 +# +# pkg setpkg [ new_pkg ] +# ex: pkg setpkg openssl-0.9.6g-flx0.1 +# +# pkg { info | cat | edit | unpack } [ pkg ] +# ex: pkg info +# pkg info bash +# pkg edit modutils-2.4 +# pkg cat gzip-1.3 +# +# pkg { compile,build,prepack,strip,pack,delpack,release,clean }* +# +# pkg { patch | unpatch } [ patch_name ] +# +# pkg { any_command } [ any_args ] +# + +# don't return stupid names, and we also want dotfiles and use extended globbing +shopt -s nullglob +shopt -s dotglob +shopt -s extglob + +# disable pathnames expansion +set -o noglob + +# change the default mask to avoid common security problems +umask og-w + +# set some constants +KERNDIR=${KERNDIR:-/usr/src/linux} +FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')} +FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)} +FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS} + +# FLXTARGARCH can be influenced by FLXARCH if defined +FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS} +FLXTARGARCH=${FLXTARGARCH:-$FLXARCH} +FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH} +FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS} +FLXARCH=${FLXARCH:-$FLXTARGARCH} + +DEVROOT=${DEVROOT:-/var/flx-dev} +PKGROOT=${PKGROOT:-/var/flx-pkg} +# use -p1 by default to apply a patch +PATCH_LEVEL=${PATCH_LEVEL:-1} +# the suffix that we use to name different builds. It also matches build +# versions with this name followed by a number (BUILDVER) +BUILDSFX=${BUILDSFX:-flx} +BUILDVER=${BUILDVER:-0} + +PKGSUFF="tgz" +CFGSUFF="cfg" +INSTNAME=".flxdisk" +LINKNAME=".flxpkg" + +FIND_CMD=pkgfilefind +CURDIR="$(pwd)" + +FILE_LIST= + +# all the directories that should be ignored by do_pack +EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm ) + +###### +###### here are some undertermined type functions +###### + +# check that this utility's version is at least as high as the version +# specified in $1. Returns 0 if OK, 1 if inferior. + +function check_pkg_version { + local version="$1" + local major minor patch + local mymajor myminor mypatch + + major=${version%%.*} + minor=${version#$major.}; minor=${minor%%.*} + patch=${version##*.} + + mymajor=${PKG_VERSION%%.*} + myminor=${PKG_VERSION#$mymajor.}; myminor=${myminor%%.*} + mypatch=${PKG_VERSION##*.} + + if [ -n "$major" ]; then + [ "$mymajor" -gt "$major" ] && return 0 + [ "$mymajor" -lt "$major" ] && return 1 + else + return 0 + fi + + if [ -n "$minor" ]; then + [ "$myminor" -gt "$minor" ] && return 0 + [ "$myminor" -lt "$minor" ] && return 1 + else + return 0 + fi + + if [ -n "$patch" ]; then + [ "$mypatch" -gt "$patch" ] && return 0 + [ "$mypatch" -lt "$patch" ] && return 1 + else + return 0 + fi + return 0 +} + + +# find packageable files (that can't be automaticaly created) and return only +# their relative path to the argument. + +function pkgfilefind { + local start=${1%%/} + local dir + local -a exclude_args=( ) + + for dir in "${EXCLUDE_LIST[@]}"; do + exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" ) + done + + find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n" +} + + +# resolves a symlink to an absolute location. +# usage: resolve_link <link_dir> <link_pointer> +function resolve_link { + # prints $1 if $2 is empty, and prints $2 if it starts with a '/'. + if [ -z "$2" ]; then + dir="$1" + elif [ -z "${2##/*}" ]; then + dir="$2" + else + dir="$1/$2" + fi + + # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right, + # then enclose with '/' + while [ -n "$dir" ]; do + if [ -z "${dir##./*}" ]; then dir="${dir#./}" + elif [ -z "${dir##/*}" ]; then dir="${dir#/}" + elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}" + elif [ -z "${dir%%*/}" ]; then dir="${dir%/}" + elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}" + elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}" + else + dir="/$dir/" + break; + fi + done + + # now resolve '/../' from left to right only. + while [ -z "${dir##*/../*}" ]; do + # if dir goes past root, we must truncate it + if [ -z "${dir##/../*}" ]; then + dir="/${dir##/../}" + else + # turn all '/x/../' into '/' + odir="$dir" + dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')" + [ "$dir" = "$odir" ] && break + fi + done + + [ "$dir" = "/" ] || dir="${dir#/}" + [ "$dir" = "/" ] || dir="${dir%/}" + echo "$dir" +} + +# this function analyses an ELF executable and prints its name along with some +# informations such as : +# %N:soname : for libraries, their soname +# %D:libname : library it depends on (their soname) +# %P:provide : feature provided by a library, in the form soname/version +# %R:require : required feature, in the for soname/version +function elf_get_dep { + local elf + for elf in "$@"; do + $OBJDUMP -p "$elf" | ( + soname_str="" + soname="" + needed="" + provide="" + require="" + curreq="" + section="" + while read; do + case "$REPLY" in + Dynamic\ Section*) + section="dynamic" ;; + Version\ defin*) + section="definitions" ;; + Version\ Refer*) + section="references" ;; + *) + set -- $REPLY + if [ "$section" = "dynamic" ]; then + if [ "$1" = "NEEDED" ]; then + needed="${needed:+$needed }%D:$2" + elif [ "$1" = "SONAME" ]; then + soname="$2" + soname_str="${soname_str:+$soname_str }%N:$2" + fi + elif [ "$section" = "definitions" ]; then + if [ "$#" = "4" -a "$2" = "0x00" ]; then + provide="${provide:+$provide }%P:$soname/$4" + fi + elif [ "$section" = "references" ]; then + if [ "$#" = "3" -a "$1" = "required" ]; then + curreq="${3%:}" + elif [ "$#" = "4" ]; then + require="${require:+$require }%R:$curreq/$4" + fi + fi + ;; + esac + done + echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}" + ) + done + return 0 +} + + +###### +###### here are some functions for manipulating package names +###### + +# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg' +function get_pkg_radix { + echo ${1%%[-_][0-9]*} +} + +# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a' +function get_pkg_ver { + local ver=${1#${1%%[_-][0-9]*}[._-]} + ver=${ver%-${BUILDSFX}*} + [ "$ver" = "$1" ] || echo $ver +} + +# returns the build number from a package name when appropriate, or empty when +# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12' +function get_build_num { + local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg + build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12 + build=${build#-} # flx0.12 + [ "$build" != "$1" ] && echo $build +} + +# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13' +function get_next_build { + local prefix=${1%%.*} + local suffix=${1##*.} + echo $prefix.$[$suffix + 1] +} + +# This function accepts a list of versionned names, and returns them sorted by +# version number. The names must NOT contain any '|' or '~' character, or they +# will be discarded. Names that don't have any version are also discarded. +# Note: package names can be full path names. +function sortnames { + local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION + local base version rest filename i t file flist + local -a list + + # a numeric versions consists in a series of numbers delimited by dots, and + # optionnally ending with one or several dots, so that strange namings are + # correctly processed. An alphanumeric version consists in everything that + # cannot match a numeric version, optionnaly ending with one or more dots. + IFS=$'\n' + FIELD='\([^|]*\)' + NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)' + ALPHA_VERSION='\([^0-9~|.]\+[.]*\)' + VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)" + + # make the list appear in the form 'package|version|rest|full_name' + list=($(echo "$*" | grep -v "|~" | sed -e "s,$VERSION,\1|," \ + -e "s,^$FIELD|$VERSION,\1|\2|," \ + -e "s,^$FIELD|$FIELD|$FIELD$,\1|\2|\3~\1\2\3," \ + -e "s,^[^|]*|[^|]*$,," \ + -e 's,^[^|]*/,,')) + + # there's a risk that it doesn't complete for all the list, and that some + # elements keep a "rest". But what can we do about it ? + + # we loop on the list if there's at least one element + # this will build alternating series of numeric-only and non-numeric + # substrings, packed by six. + while [ "${list[0]}" ] ; do + # now we add sub-version delimiters ',' + list=( $(for file in ${list[*]} ; do + IFS="|~" ; set -- $file + base=$1 ; version=$2 ; rest=$3 ; filename=$4 + if [ -z "$rest" ] ; then + IFS="." ; set -- $version + # we append a dot to the version for sed below. + echo "$base,$1,$2,$3,$4,$5,$6|.~$filename" + continue + fi + IFS="." ; set -- $version + echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename" + done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/")) + IFS=$'\n' + # and we stop once everyone has "|\.|~" (no rest) + if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi + done + + # now construct a field separator list for 'sort'. Since it's full of bugs, + # the only way for it to work is -k1,1 -k2,2n -k3,3n ... + # To match most cases, we'll assume that most of our packages will be + # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating). + IFS=',' ; i=1 ; flist= + for t in ${list[0]%%|*} ; do + if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then + flist="$flist${flist:+ }-k$i,$i" + else + flist="$flist${flist:+ }-k$i,$i"n + fi + i=$[$i+1]; + done + + IFS=$'\n'$'\t'' ' + # Do not use '-u' since sort is stupid enough to remove nearly identical + # lines ! + #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~ + echo "${list[*]}" | sort -t , $flist | cut -f2 -d~ +} + + +###### +###### here are some "exported" functions used to ease file manipulation +###### + +# +# usage: set_perm uid:gid mode file... +function set_perm { + local own mode + [ $# -gt 2 ] || return 1 + own=$1 ; shift + mode=$1 ; shift + chown $own "$@" + chmod $mode "$@" + return 0 +} + +# +# usage: set_default_perm $ROOTDIR/start_dir +function set_default_perm { + local start_dir=$1 + local strip_dir=${ROOTDIR%%/} + local type executable script + + if [ -z "$1" ]; then + echo; echo "### ERROR! set_default_perm called without arguments !!!" + echo "### You must specify the root directory to fix." + return 1 + fi + + echo + echo "PKG : Fixing permissions in $1 ... " + echo " Please wait..." + echo " Fixing directories..." + + # first pass : check directories + find $start_dir -type d | while read; do + case "${REPLY##$strip_dir}" in + /|/.) + set_perm root:root 755 "$REPLY" + ;; + /sbin|/sbin/init.d|/usr/sbin) + set_perm root:adm 751 "$REPLY" + ;; + /root) + set_perm root:root 700 "$REPLY" + ;; + /etc/formilux|/var/core) + set_perm root:adm 750 "$REPLY" + ;; + *) + if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then + set_perm root:root 755 "$REPLY" + fi + ;; + esac + done + + echo " Fixing special files..." + # second pass : check special files (block, char, fifo) + find $start_dir -not -xtype d -a -not -xtype f | while read; do + if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then + set_perm root:root 600 "$REPLY" + fi + done + + echo " Fixing regular files..." + # third pass : check regular files + find $start_dir -type f | while read; do + if [ -u "$REPLY" -o -g "$REPLY" ]; then + # remove other r/w on setuid/setgid + chmod o-rw "$REPLY" + else + type=$(file -z "$REPLY") + executable=0 + script=0 + + if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \ + -z "${type//*ERROR: Corrupt*/}" ]; then + executable=1 + elif [ -z "${type//*script*/}" ]; then + script=1 + fi + + #echo "processing ${REPLY##$strip_dir}" + case "${REPLY##$strip_dir}" in + /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*) + if [ $executable -gt 0 ]; then + set_perm root:adm ug-w,o-rw "$REPLY" + elif [ $script -gt 0 ]; then + set_perm root:adm ugo-w "$REPLY" + else + set_perm root:adm ugo-w "$REPLY" + fi + ;; + /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*) + if [ $executable -gt 0 ]; then + set_perm root:adm u-sw,g-wx,o-rwx "$REPLY" + elif [ $script -gt 0 ]; then + set_perm root:adm u-sw,g-swx,o-rwx "$REPLY" + else + # neither an exec nor a script, no need to execute it ! + set_perm root:adm ug-swx,o-wx "$REPLY" + fi + ;; + /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\ + /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*) + set_perm root:adm ug-sw,o-w,+x "$REPLY" + ;; + /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao]) + set_perm root:adm ugo-swx "$REPLY" + ;; + /etc/profile.d/*.var) + set_perm root:adm 0644 "$REPLY" + ;; + /etc/profile.d/*) + set_perm root:adm 0755 "$REPLY" + ;; + /boot/*/*|/boot/*|/etc/*/*) + set_perm root:adm ug-swx,o-rwx "$REPLY" + ;; + /etc/*) + set_perm root:adm ugo-swx "$REPLY" + ;; + /*/man/*) + set_perm root:man ugo-swx "$REPLY" + ;; + /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*) + set_perm root:man ugo-swx "$REPLY" + ;; + /usr/share/examples/*|/usr/share/examples/*/*) + set_perm root:man ugo-swx "$REPLY" + ;; + *) + # chgrp adm if not setgid and group==root + # chmod ugo-w if user==root + ;; + esac + fi + done + echo "PKG : done fixing permissions." +} + +###### +###### here are "exported" functions, which can be used and redefined by build.cfg +###### + +# builds everything from a clean start +function do_build { + local ACTION + # ACTION will be inherited by other functions + for ACTION in clean compile prepack strip pack ; do + declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; } + declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; } + declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; } + done + return 0 +} + +# this function returns one exact package name from a list of potentially +# interesting ones, classed from higher preference to lower. They are all +# passed as strings, constituting packages names, or some of the following +# special names : +# %P => use current directory as the source for the name +# %L => use the package pointed to by the ${LINKNAME} link +# %D => use the default package +# If several packages match a given pattern, the user is asked to select the +# desired one. +# The resulting package name is returned in REPLY, and the package directoryy +# is returned in PKGDIR whenever possible. +function get_name { + local pattern pkg_name + local radix ver build + local -a rel_list dev_list sort_list + local i search_dir + + REPLY= + for pattern in $*; do + search_dir= + if [ "$pattern" = "%P" ]; then + search_dir="${CURDIR%/*}" ; search_dir="/${search_dir#/}" + pattern="$(basename $CURDIR)" + elif [ "$pattern" = "%L" ]; then + if [ -r ".flxpkg/Version" ]; then + REPLY="$(cat .flxpkg/Version)" + REPLY="${REPLY##*/}" + PKGDIR="$CURDIR/.flxpkg/." + return + elif [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then + # the link is always an EXACT name, so we return it as-is. + pattern="$(readlink ${LINKNAME})" + PKGDIR="$pattern/." + REPLY="${pattern##*/}" + return + else + continue + fi + elif [ "$pattern" = "%D" ]; then + pattern=default + fi + radix=$(get_pkg_radix $pattern) + ver=$(get_pkg_ver $pattern) + build=$(get_build_num $pattern) + pkg_name=${radix:-*}-${ver:-*}-${build:-*} + + REPLY= + # we loop until pkg_name is empty, which allows recursive choices. + while [ "$pkg_name" ]; do + # now we'll try to build a list of potentially matching packages for + # each pattern. We'll reduce the original name until either we have + # a non-empty list or the package name is void. + rel_list=( ); dev_list=( ) + while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do + rel_list=( $(find ${search_dir:+$search_dir/} $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) ) + if [ "$release_only" != "1" ]; then + dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) ) + fi + + if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then + radix=$(get_pkg_radix $pkg_name) + ver=$(get_pkg_ver $pkg_name) + build=$(get_build_num $pkg_name) + + if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then + if [ "$build" -a "$build" != "*" ]; then + pkg_name=${radix}-${ver}-* + elif [ "${ver%.*}" != "$ver" ]; then + # let's reduce the version precision + pkg_name=${radix}-${ver%.*}-* + else + pkg_name=${radix}-* + fi + else + break + fi + else + break + fi + done + + # we're prepared to break the big loop, unless someone sets pkg_name again. + pkg_name= + sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) ) + + # if we matched nothing, we jump to the next pattern, and if we matched + # exactly one result, we return it immediately. + if [ ${#sort_list[*]} -eq 0 ]; then + continue + elif [ ${#sort_list[*]} -eq 1 ]; then + REPLY="${sort_list[0]}" + PKGDIR="${REPLY/*}" + REPLY="${REPLY##*/}" + return + fi + + # now, we'll present the possible names to the user. + i=0 + printf " %5d : - None of the following packages -\n" 0 + while [ $i -lt ${#sort_list[*]} ]; do + # we'll display an 'R' in front of released names, or a 'D' for dev. + # FIXME : we risk a wrong match here (eg: flx0.1 <-> flx0.10) + if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then + printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/} + else + printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/} + fi + i=$[$i+1] + done + echo + + while : ; do + echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i + if [ -z "$i" ]; then + # empty string, we use the last choice which is the preferred one. + i=${#sort_list[*]} + REPLY="${sort_list[$[$i-1]]}" + PKGDIR="${REPLY/*}" + REPLY="${REPLY##*/}" + return + elif [ "${i//[0-9]/}" ]; then + # not a plain integer, we'll allow to recursively re-select + #pattern=${pattern}*${i} + pattern=${i} + radix=$(get_pkg_radix $pattern) + ver=$(get_pkg_ver $pattern) + build=$(get_build_num $pattern) + pkg_name=${radix:-*}-${ver:-*}-${build:-*} + break; + elif [ $i -le 0 ]; then + # if the user explicitly replied "0", then he wants other choices. + break; + elif [ $i -le ${#sort_list[*]} ]; then + REPLY="${sort_list[$[$i-1]]}" + PKGDIR="${REPLY/*}" + REPLY="${REPLY##*/}" + return + fi + done + # we get here only either if someone tries to refine the package name or + # if he refuses these ones. + done + done + PKGDIR="${REPLY/*}" + REPLY="${REPLY##*/}" +} + +# choose a package and make ${LINKNAME} point to it +function do_setpkg { + rm -f ${LINKNAME} + ln -s $PKGDIR ${LINKNAME} +} + + +# look for existing packages, and propose a new version for the current one +function do_newpkg { + local -a rel_list dev_list sort_list + local pkg_name new_name + local radix ver build + + set -o noglob + if [ -e ${LINKNAME} ]; then + if [ -L ${LINKNAME} ]; then + if [ -d ${LINKNAME}/. ]; then + echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually." + exit 1 + else + rm -f ${LINKNAME} + fi + else + echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually." + exit 1 + fi + fi + + if [ $# -gt 0 ]; then + # the user has specified an explicit version string + # either it's the complete name, or it's the complete name followed + # by an '=' sign preceding the old name. + new_name=${1%%=*} + if [ $# -gt 1 ]; then + pkg_name=$2 + elif [ "$new_name" != "$1" ]; then + pkg_name=${1##*=} + fi + fi + + if [ -z "$new_name" ]; then + # the user has not specified any version string, we'll use the directory + # name. + new_name=$(basename $CURDIR) + fi + + rel_list=( ); dev_list=( ) + + # now we'll have to guess the new package name. + # The build rev part (flx*.*) will be ignored. + # We'll look for existing packages with the exact + # name+version, and if found, use this + the first unused build number. + # If not found, a new package is created with the exact name and flx0.1 + + radix=$(get_pkg_radix $new_name) + ver=$(get_pkg_ver $new_name) + build=$(get_build_num $new_name) + new_name=${radix:-*}-${ver:-*} + + rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) ) + dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) ) + sort_list=(${rel_list[*]} ${dev_list[*]}) + + if [ "${sort_list[*]}" ]; then + sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) ) + sort_list=( $(sortnames ${sort_list[*]}) ) + if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \ + ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then + # if the package was properly named, and not already listed, let's + # propose it on last position. + sort_list=( ${sort_list[*]} $new_name ) + fi + # echo "package_list : ${sort_list[*]}" + + # now, we'll present the possible names to the user + if [ ${#sort_list[*]} -gt 1 ]; then + local i=0 + echo; echo ">>> Please select the name of the package to create :";echo + while [ $i -lt ${#sort_list[*]} ]; do + # we'll display an 'R' in front of released names, 'P' + # in front of packaged ones, or a 'D' for dev. + if [ -e "${sort_list[$i]}/RELEASED" ]; then + printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/} + elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then + printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]##*/} + else + printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/} + fi + i=$[$i+1] + done + + echo + while : ; do + echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i + if [ -z "$i" ]; then + new_name=${sort_list[${#sort_list[*]}-1]} + break + elif [ "${i//[0-9]/}" ]; then + # not a plain integer, we'll take it for the new name + new_name=$i + break; + elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then + new_name=${sort_list[$[$i-1]]} + break; + fi + done + else + new_name=${sort_list[0]} + fi + # we'll search for all packages starting with the same name and version + # in both release and dev dirs. Then we'll be able to deduce the latest + # build number used. + #sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) ) + sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%p\n" 2>/dev/null|sort -u) ) + if [ ${#sort_list[*]} -eq 0 ]; then + # this can happen with new BUILDSFX/BUILDVER + new_name=${new_name}-${BUILDSFX}${BUILDVER}.1 + else + sort_list=( $(sortnames ${sort_list[*]} )) + new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]})) + fi + else + if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then + echo "Error: no existing package matches $new_name, and wildcards" + echo "or incomplete names cannot be part of a real name." + exit 1 + fi + # we keep new_name since it's syntactically correct + new_name=${new_name}-${BUILDSFX}${BUILDVER}.1 + fi + + #echo "new_name: $new_name" + + # if pkg_name is unspecified, we'll use the current directory name to guess + # the source package, else we'll use the explicit name + echo; echo ">>> Please select the package to use as a reference :"; echo + + get_name $pkg_name $new_name %P %D + + if [ -z "$REPLY" ]; then + echo "No reference package found (even default). Please specify one." + exit 1 + fi + + echo "Using '$REPLY'." + + if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then + pkg_name=$PKGROOT/$REPLY + else + pkg_name=$DEVROOT/$REPLY + fi + + # new_name is always relative to DEVROOT + #echo "new_name: $new_name ; old_name: $(basename $pkg_name)" + + # we should verify that new_name/released doesn't exist before extracting + # anything into it, or even that new_name doesn't exist at all. + new_name=$DEVROOT/$new_name + if [ -e $new_name ]; then + echo "Error! new directory $new_name already exists. Refusing to overwrite." + exit 1 + fi + + rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \ + tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \ + --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \ + --exclude='./Version' --one-file-system -cpf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME}) + chmod u+rw $new_name/build.cfg + + echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'." + echo "The link '${LINKNAME}' now points to it." + echo + if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then + echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***" + echo + fi + set +o noglob + return 0 +} + + +function do_edit { + if [ -e "$PKGDIR/RELEASED" ]; then + echo "Editing $CFGFILE in read-only mode..." + vi -R $CFGFILE + else + echo "Editing $CFGFILE..." + vi $CFGFILE + fi +} + +function do_cat { + cat $CFGFILE +} + +function do_lst { + local FPNAME + + FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH + cat $FPNAME.lst +} + +function pre_info { + echo "Information for package '${EXACTPKG##*/}' (\${EXACTPKG##*/}) :" + + echo " Package name : $PKGRADIX (\$PKGRADIX)" + echo " Package version : $PKGVER (\$PKGVER)" + echo " Distrib version : $DISTVER (\$DISTVER)" + echo -n " Config. file : " + if [ -e $CFGFILE ]; then + echo "$CFGFILE" + else + echo "none found." + fi + echo " Package file : $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF" + echo -n " Package size : " + if [ -e $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF ]; then + echo "$(du -b $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF |cut -f1) bytes." + else + echo "does not exist yet." + fi + if [ -n "${PATCH_LIST}" ]; then + echo " Patches list : ${PATCH_LIST}" + else + echo " Empty patch list." + fi + + if [ -e "$PKGDIR/ChangeLog" ]; then + echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)" + else + echo " No ChangeLog." + fi + + if [ -e "$PKGDIR/RELEASED" ]; then + echo " Tagged as RELEASED" + else + echo " UNRELEASED." + fi + + return 0 +} + +# does only compile, not changing the current config +function do_compile_only { + $FLXMAKE + return $? +} + +# new simplified name for 'config_only', which is deprecated, not changing current scripts. +function do_config { + if declare -f do_config_only >/dev/null 2>&1; then + do_config_only + return $? + else + return 0 + fi +} + +# configures and compiles +function do_compile { + ( do_config ) && ( do_compile_only ) +} + +# preparatory work for prepack() +function pre_prepack { + if [ "$UID" != "0" -a "$force" != "1" ]; then + echo "You must specify '--force' to install as non-root" + exit 1 + fi + # WARNING! here, we don't use $ROOTDIR because we don't want to risk + # erasing a wrong directory as root ! + [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}" + # permissions are important here because we don't want to get an + # inherited setgid or something alike on the root dir + [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chown 0:0 $ROOTDIR; chmod 0755 $ROOTDIR; } + #mkdir -p "$EXAMPLEDIR" + return 0 +} + +# build link in /opt directory +# INPUT: selected path to creation in /opt +function build_opt { + local dir + + if [ -d $ROOTDIR/opt ] ; then ( + [ $# = 0 ] && set -- bin sbin lib + set +o noglob + shopt -s nullglob + cd $ROOTDIR/opt + for dir in $* ; do + mkdir $dir + dirs=( */$dir ) + [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n" + done + ) fi + return 0 +} + +# deletes the current prepack directory. +function do_delpack { + # WARNING! here, we don't use $ROOTDIR because we don't want to risk + # erasing a wrong directory as root ! + [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}" + return 0 +} + +# does a full clean +function do_clean { + make distclean || make mrproper || make clean + ( do_delpack ) + return 0 +} + +# applies all the patches to the current sources +# files which match *.rej and *~ will be deleted +function do_patch { + local i + find . -name '*.rej' -o -name '*~' | xargs rm -f + + for i in ${PATCH_LIST}; do + [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz" + if [ -z "${i##*.gz}" ]; then + gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL + else + patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i + fi + done + + if [ -z "$(find . -name '*.rej')" ]; then + find . -name '*~' | xargs rm -f + fi + return 0 +} + +# reverts all the patches from the current sources +# files which match *.rej and *~ will be deleted +function do_unpatch { + local i + local UNPATCH_LIST="" + + find . -name '*.rej' -o -name '*~' | xargs rm -f + + for i in ${PATCH_LIST}; do + UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} ) + done + + for i in ${UNPATCH_LIST[@]}; do + [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz" + if [ -z "${i##*.gz}" ]; then + gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL + else + patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i + fi + done + + if [ -z "$(find . -name '*.rej')" ]; then + find . -name '*~' | xargs rm -f + fi + return 0 +} + +# extracts a binary package into $ROOTDIR, to reflect the state prior to pack(). +function do_unpack { + local FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF + mkdir -p $ROOTDIR + cd $ROOTDIR + + echo -n "Extracting $FILE into $ROOTDIR ... " + tar zUxpf $FILE >/dev/null 2>&1 + echo "done." + return 0 +} + +# strips symbols from executables before building the package. +# Abort if ROOTDIR doesn't exist (thus needing prepack() first). +function do_strip { + if [ ! -d $ROOTDIR ] ; then + echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'." + exit 1 + fi + #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1 + # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped + find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1 + return 0 +} + +# forces pack() to strip before starting, even if do_pack() is redefined by the user. +function pre_pack { + # in the mean time, we avoid removing this directory since it could have + # been brought legally by an authorized package. + #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null + ( do_strip ) + return 0 +} + +# this function finds perl dependencies for a given file. +# It's only called from _do_pack_files() and do_pack() +function get_perl_depend { + local filename=$1 + local dep DEP + local DEP_FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.dep + + DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \ + sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \ + -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \ + sed 's@::@/@g') + if [ "x$DEP" != "x" ] ; then + echo -n "$filename" >> $DEP_FILE + for dep in $DEP ; do + if [ "x${dep/*.*}" != "x" ] ; then + echo -n " $dep.pm" >> $DEP_FILE + else + echo -n " $dep" >> $DEP_FILE + fi + done + echo >> $DEP_FILE + fi +} + +# same as pack, except that it uses files in the current directory as the root +# entries, and that no strip, link nor compression is performed. +# Only entries listed in the files pointed to by $* find their way to the archive. +# This function relies on get_perl_depend(). +function _do_pack_files { + local DEP_FILE FPNAME ext + local FILE_LIST=$* + + echo -n "Updating timestamps ... " + find . -not -type l | xargs touch -m + echo "done." + + # full path name of different files + FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH + DEP_FILE=$FPNAME.dep + + rm -rf $DEP_FILE + if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi + + echo -n "Creating $DEP_FILE ... " + touch $DEP_FILE + ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do + case $REPLY in + *.pm|*.pl|*.ph) + get_perl_depend $REPLY + ;; + */man/man*/*.[0-9n]) + echo "$REPLY \$MAN" >> $DEP_FILE + ;; + */info/*.info|*/info/*.info-[0-9]*) + echo "$REPLY \$INFO" >> $DEP_FILE + ;; + bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*) + flr="$(file $REPLY)" + case "$flr" in + *\ shell\ *) + echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE + ;; + *perl\ commands*) + echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE + get_perl_depend $REPLY + ;; + *:\ symbolic\ link*) + echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE + ;; + *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*) + elf_get_dep $REPLY >> $DEP_FILE + ;; + *\ ELF\ [0-9][0-9]-bit\ *shared\ object*) + elf_get_dep $REPLY >> $DEP_FILE + ;; + esac + ;; + esac + done + echo "done." + + echo -n "Creating $FPNAME.lst ... " + # we try the special case of the '.' entry which is needed to set the root permissions. + # this entry must be set as "." in FILE_LIST. + if grep -q '^.[ ]' $FILE_LIST; then + set -- $(grep '^.[ ]' $FILE_LIST) + owner=${2%%:*} + group=${2##*:} + echo "d $3 $owner $group 0 -------------------------------- 0 ." + fi > $FPNAME.lst + (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1 + echo "done." + + echo -n "Creating $FPNAME.$PKGSUFF ... " + + # we want everything, including directories. + cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null + + # create shortcuts ".*" for tgz, dep and lst files + for ext in dep lst tgz; do + rm -f $PKGDIR/.$ext + ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext + done + echo "done." + return 0 +} + + +# packs the prepacked files into a new file located in $DEVROOT. +# any eventual old package is removed. +# this function relies on _do_pack_files(), get_perl_depend(), +function do_pack { + local DEP_FILE FPNAME + local FILE_LISTS ext + + # normalize the list with an absolute path for each entry + for file in $FILE_LIST ; do + if [ -z "${file##/*}" ]; then + FILE_LISTS="$FILE_LISTS $file" + else + FILE_LISTS="$FILE_LISTS $CURDIR/$file" + fi + done + # FIXME: is this normal ??? + if [ ! -d "$ROOTDIR" ] ; then + echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR" + exit 1 + fi + cd $ROOTDIR + + # use the file list when available + if [ "$FILE_LISTS" ]; then + _do_pack_files $FILE_LISTS + return $? + fi + +## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \ +## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \ +## ldconfig -nr . ) > /dev/null 2>&1 + + echo -n "Updating libraries ... " + ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1 + echo "done." + + echo -n "Updating timestamps ... " + find . ! -type l | xargs touch -m + echo "done." + + # full path name of different files + FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH + DEP_FILE=$FPNAME.dep + + # rebuild dependencies file, first is a diff file + echo -n "Creating $DEP_FILE ... " + rm -rf $DEP_FILE + if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi + + # build a one shot function 'add' to add dependences + oldadd="$(declare -f add)" + # usage: add file [...] need file [...] + function add { + local file files + # remove file + while [ $# -gt 0 -a "x$1" != xneed ] ; do + files=( "$1" "${files[@]}" ) + shift + done + [ $# -le 1 ] && return + shift + for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done + } + # load dependences function + declare -f load_deps > /dev/null && ( load_deps ) + # reset 'add' function + unset add + # reload old one + [ -n "$oldadd" ] && eval "$oldadd" + + touch $DEP_FILE + find . \( -type f -o -type l \) -printf "%P\n" | while read ; do + case $REPLY in + *.pm|*.pl|*.ph) + get_perl_depend $REPLY + ;; + */man/man*/*.[0-9n]) + if [ "${REPLY/*gz}" ] ; then + if [ -L $REPLY ] ; then + LINK=$(readlink $REPLY) + rm $REPLY + ln -s $LINK.gz $REPLY.gz + else + gzip -f -9 $REPLY + chmod 644 $REPLY.gz + fi + fi + echo "$REPLY \$MAN" >> $DEP_FILE + ;; + */info/*.info|*/info/*.info-[0-9]*) + if [ "${REPLY/*gz}" ] ; then + gzip -f -9 $REPLY + chmod 644 $REPLY.gz + fi + echo "$REPLY \$INFO" >> $DEP_FILE + ;; + bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*) + flr="$(file $REPLY)" + case "$flr" in + *\ shell\ *) + echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE + ;; + *perl\ commands*) + echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE + get_perl_depend $REPLY + ;; + *:\ symbolic\ link*) + echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE + ;; + *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*) + elf_get_dep $REPLY >> $DEP_FILE + ;; + *\ ELF\ [0-9][0-9]-bit\ *shared\ object*) + elf_get_dep $REPLY >> $DEP_FILE + ;; + esac + ;; + esac + done + echo "done." + + echo -n "Creating $FPNAME.lst ... " + ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1 + echo "done." + + echo -n "Creating $FPNAME.$PKGSUFF ... " + # we want everything, and directories only if they're empty. + # All this without './' we shouldn't get an empty line since . + # should contain at least what we want to tar ! + $FIND_CMD . | tar --no-recursion -T - --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null + + # create shortcuts ".*" for tgz, dep and lst files + for ext in dep lst tgz; do + rm -f $PKGDIR/.$ext + ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext + done + echo "done." + return 0 +} + + +# this function prepares all needed variables to work in a cross-compiler environment +function set_cross_environment { + # Handling of cross-compilers : + # - setting CC will force both HOSTCC and FLXCROSSCC + # - setting HOSTCC will keep it + # - setting FLXCROSS will set CC + # - setting FLXCROSSCC will set CC whatever FLXCROSS is. + + if [ -z "$FLX_CROSS_OPT_SET" ]; then + CC=${CC:-gcc} + CXX=${CXX:-g++} + AS=${AS:-as} + LD=${LD:-ld} + AR=${AR:-ar} + NM=${NM:-nm} + RANLIB=${RANLIB:-ranlib} + STRIP=${STRIP:-strip} + OBJDUMP=${OBJDUMP:-objdump} + + HOSTCC=${HOSTCC:-$CC} + HOSTCXX=${HOSTCXX:-$CXX} + HOSTAS=${HOSTAS:-$AS} + HOSTLD=${HOSTLD:-$LD} + HOSTAR=${HOSTAR:-$AR} + HOSTNM=${HOSTNM:-$NM} + HOSTSTRIP=${HOSTSTRIP:-$STRIP} + HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP} + + if [ -n "$FLXCROSS" ]; then + CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC} + CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX} + AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS} + LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD} + AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR} + NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM} + RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB} + STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP} + OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP} + fi + # specify that we don't want to do this again + FLX_CROSS_OPT_SET=1 + fi +} + +# this function sets all needed compiler options +function set_compiler_options { + # now we'll set default ARCH and CPU for the current FLXARCH if none is set. + case "$FLXARCH" in + i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;; + i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;; + i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;; + i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;; + parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;; + sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;; + sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;; + ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;; + *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;; + esac + + # FIXME: this should go into a per-architecture file + case "$FLXARCH" in + *86) + CC=${CC:-gcc} + CXX=${CXX:-g++} + FLX_ARCH_CURRENT="$FLXARCH" + FLX_ARCH_COMMON="i586" + FLX_ARCH_SMALL="$basearch" + GCC_ARCH_CURRENT="-march=$arch" + GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON" + GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL" + GCC_CPU_CURRENT="-mcpu=$cpu" + GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON" + GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL" + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0" + GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0" + if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps" + GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + fi + ;; + + parisc*) + CC=${CC:-gcc} + CXX=${CXX:-g++} + FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}" + FLX_ARCH_COMMON="1.0" + FLX_ARCH_SMALL="1.0" + GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT" + GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON" + GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL" + GCC_CPU_CURRENT="-mschedule=7100LC" + GCC_CPU_COMMON="-mschedule=7100" + GCC_CPU_SMALL="-mschedule=7100" + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -fno-align-jumps" + GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + ;; + + sparc*) + CC=${CC:-gcc} + CXX=${CXX:-g++} + FLX_ARCH_CURRENT="$FLXARCH" + FLX_ARCH_COMMON="$FLXARCH" + FLX_ARCH_SMALL="$FLXARCH" + GCC_ARCH_CURRENT="-mcpu=$arch" + GCC_ARCH_COMMON="-mcpu=$arch" + GCC_ARCH_SMALL="-mcpu=$arch" + GCC_CPU_CURRENT="-mtune=$cpu" + GCC_CPU_COMMON="-mtune=$cpu" + GCC_CPU_SMALL="-mtune=$cpu" + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -fno-align-jumps" + GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + ;; + + ev[456]*) + CC=${CC:-gcc} + CXX=${CXX:-g++} + FLX_ARCH_CURRENT="$FLXARCH" + FLX_ARCH_COMMON="$FLXARCH" + FLX_ARCH_SMALL="$FLXARCH" + GCC_ARCH_CURRENT="-mcpu=$arch" + GCC_ARCH_COMMON="-mcpu=$arch" + GCC_ARCH_SMALL="-mcpu=$arch" + GCC_CPU_CURRENT="-mtune=$cpu" + GCC_CPU_COMMON="-mtune=$cpu" + GCC_CPU_SMALL="-mtune=$cpu" + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -fno-align-jumps" + GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + ;; + + *) + CC=${CC:-gcc} + CXX=${CXX:-g++} + FLX_ARCH_CURRENT="$FLXARCH" + FLX_ARCH_COMMON="$FLXARCH" + FLX_ARCH_SMALL="$FLXARCH" + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -malign-jumps=0" + GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0" + if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then + GCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + GCC_OPT_FAST="-O2 -fno-align-jumps" + GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + fi + ;; + esac + + case "$FLXHOSTARCH" in + *86) + HOSTCC=${HOSTCC:-$CC} + HOSTCXX=${HOSTCXX:-$CXX} + HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0" + HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0" + if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then + HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps" + HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + fi + ;; + parisc*) + HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST" + HOSTCC_OPT_FAST="$GCC_OPT_FAST" + HOSTCC_OPT_SMALL="$GCC_OPT_SMALL" + ;; + + sparc*) + HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST" + HOSTCC_OPT_FAST="$GCC_OPT_FAST" + HOSTCC_OPT_SMALL="$GCC_OPT_SMALL" + ;; + + ev[456]*) + HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST" + HOSTCC_OPT_FAST="$GCC_OPT_FAST" + HOSTCC_OPT_SMALL="$GCC_OPT_SMALL" + ;; + + *) + HOSTCC=${HOSTCC:-$CC} + HOSTCXX=${HOSTCXX:-$CXX} + HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + HOSTCC_OPT_FAST="-O2 -malign-jumps=0" + HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0" + if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then + HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer" + HOSTCC_OPT_FAST="-O2 -fno-align-jumps" + HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels" + fi + ;; + esac + + export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL + export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG + export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL + export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL + export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL + export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL + + return 0 +} + +# displays used environment variables +function print_env { + set_cross_environment + set_compiler_options + for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \ + FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \ + FLXCROSS FLXTOOLDIR FLXROOTDIR \ + AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \ + GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \ + GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \ + GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \ + HOSTCC HOSTCXX \ + HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \ + FLXMAKE FLXPMAKE; do + echo "$i=$(eval echo \$$i)" + done + exit 0 +} + +function usage { + # this is needed to present current options to the user + set_cross_environment + set_compiler_options + + echo "PKG version $PKG_VERSION - Formilux package build utility." + echo "Usage:" + echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]" + echo + echo " pkg newpkg [ new_pkg [ old_pkg ] ]" + echo " pkg newpkg [ newpkg ]=[ old_pkg ]" + echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1" + echo " pkg newpkg =apache-1.3" + echo " pkg newpkg bash" + echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1" + echo + echo " pkg setpkg [ new_pkg ]" + echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1" + echo + echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]" + echo " ex: pkg info" + echo " pkg info bash" + echo " pkg edit modutils-2.4" + echo " pkg cat gzip-1.3" + echo + echo " pkg { clean | compile | config | compile_only | build }*" + echo " pkg { prepack | strip | pack | delpack | release }*" + echo + echo " pkg { patch | unpatch } [ patch_name ]" + echo + echo " pkg { any_command } [ any_args ]" + echo + echo "User variables are :" + echo "PKGROOT : directory containing released packages <$PKGROOT>" + echo "DEVROOT : directory containing unreleased packages <$DEVROOT>" + echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>" + echo "FLXARCH : architecture to use for the package, <$FLXARCH>" + echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>" + echo + echo "Architecture-specific variables :" + echo -e " CURRENT\t|COMMON\t|SMALL" + echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL" + echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL" + echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL" + echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST" + echo "GCC_OPT_FAST=$GCC_OPT_FAST" + echo "GCC_OPT_SMALL=$GCC_OPT_SMALL" + echo + echo "Use pkg --env to get all variables." + +# Those two are not user-settable anymore +# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>" +# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)" + exit 1 +} + +# displays usage +function do_help { + usage + return 0 +} + +# creates a new changelog entry and prompts the user to add information. +function do_changelog { + # Let's create a new changelog entry + (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME"; + echo ''; echo $'\t* '; echo ''; echo '.' ; + echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null + + # we'll ask the user to fill the changelog + vi -c ":3" $PKGDIR/ChangeLog + return 0 +} + +# marks the current package as released +function do_release { + local last_pkg + + echo "#####################################################" + echo "# Release command not implemented yet ! Aborting... #" + echo "#####################################################" + #exit 1 + # some important checks before things get wrong + if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then + echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !" + exit 1 + fi + + if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then + echo "Nothing to be released in this package." + echo "Please ensure that .lst, .dep and .tgz exist." + exit 1 + fi + + # first, the destination directory must not exist + if [ -d "$PKGROOT/${EXACTPKG##*/}" ]; then + if [ -e "$PKGROOT/${EXACTPKG##*/}/RELEASED" ]; then + echo "Error: This package already exists." + else + echo "Error: The package directory $PKGROOT/${EXACTPKG##*/} already exists." + fi + exit 1 + fi + + # identify last changelog entry + last_pkg="" + if [ -e "$PKGDIR/ChangeLog" ]; then + last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog") + last_pkg=${last_pkg##*released } + fi + + if [ "$last_pkg" != "$EXACTPKG" ]; then + # Let's create a new changelog entry + touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist + (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME"; + echo ''; echo $'\t'"* released $EXACTPKG"; + echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null + fi + + # we'll ask the user to fill the changelog + vi -c ":4" $PKGDIR/ChangeLog + +#<FIXME.WTA> +#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi +#</FIXME> + + if ! mv $PKGDIR $PKGROOT/ ; then + echo "Error: cannot move the package to the released directory. Cancelling." + # the mv here fails atomically, so nothing's lost in PKGDIR, but we have + # to clean a possible partial copy + rm -rf $PKGROOT/${EXACTPKG##*/} + exit 2 + fi + + touch $PKGROOT/${EXACTPKG##*/}/RELEASED + + return 0 +} + +# usage: install-files <owner> <perm> <dest> file... +# +function install-files { + local owner="$1" ; shift + local perm="$1" ; shift + local dst="$1" ; shift + local file + + [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}" + cp -dpfP "$@" "$ROOTDIR/$dst/" && \ + ( cd "$ROOTDIR/$dst" && chown -h $owner "${@##*/}" && chmod $perm "${@##*/}" ) + + [ -n "$FILE_LIST" ] && for file in "$@"; do echo "$dst/$file $owner $perm"; done >> $FILE_LIST +} + +# usage: install-file <owner> <perm> <file> <dest> +# +function install-file { + local owner="$1" ; shift + local perm="$1" ; shift + local src="$1" ; shift + local dst="$1" ; shift + + [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}" + if cp -dpfP "$src" "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst" \ + && [ ! -L "$ROOTDIR/$dst" ]; then chmod $perm "$ROOTDIR/$dst"; fi + + [ -n "$FILE_LIST" ] && echo $dst $owner $perm >> $FILE_LIST +} + +# usage: install-dir <owner> <perm> <dir>... +# +function install-dir { + local owner="$1" ; shift + local perm="$1" ; shift + local dst + + for dst in "$@"; do + mkdir -pm $perm "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst" + [ -n "$FILE_LIST" ] && echo $dst $owner $perm >> $FILE_LIST + done +} + +# usage: install-ln <owner> <target> <dest> +# +function install-ln { + local owner="$1" ; shift + local target="$1" ; shift + local dst="$1" ; shift + + [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}" + ln -s "$target" "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst" + [ -n "$FILE_LIST" ] && echo $dst $owner 000 >> $FILE_LIST +} + + +###### +###### here are some functions used only from main +###### + +function known_cmd { + declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; } + declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; } + declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; } + return 0 +} + + +###### +###### here is the main entry point +###### + +# scan the command line + +release_only=0 +force=0 +TESTGCC=0 +PRINTUSAGE=0 +PRINTENV=0 +ARGLIST=( ) +ACTION= +CHAINCMD=1 + +[ $# -eq 0 ] && PRINTUSAGE=1 + +while [ $# -gt 0 ] ; do + case "$1" in + --force ) + force=1 + ;; + --help|-h) + PRINTUSAGE=1 + ;; + --env|-e) + PRINTENV=1 + TESTGCC=1 + ;; + --rel|-r*) + release_only=1 + ;; + --) + shift + ARGLIST=(${ARGLIST[*]} $*) + break + ;; + -* ) + PRINTUSAGE=1 + ;; + *) + ARGLIST=(${ARGLIST[*]} "$1") + ;; + esac + shift +done + + +#echo "arglist=${ARGLIST[*]}" + +[ $PRINTENV -gt 0 ] && print_env +[ $PRINTUSAGE -gt 0 ] && usage +[ ${#ARGLIST[*]} -lt 1 ] && usage + +# Some actions can be chained, others not. we'll get the longest +# possible chain, and stop once we encounter a non-chainable action + +while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do + set -o noglob + ACTION=${ARGLIST[0]} + TESTGCC=0 + # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!! + ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash ! + + case "$ACTION" in + newpkg) + CHAINCMD=0 + KNOWNCMD=1 + # newpkg is the only command which doesn't start by a package lookup. + ;; + setpkg) + CHAINCMD=0 + KNOWNCMD=1 + get_name $1 %P default + ;; + info|edit|cat|unpack|changelog) + CHAINCMD=0 + KNOWNCMD=1 + get_name ${ARGLIST[0]} %L %P %D + [ -d "$PKGDIR" ] || PKGDIR= + ;; + patch|unpatch) + CHAINCMD=0 + KNOWNCMD=1 + if [ -r ".flxpkg/Version" ]; then + REPLY="$(cat .flxpkg/Version)" + REPLY="${REPLY##*/}" + PKGDIR="$CURDIR/.flxpkg/." + else + REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)" + PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)" + fi + # get_name %L + ;; + compile_only|config|config_only|compile|build) + KNOWNCMD=1 + if [ -r ".flxpkg/Version" ]; then + REPLY="$(cat .flxpkg/Version)" + REPLY="${REPLY##*/}" + PKGDIR="$CURDIR/.flxpkg/." + else + REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)" + PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)" + fi + TESTGCC=1 + # get_name %L + ;; + prepack|strip|pack|delpack|release|clean) + KNOWNCMD=1 + if [ -r ".flxpkg/Version" ]; then + REPLY="$(cat .flxpkg/Version)" + REPLY="${REPLY##*/}" + PKGDIR="$CURDIR/.flxpkg/." + else + REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)" + PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)" + fi + # get_name %L + ;; + *) + CHAINCMD=0 + KNOWNCMD=0 + if [ -r ".flxpkg/Version" ]; then + REPLY="$(cat .flxpkg/Version)" + REPLY="${REPLY##*/}" + PKGDIR="$CURDIR/.flxpkg/." + else + REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)" + PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)" + fi + # get_name %L + ;; + esac + + [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2 + + set +o noglob + if [ "$ACTION" != "newpkg" ]; then + if [ -z "$REPLY" ]; then + echo "Error: package name not found." + exit 1 + fi + EXACTPKG="$PKGDIR/$REPLY" + + if [ -z "$PKGDIR" ]; then + if [ -e "$PKGROOT/${EXACTPKG##*/}/build.cfg" ]; then + PKGDIR="$PKGROOT/${EXACTPKG##*/}" + else + PKGDIR="$DEVROOT/${EXACTPKG##*/}" + fi + fi + CFGFILE="$PKGDIR/build.cfg" + PKGRADIX="$(get_pkg_radix ${EXACTPKG##*/})" + PKGVER="$(get_pkg_ver ${EXACTPKG##*/})" + DISTVER="$(get_build_num ${EXACTPKG##*/})" + ROOTDIR="${ROOTDIR:-$CURDIR/${INSTNAME}}" + EXAMPLEDIR="${ROOTDIR}/usr/share/examples" + + # for compatibility with old functions. Not used anywhere outside this script. + packver="${EXACTPKG##*/}" + pack="$PKGRADIX" + fi + + set_cross_environment + set_compiler_options + + if [ "$ACTION" != "newpkg" ]; then + . $CFGFILE + fi + + # FLXMAKE is used for sequential make and FLXPMAKE for parallel make + FLXMAKE="${FLXMAKE:-make}" + FLXPMAKE="${FLXPMAKE:-$FLXMAKE}" + + export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST + +# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD" +# echo "ARGLIST=${ARGLIST[*]}" + + if [ $KNOWNCMD -gt 0 ]; then + known_cmd ${ARGLIST[*]} || exit 1 + else + if declare -f do_$ACTION >/dev/null; then + ( do_$ACTION ${ARGLIST[*]} ) || exit 1 + fi + fi + [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2 + + # now, we'll loop only if we were in a chainable action +done + +[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2 +exit 0 + |