#!/bin/bash # # makepkg - make packages compatable for use with pacman # # Copyright (c) 2002-2006 by Judd Vinet # Copyright (c) 2005 by Aurelien Foret # Copyright (c) 2006 by Miklos Vajna # Copyright (c) 2005 by Christian Hamar # Copyright (c) 2006 by Alex Smith # Copyright (c) 2006 by Andras Voroskoi # # 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # myver='3.0.3' startdir=$(pwd) BUILDSCRIPT="PKGBUILD" PKGEXT="pkg.tar.gz" source "/etc/abs/abs.conf" SRCROOT="$ABSROOT" # Options CLEANUP=0 CLEANCACHE=0 DEP_BIN=0 DEP_SRC=0 SUDO=0 FORCE=0 GENINTEG=0 INSTALL=0 NOBUILD=0 NODEPS=0 NOEXTRACT=0 RMDEPS=0 REPKG=0 LOGGING=0 PACMAN_OPTS= #determine if we are running with fakeroot if [ "$1" = "-F" ]; then INFAKEROOT=1 shift else INFAKEROOT=0 fi ### SUBROUTINES ### plain() { if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then echo -e " \033[1;1m$1\033[1;0m" >&2 else echo " $1" >&2 fi } msg() { if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then echo -e "\033[1;32m==>\033[1;0m \033[1;1m$1\033[1;0m" >&2 else echo "==> $1" >&2 fi } msg2() { if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then echo -e " \033[1;34m->\033[1;0m \033[1;1m$1\033[1;0m" >&2 else echo " -> $1" >&2 fi } warning() { if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then echo -e "\033[1;33m==> WARNING:\033[1;0m \033[1;1m$1\033[1;0m" >&2 else echo "==> WARNING: $1" >&2 fi } error() { if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then echo -e "\033[1;31m==> ERROR:\033[1;0m \033[1;1m$1\033[1;0m" >&2 else echo "==> ERROR: $1" >&2 fi } strip_url() { echo "$1" | sed 's|^.*://.*/||g' } # checks to see if options are present in makepkg.conf or PKGBUILD; # PKGBUILD options always take precedence check_option() { local needle=$(echo $1 | tr [:upper:] [:lower:]) local i # loop PKGBUILD opts first so it overrides makepkg.conf for i in ${options[@]}; do local lc=$(echo $i | tr [:upper:] [:lower:]) if [ "$lc" = "$needle" ]; then echo "y" return elif [ "$lc" = "!$needle" ]; then echo "n" return # START DEPRECATED # TODO This code should be removed in the next release of makepkg elif [ "$lc" = "no$needle" ]; then warning "Options beginning with 'no' will be depricated in the next version of makepkg!" plain "Please replace 'no' with '!': no$needle -> !$needle." echo "n" return elif [ "$lc" = "keepdocs" -a "$needle" = "docs" ]; then warning "Option 'keepdocs' may not work as intended. Please replace with 'docs'." # END DEPRECATED fi done # fall back to makepkg.conf options for i in ${OPTIONS[@]}; do local lc=$(echo $i | tr [:upper:] [:lower:]) if [ "$lc" = "$needle" ]; then echo "y" return elif [ "$lc" = "!$needle" ]; then echo "n" return fi done echo "unknown" return } # check if option is present in BUILDENV check_buildenv() { local needle=$(echo $1 | tr [:upper:] [:lower:]) local i # use options from makepkg.conf for i in ${BUILDENV[@]}; do local lc=$(echo $i | tr [:upper:] [:lower:]) if [ "$lc" = "$needle" ]; then echo "y" return elif [ "$lc" = "!$needle" ]; then echo "n" return fi done echo "unknown" return } in_array() { local needle=$1 shift 1 [ -z "$1" ] && return 1 for i in $*; do [ "$i" = "$needle" ] && return 0 done return 1 } checkdeps() { [ $# -gt 0 ] || return pmout=$(pacman $PACMAN_OPTS -T $*) ret=$? if [ $ret -eq 1 ]; then #unresolved deps local missingdeps=() for dep in $pmout; do # dep is considered resolved if it is one of the packages # that we are building if ! in_array $dep ${pkgs[@]}; then missingdeps=(${missingdeps[@]} ${dep}) fi done echo ${missingdeps[*]} elif [ $ret -ne 0 ]; then error "pacman returned a fatal error ($ret): $pmout" exit 1 fi } handledeps() { local missingdeps=0 local deplist="$*" local depstrip="" local striplist="" local haveperm=0 if [ \( "$EUID" = "0" -a "$INFAKEROOT" != "1" \) -o "$SUDO" = 1 ]; then haveperm=1 fi for dep in $deplist; do depstrip=$(echo $dep | sed 's|=.*$||' | sed 's|>.*$||' | sed 's|<.*$||') striplist="$striplist $depstrip" done if [ "$deplist" != "" -a $haveperm -eq 1 ]; then if [ "$DEP_BIN" = "1" -a "$SUDO" = "1" ]; then # install missing deps from binary packages (using pacman -S and sudo) msg "Installing missing dependencies..." if [ "$INFAKEROOT" = "1" ]; then # kinda hacky, but we need to make pacman think that we're NOT # in fakeroot so it will go ahead and install the dependencies. FAKEROOTKEY2=$FAKEROOTKEY unset FAKEROOTKEY fi sudo pacman $PACMAN_OPTS -S $striplist if [ $? -eq 1 ]; then error "Pacman failed to install missing dependencies." exit 1 fi if [ "$INFAKEROOT" = "1" ]; then export FAKEROOTKEY=$FAKEROOTKEY2 unset FAKEROOTKEY2 fi elif [ "$DEP_BIN" = "1" ]; then # install missing deps from binary packages (using pacman -S) msg "Installing missing dependencies..." pacman $PACMAN_OPTS -S $striplist if [ $? -eq 1 ]; then error "Pacman failed to install missing dependencies." exit 1 fi elif [ "$DEP_SRC" = "1" ]; then # install missing deps by building them from source. # we look for each package name in $SRCROOT and build it. if [ "$SRCROOT" = "" ]; then error "Source root cannot be found - please make sure it is specified in /etc/makepkg.conf" exit 1 fi # TODO: handle version comparators (eg, glibc>=2.2.5) msg "Building missing dependencies..." for dep in $striplist; do candidates=$(find $SRCROOT -type d -name "$dep") if [ "$candidates" = "" ]; then error "Could not find \"$dep\" under $SRCROOT" exit 1 fi success=0 for pkgdir in $candidates; do if [ -f "$pkgdir/$BUILDSCRIPT" ]; then cd "$pkgdir" if [ "$RMDEPS" = "1" ]; then PKGDEST="$PKGDEST" makepkg -i -c -b -r else PKGDEST="$PKGDEST" makepkg -i -c -b fi if [ $? -eq 0 ]; then success=1 break fi fi done if [ "$success" = "0" ]; then error "Failed to build \"$dep\"" exit 1 fi done else missingdeps=1 fi elif [ "$deplist" != "" -a $haveperm -eq 0 ]; then if [ "$DEP_SRC" = "1" -o "$DEP_BIN" = "1" ]; then warning "Cannot auto-install missing dependencies as a normal user without sudo!" plain "Run makepkg as root or with -S to resolve dependencies automatically." fi missingdeps=1 fi # rerun any additional sh scripts found in /etc/profile.d/ for i in /etc/profile.d/*.sh do if [ -x $i ]; then . $i &>/dev/null fi done return $missingdeps } resolvedeps() { deplist="" newdeplist="" deplist=$(checkdeps $*) if [ -n "${deplist}" ]; then handledeps $deplist if [ $? -eq 0 ]; then # check deps again to make sure they were resolved newdeplist=$(checkdeps $*) if [ -n "${newdeplist}" ]; then error "Failed to install all missing dependencies." fi else newdeplist="$deplist" fi fi # if new dep list is not empty, print the list if [ -n "${newdeplist}" ]; then msg "Missing Dependencies:" for dep in ${newdeplist}; do msg2 "${dep}" done return 1 else return 0 fi } # fix flyspray bug #5923 removedeps() { # runtimedeps and buildtimedeps are set when resolving deps local deplist="$runtimedeps $buildtimedeps" local depstrip="" local striplist="" for dep in $deplist; do depstrip=$(echo $dep | sed 's|=.*$||' | sed 's|>.*$||' | sed 's|<.*$||') striplist="$striplist $depstrip" done if [ "$RMDEPS" = "1" -a "$SUDO" = "1" -a -n "$deplist" ]; then msg "Removing installed dependencies..." if [ "$INFAKEROOT" = "1" ]; then export FAKEROOTKEY2=$FAKEROOTKEY unset FAKEROOTKEY fi sudo pacman $PACMAN_OPTS -Rs $striplist if [ "$INFAKEROOT" = "1" ]; then export FAKEROOTKEY=$FAKEROOTKEY2 unset FAKEROOTKEY2 fi elif [ "$RMDEPS" = "1" -a "$EUID" = "0" -a "$INFAKEROOT" != "1" -a -n "$deplist" ]; then msg "Removing installed dependencies..." pacman $PACMAN_OPTS -Rs $striplist fi } installpackage() { local pkgfiles="" for pkg in "${pkgs[@]}" do pkgfiles="${pkgfiles} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT}" done if [ "$INSTALL" = "1" -a "$SUDO" = "1" ]; then msg "Installing package with pacman -U..." if [ "$INFAKEROOT" = "1" ]; then FAKEROOTKEY2=$FAKEROOTKEY unset FAKEROOTKEY fi sudo pacman $PACMAN_OPTS -U ${pkgfiles} local exitcode=$? if [ "$INFAKEROOT" = "1" ]; then export FAKEROOTKEY=$FAKEROOTKEY2 unset FAKEROOTKEY2 fi exit $exitcode elif [ "$INSTALL" = "1" -a "$EUID" = "0" -a "$INFAKEROOT" != "1" ]; then msg "Installing package with pacman -U..." pacman $PACMAN_OPTS -U ${pkgfiles} exit $? fi } usage() { echo "makepkg version $myver" echo echo "Usage: $0 [options]" echo echo "Options:" echo " -b, --builddeps Build missing dependencies from source" echo " -c, --clean Clean up work files after build" echo " -C, --cleancache Clean up source files from the cache" echo " -d, --nodeps Skip all dependency checks" echo " -e, --noextract Do not extract source files (use existing src/ dir)" echo " -f, --force Overwrite existing package" echo " -g, --geninteg Generate integrity checks for source files" echo " -h, --help This help" echo " -i, --install Install package after successful build" echo " -L, --log Log package build process" echo " -m, --nocolor Disable colorized output messages" echo " -o, --nobuild Download and extract files only" echo " -p Use an alternate build script (instead of '$BUILDSCRIPT')" echo " -r, --rmdeps Remove installed dependencies after a successful build" # fix flyspray feature request #2978 echo " -R, --repackage Repackage contents of pkg/ without building" echo " -s, --syncdeps Install missing dependencies with pacman" echo " -S, --usesudo When calling pacman, use sudo" echo echo "These options can be passed to pacman:" echo echo " --noconfirm Do not ask for confirmation when resolving dependencies" echo " --noprogressbar Do not show a progress bar when downloading files" echo echo "If -p is not specified, makepkg will look for '$BUILDSCRIPT'" echo } ARGLIST=$@ #preserve environment variables _PKGDEST=${PKGDEST} _SRCDEST=${SRCDEST} #Source makepkg.conf; fail if it is not found if [ -f /etc/makepkg.conf ]; then source /etc/makepkg.conf else error "/etc/makepkg.conf not found. cannot continue" exit 1 fi #Source user-specific makepkg.conf overrides if [ -f ~/.makepkg.conf ]; then source ~/.makepkg.conf fi # override settings with an environment variable for batch processing PKGDEST=${_PKGDEST:-$PKGDEST} PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined SRCDEST=${_SRCDEST:-$SRCDEST} SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined while [ "$#" -ne "0" ]; do case $1 in # pacman --noconfirm) PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;; --noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;; # makepkg --clean) CLEANUP=1 ;; --cleancache) CLEANCACHE=1 ;; --syncdeps) DEP_BIN=1 ;; --usesudo) SUDO=1 ;; --builddeps) DEP_SRC=1 ;; --nodeps) NODEPS=1 ;; --noextract) NOEXTRACT=1 ;; --install) INSTALL=1 ;; --force) FORCE=1 ;; --nobuild) NOBUILD=1 ;; --nocolor) USE_COLOR="n" ;; --geninteg) GENINTEG=1 ;; --rmdeps) RMDEPS=1 ;; --repackage) REPKG=1 ;; --log) LOGGING=1 ;; --help) usage exit 0 ;; --*) usage exit 1 ;; -*) while getopts "bcCdefghiLmop:rRsS-" opt; do case $opt in b) DEP_SRC=1 ;; c) CLEANUP=1 ;; C) CLEANCACHE=1 ;; d) NODEPS=1 ;; e) NOEXTRACT=1 ;; f) FORCE=1 ;; g) GENINTEG=1 ;; h) usage exit 0 ;; i) INSTALL=1 ;; L) LOGGING=1 ;; m) USE_COLOR="n" ;; o) NOBUILD=1 ;; p) BUILDSCRIPT=$OPTARG ;; r) RMDEPS=1 ;; R) REPKG=1 ;; s) DEP_BIN=1 ;; S) SUDO=1 ;; -) OPTIND=0 break ;; *) usage exit 1 ;; esac done ;; *) true ;; esac shift done # check for sudo if [ "$SUDO" = "1" -a ! "$(type -p sudo)" ]; then error "Cannot find the sudo binary! Is sudo installed?" exit 1 fi if [ "$CLEANCACHE" = "1" ]; then #fix flyspray feature request #5223 if [ -n "$SRCDEST" -a "$SRCDEST" != "$startdir" ]; then msg "Cleaning up ALL files from $SRCDEST." echo -n " Are you sure you wish to do this? [Y/n] " read answer answer=$(echo $answer | tr [:upper:] [:lower:]) if [ "$answer" = "yes" -o "$answer" = "y" ]; then rm "$SRCDEST"/* if [ $? -ne 0 ]; then error "Problem removing files; you may not have correct permissions in $SRCDEST" exit 1 else # removal worked msg "Source cache cleaned." exit 0 fi else # answer = no msg "No files have been removed." exit 0 fi else # $SRCDEST is $startdir, two possibilities error "Source destination must be defined in makepkg.conf." plain "In addition, please run makepkg -C outside of your cache directory." exit 1 fi fi unset pkgname pkgver pkgrel pkgdesc url license groups provides md5sums force unset replaces depends conflicts backup source install build makedepends unset options noextract if [ ! -f $BUILDSCRIPT ]; then error "$BUILDSCRIPT does not exist." exit 1 #TODO this is an attempt at a generic way to unset all package specific #variables in a PKGBUILD #else # #this is fun.... we'll unset # for var in $(grep "=" $BUILDSCRIPT | sed "s|.*\(\<.*\>\)=.*|\1|g"); do # unset $var # done fi source $BUILDSCRIPT # check for no-no's in the build script if [ -z "$pkgver" ]; then error "pkgver is not allowed to be empty." exit 1 fi if [ -z "$pkgrel" ]; then error "pkgrel is not allowed to be empty." exit 1 fi if [ $(echo "$pkgver" | grep '-') ]; then error "pkgver is not allowed to contain hyphens." exit 1 fi if [ $(echo "$pkgrel" | grep '-') ]; then error "pkgrel is not allowed to contain hyphens." exit 1 fi if ! in_array $CARCH ${arch[@]}; then error "$pkgname is not available for the '$CARCH' architecture." plain "Note that many packages may need a line added to their $BUILDSCRIPT" plain "such as arch=('$CARCH')." exit 1 fi if [ "$install" -a ! -f "$install" ]; then error "install scriptlet ($install) does not exist." exit 1 fi # cache all the pkgnames that will be built. it'll come handy later. pkgs=(${pkgname}) if [ ! -z "$subpkgs" ]; then for subpkg in "${subpkgs[@]}" do pkgs=(${pkgs[@]} $(eval "echo \$pkgname_$subpkg")) done fi # check if all packages have already been built if [ "$FORCE" = "0" -a "$GENINTEG" = "0" ]; then allpkgsbuilt=1 for pkg in "${pkgs[@]}" do if [ ! -f "$PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT}" ]; then allpkgsbuilt=0 break fi done if [ "$allpkgsbuilt" = "1" ]; then if [ "$INSTALL" = "1" ]; then warning "all packages have already been built, installing existing packagess." installpackage exit $? else error "all packages have already been built. (use -f to overwrite)" exit 1 fi fi fi # Enter the fakeroot environment if necessary. This will call the makepkg # script again as the fake root user. We detect this by passing a sentinel # option (-F) to makepkg. if [ "$EUID" != "0" ]; then if [ "$(check_buildenv fakeroot)" = "y" ]; then if [ $(type -p fakeroot) ]; then msg "Entering fakeroot environment" fakeroot -- $0 -F $ARGLIST exit $? else warning "Fakeroot is not installed. Building as an unprivileged user" plain "will result in non-root ownership of the packaged files. Install" plain "the fakeroot package to correctly build as a non-root user." plain "" sleep 1 fi else warning "Running makepkg as an unprivileged user will result in non-root" plain "ownership of the packaged files. Try using the fakeroot environment" plain "by placing 'fakeroot' in the BUILDENV array in makepkg.conf." plain "" sleep 1 fi fi msg "Making package: $pkgname $pkgver-$pkgrel ($(date))" # fix flyspray bug #5973 if [ "$NODEPS" = "1" -o "$GENINTEG" = "1" -o "$NOBUILD" = "1" -o "$REPKG" = "1" ]; then if [ "$NODEPS" = "1" ]; then warning "skipping dependency checks" fi # skip printing a warning message for the others: geninteg, nobuild, repkg elif [ $(type -p pacman) ]; then deperr=0 # these two variables are needed later by removedeps unset runtimedeps buildtimedeps msg "Checking Runtime Dependencies..." resolvedeps ${depends[@]} ret=$? # deplist is a global variable set by resolvedeps runtimedeps="$deplist" if [ "$ret" != "0" ]; then deperr=1 fi msg "Checking Buildtime Dependencies..." resolvedeps ${makedepends[@]} ret=$? # deplist is a global variable set by resolvedeps buildtimedeps="$deplist" if [ "$ret" != "0" ]; then deperr=1 fi if [ $deperr -eq 1 ]; then error "could not resolve all dependencies." exit 1 fi else warning "pacman was not found in PATH. skipping dependency checks." fi cd "$startdir" # retrieve sources msg "Retrieving Sources..." mkdir -p src cd "$startdir/src" for netfile in ${source[@]}; do file=$(strip_url "$netfile") if [ -f "../$file" ]; then msg2 "Found $file in build dir" cp "../$file" . elif [ -f "$SRCDEST/$file" ]; then msg2 "Using cached copy of $file" cp "$SRCDEST/$file" . else # check for a download utility if [ -z "$FTPAGENT" ]; then error "FTPAGENT is not configured. Check the /etc/makepkg.conf file." msg "Aborting..." exit 1 fi ftpclient=$(echo $FTPAGENT | awk {'print $1'}) if [ ! -x "$ftpclient" ]; then error "ftpclient $(basename $ftpclient) is not installed." msg "Aborting..." exit 1 fi proto=$(echo "$netfile" | sed 's|://.*||') if [ "$proto" != "ftp" -a "$proto" != "http" -a "$proto" != "https" ]; then error "$netfile was not found in the build directory and is not a proper URL." msg "Aborting..." exit 1 fi msg2 "Downloading $file" $FTPAGENT "$netfile" # fix flyspray bug #3289 ftpret=$? if [ $ftpret -gt 0 ]; then error "Failure while downloading $file" msg "Aborting..." #rm "$file" exit 1 fi if [ -n "$SRCDEST" ]; then mkdir -p $SRCDEST && cp "$file" $SRCDEST if [ $? -ne 0 ]; then warning "You do not have correct permissions to cache source in $SRCDEST" cp "$file" .. fi else cp "$file" .. fi fi done if [ "$NOEXTRACT" = "1" -o "$REPKG" = "1" ]; then warning "Skipping source integrity checks -- using existing src/ tree" else # TODO we end up checking $GENINTEG 3 times, could probably be refactored if [ "$GENINTEG" = "1" ]; then msg "Generating checksums for source files" plain "" fi for integ in ${INTEGRITY_CHECK[@]}; do integ="$(echo $integ | tr A-Z a-z)" case "$integ" in md5) integrity_name="md5sum" ;; sha1) integrity_name="sha1sum" ;; sha256) integrity_name="sha256sum" ;; sha384) integrity_name="sha384sum" ;; sha512) integrity_name="sha512sum" ;; *) error "Invalid integrity algorithm '$integ' specified"; exit 1;; esac if [ ! $(type -p $integrity_name) ]; then error "Cannot find the $integrity_name program." exit 1 fi #Generate integrity checks if [ "$GENINTEG" = "1" ]; then ct=0 numsrc=${#source[@]} for netfile in "${source[@]}"; do file=$(strip_url "$netfile") sum=$(eval "$integrity_name '$file' | cut -d' ' -f 1") if [ $ct -eq 0 ]; then echo -n "${integrity_name}s=(" else indent=0 while [ $indent -lt $((${#integrity_name}+3)) ]; do echo -n " " indent=$(($indent+1)) done fi echo -n "'$sum'" ct=$(($ct+1)) if [ $ct -eq $numsrc ]; then echo ')' else echo fi done #Validate integrity checks else integrity_sums=($(eval echo \${${integrity_name}s[@]})) if [ ${#integrity_sums[@]} -eq ${#source[@]} ]; then msg "Validating source files with ${integrity_name}s" errors=0 idx=0 for netfile in "${source[@]}"; do file=$(strip_url "$netfile") echo -n " $file ... " >&2 echo "${integrity_sums[$idx]} $file" | $integrity_name -c - >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "FAILED" >&2 errors=1 else echo "Passed" >&2 fi idx=$(($idx+1)) done if [ $errors -gt 0 ]; then error "One or more files did not pass the validity check!" exit 1 fi else warning "Integrity checks ($integ) are missing or incomplete." fi fi done if [ "$GENINTEG" = "1" ]; then plain "" exit 0 fi fi #Extract sources if [ "$NOEXTRACT" = "1" -o "$REPKG" = "1" ]; then warning "Skipping source extraction -- using existing src/ tree" else msg "Extracting Sources..." for netfile in "${source[@]}"; do unziphack=0 file=$(strip_url "$netfile") if in_array "$file" ${noextract[@]}; then #skip source files in the noextract=() array # these are marked explicitly to NOT be extracted continue fi # fix flyspray #6246 file_type=$(file -biz "$file") unset cmd case "$file_type" in *application/x-tar*application/x-compress*) cmd="tar -xzf $file" ;; *application/x-tar*) cmd="tar -xf $file" ;; *application/x-zip*) unziphack=1 cmd="unzip -qqo $file" ;; *application/x-cpio*) cmd="bsdtar -x -f $file" ;; *application/x-gzip*) cmd="gunzip -d -f $file" ;; *application/x-bzip*) cmd="bunzip2 -f $file" ;; esac if [ "$cmd" != "" ]; then msg2 "$cmd" $cmd if [ $? -ne 0 ]; then # unzip will return a 1 as a warning, it is not an error if [ "$unziphack" != "1" -o $? -ne 1 ]; then error "Failed to extract $file" msg "Aborting..." exit 1 fi fi fi done if [ "$EUID" = "0" ]; then # chown all source files to root.root chown -R root.root "$startdir/src" fi fi if [ "$NOBUILD" = "1" ]; then msg "Sources are ready." exit 0 elif [ "$REPKG" = "1" ]; then warning "Skipping build" else # check for existing pkg directory if [ -d "$startdir/pkg" ]; then msg "Removing existing pkg/ directory..." rm -rf "$startdir/pkg" fi mkdir -p "$startdir/pkg" # check for existing subpkg directories too if [ ! -z "$subpkgs" ]; then for subpkg in "${subpkgs[@]}" do if [ -d "$startdir/pkg_$subpkg" ]; then msg "Removing existing pkg_$subpkg/ directory..." rm -rf "$startdir/pkg_$subpkg" fi mkdir -p "$startdir/pkg_$subpkg" done fi # use distcc if it is requested (check buildenv and PKGBUILD opts) if [ "$(check_buildenv distcc)" = "y" -a "$(check_option distcc)" != "n" ]; then [ -d /usr/lib/distcc/bin ] && export PATH=/usr/lib/distcc/bin:$PATH elif [ "$(check_option distcc)" = "n" ]; then # if it is not wanted, clear the makeflags too export MAKEFLAGS="" fi # use ccache if it is requested (check buildenv and PKGBUILD opts) if [ "$(check_buildenv ccache)" = "y" -a "$(check_option ccache)" != "n" ]; then [ -d /usr/lib/ccache/bin ] && export PATH=/usr/lib/ccache/bin:$PATH fi # clear user-specified makeflags if requested if [ "$(check_option makeflags)" = "n" ]; then export MAKEFLAGS="" fi # build msg "Starting build()..." # some applications (eg, blackbox) will not build with some languages unset LC_ALL LC_MESSAGES LANG umask 0022 # ensure CFLAGS and CXXFLAGS are used export CFLAGS export CXXFLAGS #check for "exit on syntax error" shell option echo $SHELLOPTS | grep errexit 2>&1 >/dev/null set_e=$? ret=0 if [ "$LOGGING" = "1" ]; then BUILDLOG="${startdir}/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log" if [ -f "$BUILDLOG" ]; then i=1 while true; do if [ -f "$BUILDLOG.$i" ]; then i=$(($i +1)) else break fi done mv "$BUILDLOG" "$BUILDLOG.$i" fi #use 'errexit' to bail on syntax error [ $set_e -eq 1 ] && set -e build 2>&1 | tee "$BUILDLOG"; ret=${PIPESTATUS[0]} [ $set_e -eq 1 ] && set +e else #use 'errexit' to bail on syntax error [ $set_e -eq 1 ] && set -e build 2>&1 || ret=$? [ $set_e -eq 1 ] && set +e fi if [ $ret -gt 0 ]; then error "Build Failed. Aborting..." removedeps exit 2 fi fi if [ "$(check_option docs)" = "n" ]; then # remove info/doc files msg "Removing info/doc files..." cd "$startdir/pkg" #fix flyspray bug #5021 rm -rf ${DOC_DIRS[@]} fi # move /usr/share/man files to /usr/man if [ -d $startdir/pkg/usr/share/man ]; then cd "$startdir" mkdir -p pkg/usr/man cp -a pkg/usr/share/man/* pkg/usr/man/ rm -rf pkg/usr/share/man fi # compress man pages msg "Compressing man pages..." find "$startdir"/pkg/{usr{,/local},opt/*}/man -type f 2>/dev/null | while read i ; do ext="${i##*.}" fn="${i##*/}" if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then # update symlinks to this manpage find "$startdir"/pkg/{usr{,/local},opt/*}/man -lname "$fn" 2> /dev/null | while read ln ; do rm -f "$ln" ln -sf "${fn}.gz" "${ln}.gz" done # compress the original gzip -9 "$i" fi done cd "$startdir" # strip binaries if [ "$(check_option strip)" = "y" ]; then msg "Stripping debugging symbols from libraries..." find pkg/{,usr,usr/local,opt/*}/lib -type f -not -name "*.dll" -not -name "*.exe" \ -exec /usr/bin/strip --strip-debug '{}' \; 2>&1 \ | grep -v "No such file" | grep -v "format not recognized" msg "Stripping symbols from binaries..." find pkg/{,usr,usr/local,opt/*}/{bin,sbin} -type f -not -name "*.dll" -not -name "*.exe" \ -exec /usr/bin/strip '{}' \; 2>&1 \ | grep -v "No such file" | grep -v "format not recognized" fi # remove libtool (.la) files if [ "$(check_option libtool)" = "n" ]; then msg "Removing libtool .la files..." find pkg -type f -name "*.la" -exec rm -f -- '{}' \; fi # remove empty directories if [ "$(check_option emptydirs)" = "n" ]; then msg "Removing empty directories..." cd "$startdir/pkg" find -depth -type d -empty -delete; fi # get some package meta info builddate=$(LC_ALL= ; LANG= ; date -u "+%a %b %e %H:%M:%S %Y") if [ "$PACKAGER" != "" ]; then packager="$PACKAGER" else packager="Arch Linux (http://www.archlinux.org)" fi # XXX this function should really be moved up to live with its friends createpackage() { local pkgdir=$1 local size=$(du -cb "$pkgdir" | tail -n 1 | awk '{print $1}') msg "Making: $pkgname" # build a filelist - do this first to keep meta files out of the list msg "Generating .FILELIST file..." pushd "$pkgdir" >/dev/null tar cvf /dev/null * | sort >.FILELIST # write the .PKGINFO file msg "Generating .PKGINFO file..." echo "# Generated by makepkg $myver" >.PKGINFO echo -n "# " >>.PKGINFO date >>.PKGINFO echo "pkgname = $pkgname" >>.PKGINFO echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO echo "pkgdesc = $pkgdesc" >>.PKGINFO echo "url = $url" >>.PKGINFO echo "builddate = $builddate" >>.PKGINFO echo "packager = $packager" >>.PKGINFO echo "size = $size" >>.PKGINFO if [ "$CARCH" != "" ]; then echo "arch = $CARCH" >>.PKGINFO fi for it in "${license[@]}"; do echo "license = $it" >>.PKGINFO done for it in "${replaces[@]}"; do echo "replaces = $it" >>.PKGINFO done for it in "${groups[@]}"; do echo "group = $it" >>.PKGINFO done for it in "${depends[@]}"; do echo "depend = $it" >>.PKGINFO done for it in "${conflicts[@]}"; do echo "conflict = $it" >>.PKGINFO done for it in "${provides[@]}"; do echo "provides = $it" >>.PKGINFO done for it in "${backup[@]}"; do echo "backup = $it" >>.PKGINFO done # TODO maybe remove this at some point # warn if license array is not present or empty if [ "$license" = "" ]; then warning "Please add a license line to your $BUILDSCRIPT!" plain "example for GPL'ed software: license=('GPL')." fi # check for an install script if [ "$install" != "" ]; then msg "Copying install script..." cp "$startdir/$install" "$pkgdir/.INSTALL" fi # do we have a changelog? have_changelog=0 if [ -f "$startdir/ChangeLog" ]; then msg "Copying package changelog" cp "$startdir/ChangeLog" "$pkgdir/.CHANGELOG" have_changelog=1 fi # tar it up msg "Compressing package..." pkg_file="$PKGDEST/$pkgname-$pkgver-$pkgrel-${CARCH}.${PKGEXT}" comp_files=".PKGINFO .FILELIST ${install:+.INSTALL}" [ $have_changelog -eq 1 ] && comp_files=".CHANGELOG $comp_files" if ! tar czf $pkg_file $comp_files *; then error "Failed to create package file." exit 1 fi popd >/dev/null msg "Finished making: $pkgname ($(date))" } # bah! there are just too many parameters to pass to createpackage(). # plus, we don't want to corrupt the global variables (pkgname,pkgdesc,etc). # so, we make a function here and employ local variables. createsubpackages() { local pkgname pkgdesc replaces groups depends conflicts local provides backup install if [ ! -z "$subpkgs" ]; then for subpkg in "${subpkgs[@]}" do pkgname=$(eval "echo \${pkgname_$subpkg}") pkgdesc=$(eval "echo \${pkgdesc_$subpkg}") groups=($(eval "echo \${groups_$subpkg[@]}")) depends=($(eval "echo \${depends_$subpkg[@]}")) replaces=($(eval "echo \${replaces_$subpkg[@]}")) conflicts=($(eval "echo \${conflicts_$subpkg[@]}")) provides=($(eval "echo \${provides_$subpkg[@]}")) backup=($(eval "echo \${backup_$subpkg[@]}")) install=$(eval "echo \${install_$subpkg}") createpackage $startdir/pkg_$subpkg done fi } createpackage $startdir/pkg createsubpackages if [ "$CLEANUP" = "1" ]; then msg "Cleaning up..." rm -rf src pkg* rm -rf ${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log* fi removedeps installpackage exit 0 # vim: set ts=2 sw=2 noet: