#!/bin/bash # # makepkg - make packages compatable for use with pacman # @configure_input@ # # Copyright (c) 2002-2007 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. # # gettext initialization source gettext.sh TEXTDOMAIN=makepkg export TEXTDOMAIN TEXTDOMAINDIR='@localedir@' export TEXTDOMAINDIR myver='@PACKAGE_VERSION@' startdir="$(pwd)" srcdir="$startdir/src" pkgdir="$startdir/pkg" # Only use ABSROOT if we haven't been passed a SRCROOT on the command line. if [ -z "$SRCROOT" ]; then if [ -r @sysconfdir@/abs/abs.conf ]; then source @sysconfdir@/abs/abs.conf fi if [ -r ~/.abs.conf ]; then source ~/.abs.conf fi SRCROOT=$ABSROOT fi # Options ASROOT=0 CLEANUP=0 CLEANCACHE=0 DEP_BIN=0 DEP_SRC=0 SUDO=0 FORCE=0 INFAKEROOT=0 GENINTEG=0 INSTALL=0 NOBUILD=0 NODEPS=0 NOEXTRACT=0 RMDEPS=0 REPKG=0 LOGGING=0 SOURCEONLY=0 PACMAN_OPTS= ### SUBROUTINES ### plain() { local mesg=$1; shift if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then printf "\033[1;37m ${mesg}\033[0m\n" "$@" >&2 else printf " ${mesg}\n" "$@" >&2 fi } msg() { local mesg=$1; shift if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then printf "\033[1;32m==>\033[1;37m ${mesg}\033[0m\n" "$@" >&2 else printf "==> ${mesg}\n" "$@" >&2 fi } msg2() { local mesg=$1; shift if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then printf "\033[1;34m ->\033[1;37m ${mesg}\033[0m\n" "$@" >&2 else printf " -> ${mesg}\n" "$@" >&2 fi } warning() { local mesg=$1; shift if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then printf "\033[1;33m==> WARNING:\033[1;37m ${mesg}\033[0m\n" "$@" >&2 else printf "==> WARNING: ${mesg}\n" "$@" >&2 fi } error() { local mesg=$1; shift if [ ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then printf "\033[1;31m==> ERROR:\033[1;37m ${mesg}\033[0m\n" "$@" >&2 else printf "==> ERROR: ${mesg}\n" "$@" >&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 "$(gettext "Options beginning with 'no' will be deprecated in the next version of makepkg!")" plain "$(gettext "Please replace 'no' with '!': no%s -> !%s.")" "$needle" "$needle" echo "n" return elif [ "$lc" = "keepdocs" -a "$needle" = "docs" ]; then warning "$(gettext "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 "$(gettext "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 "$(gettext "unknown")" return } in_array() { local needle=$1 shift 1 [ -z "$1" ] && return 1 for i in $*; do [ "$i" = "$needle" ] && return 0 done return 1 } getdownloadclient() { # $1 = url with valid protocol prefix local url=$1 local proto=$(echo $netfile | sed 's|://.*||') # loop through DOWNLOAD_AGENTS variable looking for protocol for i in "${DLAGENTS[@]}"; do local handler=$(echo $i | sed 's|::.*||') if [ "$proto" == "$handler" ]; then agent=$(echo $i | sed 's|^.*::||') break fi done # if we didn't find an agent, return an error if [ -z "$agent" ]; then error "$(eval_gettext "There is no agent set up to handle \$proto URLs. Check makepkg.conf.")" error "$(gettext "Aborting...")" exit 1 # $E_CONFIG_ERROR # TODO: error code fi # ensure specified program is installed local program="$(echo $agent | awk '{print $1 }')" if [ ! -x "$program" ]; then local baseprog=$(basename $program) error "$(gettext "The download program %s is not installed.")" "$baseprog" error "$(gettext "Aborting...")" exit 1 # $E_MISSING_PROGRAM # TODO: error code fi echo "$agent" } checkdeps() { [ $# -gt 0 ] || return pmout=$(pacman $PACMAN_OPTS -T $*) ret=$? if [ $ret -eq 1 ]; then #unresolved deps echo "$pmout" elif [ $ret -ne 0 ]; then error "$(gettext "pacman returned a fatal error (%i): %s")" "$ret" "$pmout" exit 1 fi } handledeps() { local missingdeps=0 local deplist="$*" local depstrip="" local striplist="" local haveperm=0 if [ "$EUID" = "0" -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 "$(gettext "Installing missing dependencies...")" sudo pacman $PACMAN_OPTS -S $striplist if [ $? -eq 1 ]; then error "$(gettext "Pacman failed to install missing dependencies.")" exit 1 fi elif [ "$DEP_BIN" = "1" ]; then # install missing deps from binary packages (using pacman -S) msg "$(gettext "Installing missing dependencies...")" pacman $PACMAN_OPTS -S $striplist if [ $? -eq 1 ]; then error "$(gettext "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 "$(gettext "Source root cannot be found - ensure it is specified in makepkg.conf.")" exit 1 fi # TODO: handle version comparators (eg, glibc>=2.2.5) msg "$(gettext "Building missing dependencies...")" for dep in $striplist; do candidates=$(find $SRCROOT -type d -name "$dep") if [ "$candidates" = "" ]; then error "$(gettext "Could not find \"%s\" under %s")" "$dep" "$SRCROOT" exit 1 fi success=0 for packagedir in $candidates; do if [ -f "$packagedir/$BUILDSCRIPT" ]; then cd "$packagedir" 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 "$(gettext "Failed to build \"%s\"")" "$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 "$(gettext "Cannot auto-install missing dependencies as a normal user without sudo!")" plain "$(gettext "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 "$(gettext "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 "$(gettext "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 "$(gettext "Removing installed dependencies...")" sudo pacman $PACMAN_OPTS -Rs $striplist elif [ "$RMDEPS" = "1" -a "$EUID" = "0" -a "$INFAKEROOT" != "1" -a -n "$deplist" ]; then msg "$(gettext "Removing installed dependencies...")" pacman $PACMAN_OPTS -Rs $striplist fi } run_build() { # 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" export DISTCC_HOSTS elif [ "$(check_option distcc)" = "n" ]; then # if it is not wanted, clear the makeflags too 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 MAKEFLAGS="" fi msg "$(gettext "Starting build()...")" cd "$srcdir" # ensure we have a sane umask set umask 0022 # ensure all necessary build variables are exported export CFLAGS CXXFLAGS MAKEFLAGS # check for "exit on syntax error" shell option echo $SHELLOPTS | grep errexit 2>&1 >/dev/null; set_e=$? local ret=0 if [ "$LOGGING" = "1" ]; then BUILDLOG="${startdir}/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log" if [ -f "$BUILDLOG" ]; then local 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 "$(gettext "Build Failed. Aborting...")" removedeps exit 2 # $E_BUILD_FAILED # TODO: error code fi } tidy_install() { cd "$pkgdir" msg "$(gettext "Tidying install...")" if [ "$(check_option docs)" = "n" ]; then msg2 "$(gettext "Removing info/doc files...")" #fix flyspray bug #5021 rm -rf ${DOC_DIRS[@]} fi if [ -d usr/share/man ]; then msg2 "$(gettext "Moving usr/share/man files to usr/man")" mkdir -p usr/man cp -a usr/share/man/* usr/man/ rm -rf usr/share/man fi msg2 "$(gettext "Compressing man pages...")" local manpage ext file link find {usr{,/local},opt/*}/man -type f 2>/dev/null | while read manpage ; do ext="${manpage##*.}" file="${manpage##*/}" if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then # update symlinks to this manpage find {usr{,/local},opt/*}/man -lname "$file" 2>/dev/null | while read link ; do rm -f "$link" ln -sf "${file}.gz" "${link}.gz" done # compress the original gzip -9 "$manpage" fi done if [ "$(check_option strip)" = "y" ]; then msg "$(gettext "Stripping debugging symbols from binaries and libraries...")" for file in $(find {,*/}{bin,lib,sbin} -type f 2>/dev/null || true); do case "$(file -biz "$file")" in *application/x-sharedlib*) # Libraries /usr/bin/strip --strip-debug "$file";; *application/x-executable*) # Binaries /usr/bin/strip "$file";; esac done fi if [ "$(check_option libtool)" = "n" ]; then msg2 "$(gettext "Removing libtool .la files...")" find -type f -name "*.la" -exec rm -f -- '{}' \; fi if [ "$(check_option emptydirs)" = "n" ]; then msg2 "$(gettext "Removing empty directories...")" find -depth -type d -empty -delete fi } create_package() { if [ ! -d "$pkgdir" ]; then error "$(gettext "Missing pkg/ directory, aborting...")" exit 1 # $E_MISSING_PKGDIR # TODO: error code fi cd "$pkgdir" msg "$(gettext "Creating package...")" local builddate=$(LC_ALL= LANG= date -u "+%a %b %e %H:%M:%S %Y") if [ "$PACKAGER" != "" ]; then local packager="$PACKAGER" else local packager="Arch Linux (http://www.archlinux.org)" fi local size=$(du -sb | awk '{print $1}') # build a filelist - do this first to keep meta files out of the list msg2 "$(gettext "Generating .FILELIST file...")" tar -cvf /dev/null * | sort >.FILELIST # write the .PKGINFO file msg2 "$(gettext "Generating .PKGINFO file...")" echo "# Generated by makepkg $myver" >.PKGINFO echo "# $(LC_ALL= LANG= date -u)" >>.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 local it 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 "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT" plain "$(gettext "example for GPL'ed software: license=('GPL').")" fi local comp_files # check for an install script # TODO: should we include ${pkgname}.install if it exists and $install is unset? if [ "$install" != "" ]; then msg2 "$(gettext "Copying install script...")" cp "$startdir/$install" .INSTALL comp_files="$comp_files .INSTALL" fi # do we have a changelog? if [ -f "$startdir/ChangeLog" ]; then msg2 "$(gettext "Copying package changelog")" cp "$startdir/ChangeLog" .CHANGELOG comp_files="$comp_files .CHANGELOG" fi # tar it up msg2 "$(gettext "Compressing package...")" local pkg_file="$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" comp_files="$comp_files .PKGINFO .FILELIST" if ! tar -czf "$pkg_file" $comp_files *; then error "$(gettext "Failed to create package file.")" exit 1 # TODO: error code fi create_xdelta "$pkg_file" } create_xdelta() { if [ "$(check_buildenv xdelta)" != "y" ]; then return fi # Check to see if we have any old versions to create deltas with local pkg_file=$1 local base_file="" local delta_file="" local cache_dir="/var/cache/pacman/pkg" local latest_version="" local old_versions=( $(ls ${cache_dir}/${pkgname}-*-${CARCH}.${PKGEXT} 2>/dev/null; ls ${PKGDEST}/${pkgname}-*-${CARCH}.${PKGEXT} 2>/dev/null) ) local old_file dirname filename namend old_version for old_file in "${old_versions[@]}"; do dirname=$(dirname $old_file) filename=$(basename $old_file) namend=${filename#"$pkgname-"} old_version=${namend%-"${CARCH}.${PKGEXT}"} # old_version may include the target package, only use the old versions if [ "$old_version" != "$pkgver-$pkgrel" ] && [[ "$old_version" > "$latest_version" ]]; then latest_version=$old_version base_file=$old_file delta_file=$PKGDEST/$pkgname-${old_version}_to_$pkgver-$pkgrel-${CARCH}.delta fi done if [ "$delta_file" != "" ]; then msg "Making delta from version $latest_version" # xdelta will decompress base_file & pkg_file into TMP_DIR (or /tmp if TMP_DIR is unset) # then perform the delta on the resulting tars xdelta delta $base_file $pkg_file $delta_file # Generate the final gz using xdelta for compression. xdelta will be our common # denominator compression utility between the packager and the users # # makepkg and pacman must use the same compression algorithm or the delta generated # package may not match, producing md5 checksum errors. # xdelta patch $delta_file $base_file $pkg_file else msg "No previous version found, skipping xdelta" fi } create_srcpackage() { cd "$startdir" msg "$(gettext "Creating source package...")" local comp_files="PKGBUILD" msg2 "$(gettext "Adding PKGBUILD")" if [ "$install" != "" ]; then if [ -f $install ]; then msg2 "$(gettext "Adding install script")" comp_files="$comp_files $install" else error "$(gettext "Install script $install not found.")" fi fi local i for i in ${source[@]}; do if [ -f $i ]; then msg2 "$(gettext "Adding %s")" $i comp_files="$comp_files $i" fi done # TODO make package extension configurable like $PKGEXT local pkg_file="$PKGDEST/${pkgname}-${pkgver}-${pkgrel}.src.tar.gz" # tar it up msg2 "$(gettext "Compressing source package...")" if ! tar -czf "$pkg_file" $comp_files; then error "$(gettext "Failed to create source package file.")" exit 1 # TODO: error code fi } installpackage() { if [ "$INSTALL" = "1" -a "$SUDO" = "1" ]; then msg "$(gettext "Installing package with pacman -U...")" sudo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} exit $? elif [ "$INSTALL" = "1" -a "$EUID" = "0" -a "$INFAKEROOT" != "1" ]; then msg "$(gettext "Installing package with pacman -U...")" pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} exit $? fi } usage() { printf "$(gettext "makepkg (pacman) %s")\n" "$myver" echo printf "$(gettext "Usage: %s [options]")\n" "$0" echo echo "$(gettext "Options:")" echo "$(gettext " -b, --builddeps Build missing dependencies from source")" echo "$(gettext " -c, --clean Clean up work files after build")" echo "$(gettext " -C, --cleancache Clean up source files from the cache")" echo "$(gettext " -d, --nodeps Skip all dependency checks")" echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")" echo "$(gettext " -f, --force Overwrite existing package")" echo "$(gettext " -g, --geninteg Generate integrity checks for source files")" echo "$(gettext " -h, --help This help")" echo "$(gettext " -i, --install Install package after successful build")" echo "$(gettext " -L, --log Log package build process")" echo "$(gettext " -m, --nocolor Disable colorized output messages")" echo "$(gettext " -o, --nobuild Download and extract files only")" printf "$(gettext " -p Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT" echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")" # fix flyspray feature request #2978 echo "$(gettext " -R, --repackage Repackage contents of pkg/ without building")" echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")" echo "$(gettext " -S, --usesudo When calling pacman, use sudo")" echo "$(gettext " --source Do not build package; generate a source-only tarball")" echo echo "$(gettext "These options can be passed to pacman:")" echo echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")" echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")" echo printf "$(gettext "If -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT" echo } version() { printf "$(gettext "makepkg (pacman) %s")\n" "$myver" echo "$(gettext "Copyright (C) 2002-2007 Judd Vinet .")" echo echo "$(gettext "This is free software; see the source for copying conditions.")" echo "$(gettext "There is NO WARRANTY, to the extent permitted by law.")" echo } ARGLIST=$@ #preserve environment variables _PKGDEST=${PKGDEST} _SRCDEST=${SRCDEST} # Source makepkg.conf; fail if it is not found conffile="@sysconfdir@/makepkg.conf" if [ -r $conffile ]; then source $conffile else error "$(gettext "%s not found. cannot continue")" $conffile exit 1 # $E_CONFIG_ERROR # TODO: error codes fi unset conffile # Source user-specific makepkg.conf overrides if [ -r ~/.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 --asroot) ASROOT=1 ;; --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 ;; --source) SOURCEONLY=1 ;; --help) usage exit 0 ;; --version) version exit 0 ;; --*) usage exit 1 ;; -*) while getopts "bcCdefFghiLmop: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 ;; F) INFAKEROOT=1 ;; g) GENINTEG=1 ;; 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 ;; h) usage exit 0 ;; V) version exit 0 ;; -) OPTIND=0 break ;; *) usage exit 1 ;; esac done ;; *) true ;; esac shift done # check for sudo if [ "$SUDO" = "1" -a ! "$(type -p sudo)" ]; then error "$(gettext "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 "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST" echo -n "$(gettext " 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 "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST" exit 1 else # removal worked msg "$(gettext "Source cache cleaned.")" exit 0 fi else # answer = no msg "$(gettext "No files have been removed.")" exit 0 fi else # $SRCDEST is $startdir, two possibilities error "$(gettext "Source destination must be defined in makepkg.conf.")" plain "$(gettext "In addition, please run makepkg -C outside of your cache directory.")" exit 1 fi fi if [ -z $BUILDSCRIPT ]; then error "$(eval_gettext "BUILDSCRIPT is undefined! Ensure you have updated makepkg.conf.")" exit 1 fi if [ "$INFAKEROOT" = "0" ]; then if [ $EUID -eq 0 -a $ASROOT -eq 0 ]; then # Warn those who like to live dangerously. error "$(gettext "Running makepkg as root is a BAD idea and can cause")" plain "$(gettext "permanent, catastrophic damage to your system. If you")" plain "$(gettext "wish to run as root, please use the --asroot option.")" plain "" exit 1 # $E_USER_ABORT elif [ "$(check_buildenv fakeroot)" = "y" ]; then if [ ! $(type -p fakeroot) ]; then error "$(gettext "fakeroot must be installed if using the 'fakeroot' option")" plain "$(gettext "in the BUILDENV array in makepkg.conf.")" plain "" exit 1 fi else warning "$(gettext "Running makepkg as an unprivileged user will result in non-root")" plain "$(gettext "ownership of the packaged files. Try using the fakeroot environment by")" plain "$(gettext "placing 'fakeroot' in the BUILDENV array in makepkg.conf.")" plain "" sleep 1 fi else if [ "$FAKEROOTKEY" = "" ]; then error "$(gettext "Do not use the '-F' option. This option is only for use by makepkg.")" exit 1 # TODO: error code 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 "$(gettext "%s does not exist.")" "$BUILDSCRIPT" 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 "$(gettext "pkgver is not allowed to be empty.")" exit 1 fi if [ -z "$pkgrel" ]; then error "$(gettext "pkgrel is not allowed to be empty.")" exit 1 fi if [ $(echo "$pkgver" | grep '-') ]; then error "$(gettext "pkgver is not allowed to contain hyphens.")" exit 1 fi if [ $(echo "$pkgrel" | grep '-') ]; then error "$(gettext "pkgrel is not allowed to contain hyphens.")" exit 1 fi if ! in_array $CARCH ${arch[@]}; then error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgname" "$CARCH" plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT" plain "$(gettext "such as arch=('%s').")" "$CARCH" exit 1 fi if [ "$install" -a ! -f "$install" ]; then error "$(gettext "install scriptlet (%s) does not exist.")" "$install" exit 1 fi if [ -f "$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" \ -a "$FORCE" = "0" -a "$GENINTEG" = "0" -a "$SOURCEONLY" = "0" ]; then if [ "$INSTALL" = "1" ]; then warning "$(gettext "a package has already been built, installing existing package.")" installpackage exit $? else error "$(gettext "a package has already been built. (use -f to overwrite)")" exit 1 fi fi # Run the bear minimum in fakeroot # fix flyspray bug 6208 -- using makepkg with fakeroot gives an error if [ "$INFAKEROOT" = "1" ]; then if [ "$REPKG" = "1" ]; then warning "$(gettext "Skipping build.")" else run_build tidy_install fi create_package msg "$(gettext "Leaving fakeroot environment.")" exit 0 # $E_OK fi date=$(date) msg "$(gettext "Making package: %s")" "$pkgname $pkgver-$pkgrel ($date)" # if we are creating a source-only package, go no further if [ "$SOURCEONLY" = "1" ]; then if [ -f "$PKGDEST/${pkgname}-${pkgver}-${pkgrel}.src.tar.gz" \ -a "$FORCE" = "0" ]; then error "$(gettext "a package has already been built. (use -f to overwrite)")" exit 1 fi create_srcpackage date=$(date) msg "$(gettext "Source package created: %s")" "$pkgname ($date)" exit 0 fi # fix flyspray bug #5973 if [ "$NODEPS" = "1" -o "$GENINTEG" = "1" -o "$NOBUILD" = "1" -o "$REPKG" = "1" ]; then if [ "$NODEPS" = "1" ]; then warning "$(gettext "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 "$(gettext "Checking Runtime Dependencies...")" resolvedeps ${depends[@]} ret=$? # deplist is a global variable set by resolvedeps runtimedeps="$deplist" if [ "$ret" != "0" ]; then deperr=1 fi msg "$(gettext "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 "$(gettext "could not resolve all dependencies.")" exit 1 fi else warning "$(gettext "pacman was not found in PATH; skipping dependency checks.")" fi cd "$startdir" mkdir -p src cd "$srcdir" if [ "$NOEXTRACT" = "1" -o "$REPKG" = "1" ]; then warning "$(gettext "Skipping source retrieval -- using existing src/ tree")" else msg "$(gettext "Retrieving Sources...")" for netfile in ${source[@]}; do file=$(strip_url "$netfile") if [ -f "../$file" ]; then msg2 "$(gettext "Found %s in build dir")" "$file" cp "../$file" . continue elif [ -f "$SRCDEST/$file" ]; then msg2 "$(gettext "Using cached copy of %s")" "$file" cp "$SRCDEST/$file" . continue fi # find the client we should use for this URL dlclient=$(getdownloadclient $netfile) || exit $? msg2 "$(gettext "Downloading %s")" "$file" # fix flyspray bug #3289 ret=0 $dlclient "$netfile" || ret=$? if [ $ret -gt 0 ]; then error "$(gettext "Failure while downloading %s")" "$file" msg "$(gettext "Aborting...")" exit 1 fi if [ -n "$SRCDEST" ]; then mkdir -p "$SRCDEST" && cp "$file" "$SRCDEST" || ret=$? if [ $ret -gt 0 ]; then warning "$(gettext "You do not have correct permissions to cache source in %s")" "$SRCDEST" cp "$file" .. fi else cp "$file" .. fi done unset netfile file dlclient ret fi if [ "$NOEXTRACT" = "1" -o "$REPKG" = "1" ]; then warning "$(gettext "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 "$(gettext "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 "$(gettext "Invalid integrity algorithm '%s' specified")" "$integ"; exit 1;; esac if [ ! $(type -p $integrity_name) ]; then error "$(gettext "Cannot find the %s program.")" "$integrity_name" 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 "$(gettext "Validating source files with %s")" "${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 "$(gettext "FAILED")" >&2 errors=1 else echo "$(gettext "Passed")" >&2 fi idx=$(($idx+1)) done if [ $errors -gt 0 ]; then error "$(gettext "One or more files did not pass the validity check!")" exit 1 fi else warning "$(gettext "Integrity checks (%s) are missing or incomplete.")" "$integ" fi fi done if [ "$GENINTEG" = "1" ]; then plain "" exit 0 fi fi #Extract sources if [ "$NOEXTRACT" = "1" -o "$REPKG" = "1" ]; then warning "$(gettext "Skipping source extraction -- using existing src/ tree")" else msg "$(gettext "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 "$(gettext "Failed to extract %s")" "$file" msg "$(gettext "Aborting...")" exit 1 fi fi fi done if [ "$EUID" = "0" ]; then # chown all source files to root.root chown -R root.root "$srcdir" fi fi if [ "$NOBUILD" = "1" ]; then msg "$(gettext "Sources are ready.")" exit 0 else # check for existing pkg directory; don't remove if we are repackaging if [ -d "$pkgdir" -a "$REPKG" = "0" ]; then msg "$(gettext "Removing existing pkg/ directory...")" rm -rf "$pkgdir" fi mkdir -p "$pkgdir" if [ $EUID -eq 0 ]; then # if we are root, then we don't need to recall makepkg with fakeroot if [ "$REPKG" = "1" ]; then warning "$(gettext "Skipping build.")" else run_build tidy_install fi create_package else msg "$(gettext "Entering fakeroot environment...")" cd "$startdir" ret=0 fakeroot -- $0 -F $ARGLIST || ret=$? [ $ret -ne 0 ] && exit $ret unset ret fi fi cd "$startdir" if [ "$CLEANUP" = "1" ]; then msg "$(gettext "Cleaning up...")" rm -rf src pkg rm -rf ${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log* fi removedeps date=$(date) msg "$(gettext "Finished making: %s")" "$pkgname ($date)" installpackage exit 0 # vim: set ts=2 sw=2 noet: