diff options
Diffstat (limited to 'scripts/makepkg.sh.in')
-rw-r--r-- | scripts/makepkg.sh.in | 1578 |
1 files changed, 952 insertions, 626 deletions
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index e21418a6..dd4066bf 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/bash # # makepkg - make packages compatible for use with pacman # @configure_input@ @@ -39,25 +39,27 @@ export COMMAND_MODE='legacy' # Ensure CDPATH doesn't screw with our cd calls unset CDPATH -myver='@PACKAGE_VERSION@' -confdir='@sysconfdir@' -BUILDSCRIPT='@BUILDSCRIPT@' -startdir="$PWD" +declare -r makepkg_version='@PACKAGE_VERSION@' +declare -r confdir='@sysconfdir@' +declare -r BUILDSCRIPT='@BUILDSCRIPT@' +declare -r startdir="$PWD" packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx') other_options=('ccache' 'distcc' 'buildflags' 'makeflags') -splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'license' \ +splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'url' 'license' \ 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \ 'replaces' 'backup' 'options' 'install' 'changelog') readonly -a packaging_options other_options splitpkg_overrides # Options +ASDEPS=0 ASROOT=0 CLEANUP=0 DEP_BIN=0 FORCE=0 INFAKEROOT=0 GENINTEG=0 +HOLDVER=0 SKIPCHECKSUMS=0 SKIPPGPCHECK=0 INSTALL=0 @@ -69,10 +71,11 @@ REPKG=0 LOGGING=0 SOURCEONLY=0 IGNOREARCH=0 -HOLDVER=0 +PREPAREFUNC=0 BUILDFUNC=0 CHECKFUNC=0 PKGFUNC=0 +PKGVERFUNC=0 SPLITPKG=0 PKGLIST=() SIGNPKG='' @@ -168,7 +171,7 @@ clean_up() { # clean up dangling symlinks to packages for pkg in ${pkgname[@]}; do - for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do + for file in ${pkg}-*-*-*{${PKGEXT},${SRCEXT}}; do if [[ -h $file && ! -e $file ]]; then rm -f "$file" fi @@ -183,12 +186,7 @@ clean_up() { enter_fakeroot() { msg "$(gettext "Entering %s environment...")" "fakeroot" - - if [[ -n $newpkgver ]]; then - fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $? - else - fakeroot -- $0 -F "${ARGLIST[@]}" || exit $? - fi + fakeroot -- $0 -F "${ARGLIST[@]}" || exit $? } @@ -197,42 +195,452 @@ enter_fakeroot() { # 2) "http://path/to/file" # Return the absolute filename of a source entry -# -# This function accepts a source entry or the already extracted filename of a -# source entry as input get_filepath() { local file="$(get_filename "$1")" + local proto="$(get_protocol "$1")" + + case $proto in + git*|hg*|svn*) + if [[ -d "$startdir/$file" ]]; then + file="$startdir/$file" + elif [[ -d "$SRCDEST/$file" ]]; then + file="$SRCDEST/$file" + else + return 1 + fi + ;; + *) + if [[ -f "$startdir/$file" ]]; then + file="$startdir/$file" + elif [[ -f "$SRCDEST/$file" ]]; then + file="$SRCDEST/$file" + else + return 1 + fi + ;; + esac - if [[ -f "$startdir/$file" ]]; then - file="$startdir/$file" - elif [[ -f "$SRCDEST/$file" ]]; then - file="$SRCDEST/$file" - else - return 1 - fi - - echo "$file" -} - -# Print 'source not found' error message and exit makepkg -missing_source_file() { - error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")" - plain "$(gettext "Aborting...")" - exit 1 # $E_MISSING_FILE + printf "%s\n" "$file" } # extract the filename from a source entry get_filename() { + local netfile=$1 + # if a filename is specified, use it - local filename="${1%%::*}" - # if it is just an URL, we only keep the last component - echo "${filename##*/}" + if [[ $netfile = *::* ]]; then + printf "%s\n" ${netfile%%::*} + return + fi + + local proto=$(get_protocol "$netfile") + + case $proto in + git*|hg*|svn*) + filename=${netfile##*/} + filename=${filename%%#*} + # fall-through + ;;& + git*) + filename=${filename%%.git*} + ;; + *) + # if it is just an URL, we only keep the last component + filename="${netfile##*/}" + ;; + esac + printf "%s\n" "${filename}" } # extract the URL from a source entry get_url() { # strip an eventual filename - echo "${1#*::}" + printf "%s\n" "${1#*::}" +} + +# extract the protocol from a source entry - return "local" for local sources +get_protocol() { + if [[ $1 = *://* ]]; then + # strip leading filename + local proto="${1##*::}" + printf "%s\n" "${proto%%://*}" + else + printf "%s\n" local + fi +} + +get_downloadclient() { + local proto=$1 + + # loop through DOWNLOAD_AGENTS variable looking for protocol + local i + for i in "${DLAGENTS[@]}"; do + local handler="${i%%::*}" + if [[ $proto = "$handler" ]]; then + local agent="${i##*::}" + break + fi + done + + # if we didn't find an agent, return an error + if [[ -z $agent ]]; then + error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF" + plain "$(gettext "Aborting...")" + exit 1 # $E_CONFIG_ERROR + fi + + # ensure specified program is installed + local program="${agent%% *}" + if [[ ! -x $program ]]; then + local baseprog="${program##*/}" + error "$(gettext "The download program %s is not installed.")" "$baseprog" + plain "$(gettext "Aborting...")" + exit 1 # $E_MISSING_PROGRAM + fi + + printf "%s\n" "$agent" +} + +download_local() { + local netfile=$1 + local filepath=$(get_filepath "$netfile") + + if [[ -n "$filepath" ]]; then + msg2 "$(gettext "Found %s")" "${filepath##*/}" + rm -f "$srcdir/${filepath##*/}" + ln -s "$filepath" "$srcdir/" + continue + else + local filename=$(get_filename "$netfile") + error "$(gettext "%s was not found in the build directory and is not a URL.")" "$filename" + exit 1 # $E_MISSING_FILE + fi +} + +download_file() { + local netfile=$1 + + local filepath=$(get_filepath "$netfile") + if [[ -n "$filepath" ]]; then + msg2 "$(gettext "Found %s")" "${filepath##*/}" + rm -f "$srcdir/${filepath##*/}" + ln -s "$filepath" "$srcdir/" + return + fi + + local proto=$(get_protocol "$netfile") + + # find the client we should use for this URL + local dlcmd + dlcmd=$(get_downloadclient "$proto") || exit $? + + local filename=$(get_filename "$netfile") + local url=$(get_url "$netfile") + + if [[ $proto = "scp" ]]; then + # scp downloads should not pass the protocol in the url + url="${url##*://}" + fi + + msg2 "$(gettext "Downloading %s...")" "$filename" + + # temporary download file, default to last component of the URL + local dlfile="${url##*/}" + + # replace %o by the temporary dlfile if it exists + if [[ $dlcmd = *%o* ]]; then + dlcmd=${dlcmd//\%o/\"$filename.part\"} + dlfile="$filename.part" + fi + # add the URL, either in place of %u or at the end + if [[ $dlcmd = *%u* ]]; then + dlcmd=${dlcmd//\%u/\"$url\"} + else + dlcmd="$dlcmd \"$url\"" + fi + + local ret=0 + eval "$dlcmd || ret=\$?" + if (( ret )); then + [[ ! -s $dlfile ]] && rm -f -- "$dlfile" + error "$(gettext "Failure while downloading %s")" "$filename" + plain "$(gettext "Aborting...")" + exit 1 + fi + + # rename the temporary download file to the final destination + if [[ $dlfile != "$filename" ]]; then + mv -f "$SRCDEST/$dlfile" "$SRCDEST/$filename" + fi + + rm -f "$srcdir/$filename" + ln -s "$SRCDEST/$filename" "$srcdir/" +} + +download_git() { + local netfile=$1 + + local fragment=${netfile##*#} + if [[ $fragment = "$netfile" ]]; then + unset fragment + fi + + local dir=$(get_filepath "$netfile") + [[ -z "$dir" ]] && dir="$SRCDEST/$(get_filename "$netfile")" + + local repo=${netfile##*/} + repo=${repo%%#*} + repo=${repo%%.git*} + + local url=$(get_url "$netfile") + url=${url##*git+} + url=${url%%#*} + + if [[ ! -d "$dir" ]]; then + msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "git" + if ! git clone --mirror "$url" "$dir"; then + error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "git" + plain "$(gettext "Aborting...")" + exit 1 + fi + elif (( ! HOLDVER )); then + msg2 "$(gettext "Updating %s %s repo...")" "${repo}" "git" + cd_safe "$dir" + if ! git fetch --all -p; then + # only warn on failure to allow offline builds + warning "$(gettext "Failure while updating %s %s repo")" "${repo}" "git" + fi + fi + + msg2 "$(gettext "Creating working copy of %s %s repo...")" "${repo}" "git" + pushd "$srcdir" &>/dev/null + rm -rf "${dir##*/}" + + if ! git clone "$dir"; then + error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git" + plain "$(gettext "Aborting...")" + exit 1 + fi + + cd_safe "${dir##*/}" + + local ref + if [[ -n $fragment ]]; then + case ${fragment%%=*} in + commit|tag) + ref=${fragment##*=} + ;; + branch) + ref=origin/${fragment##*=} + ;; + *) + error "$(gettext "Unrecognized reference: %s")" "${fragment}" + plain "$(gettext "Aborting...")" + exit 1 + esac + fi + + if [[ -n $ref ]]; then + if ! git checkout -b makepkg $ref; then + error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git" + plain "$(gettext "Aborting...")" + exit 1 + fi + fi + + popd &>/dev/null +} + +download_hg() { + local netfile=$1 + + local fragment=${netfile##*#} + if [[ $fragment = "$netfile" ]]; then + unset fragment + fi + + local dir=$(get_filepath "$netfile") + [[ -z "$dir" ]] && dir="$SRCDEST/$(get_filename "$netfile")" + + local repo=${netfile##*/} + repo=${repo%%#*} + + local url=$(get_url "$netfile") + url=${url##*hg+} + url=${url%%#*} + + if [[ ! -d "$dir" ]]; then + msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "hg" + if ! hg clone "$url" "$dir"; then + error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "hg" + plain "$(gettext "Aborting...")" + exit 1 + fi + elif (( ! HOLDVER )); then + msg2 "$(gettext "Updating %s %s repo...")" "${repo}" "hg" + cd_safe "$dir" + if ! hg pull -u; then + # only warn on failure to allow offline builds + warning "$(gettext "Failure while updating %s %s repo")" "${repo}" "hg" + fi + fi + + msg2 "$(gettext "Creating working copy of %s %s repo...")" "${repo}" "hg" + pushd "$srcdir" &>/dev/null + rm -rf "${dir##*/}" + + local ref + if [[ -n $fragment ]]; then + case ${fragment%%=*} in + branch|revision|tag) + ref=('-u' "${fragment##*=}") + ;; + *) + error "$(gettext "Unrecognized reference: %s")" "${fragment}" + plain "$(gettext "Aborting...")" + exit 1 + esac + fi + + if ! hg clone "${ref[@]}" "$dir" "${dir##*/}"; then + error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "hg" + plain "$(gettext "Aborting...")" + exit 1 + fi + + popd &>/dev/null +} + +download_svn() { + local netfile=$1 + + local fragment=${netfile##*#} + if [[ $fragment = "$netfile" ]]; then + unset fragment + fi + + local dir=$(get_filepath "$netfile") + [[ -z "$dir" ]] && dir="$SRCDEST/$(get_filename "$netfile")" + + local repo=${netfile##*/} + repo=${repo%%#*} + + local url=$(get_url "$netfile") + if [[ $url != svn+ssh* ]]; then + url=${url##*svn+} + fi + url=${url%%#*} + + if [[ ! -d "$dir" ]]; then + msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "svn" + if ! svn checkout --config-dir "$dir" "$url" "$dir"; then + error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "svn" + plain "$(gettext "Aborting...")" + exit 1 + fi + elif (( ! HOLDVER )); then + msg2 "$(gettext "Updating %s %s repo...")" "${repo}" "svn" + cd_safe "$dir" + if ! svn update; then + # only warn on failure to allow offline builds + warning "$(gettext "Failure while updating %s %s repo")" "${repo}" "svn" + fi + fi + + msg2 "$(gettext "Creating working copy of %s %s repo...")" "${repo}" "svn" + pushd "$srcdir" &>/dev/null + rm -rf "${dir##*/}" + + local ref + if [[ -n $fragment ]]; then + case ${fragment%%=*} in + revision) + ref=('-r' "${fragment##*=}") + ;; + *) + error "$(gettext "Unrecognized reference: %s")" "${fragment}" + plain "$(gettext "Aborting...")" + exit 1 + esac + fi + + if ! svn export $(ref[@]) "$dir"; then + error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "svn" + plain "$(gettext "Aborting...")" + fi + + popd &>/dev/null +} + +download_sources() { + msg "$(gettext "Retrieving Sources...")" + + local GET_VCS=1 + if [[ $1 == "fast" ]]; then + GET_VCS=0 + fi + + pushd "$SRCDEST" &>/dev/null + + local netfile + for netfile in "${source[@]}"; do + local proto=$(get_protocol "$netfile") + + case "$proto" in + local) + download_local "$netfile" + ;; + ftp|http|https|rsync|scp) + download_file "$netfile" + ;; + git*) + (( GET_VCS )) && download_git "$netfile" + ;; + hg*) + (( GET_VCS )) && download_hg "$netfile" + ;; + svn*) + (( GET_VCS )) && download_svn "$netfile" + ;; + *) + error "$(gettext "Unknown download protocol: %s")" "$proto" + plain "$(gettext "Aborting...")" + exit 1 + ;; + esac + done + + if (( PKGVERFUNC && GET_VCS )); then + update_pkgver + check_pkgver || exit 1 + check_build_status + fi + + popd &>/dev/null +} + +# Automatically update pkgver variable if a pkgver() function is provided +# Re-sources the PKGBUILD afterwards to allow for other variables that use $pkgver +update_pkgver() { + newpkgver=$(run_function_safe pkgver) + + if [[ -n $newpkgver && $newpkgver != "$pkgver" ]]; then + if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then + @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE" + @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE" + source "$BUILDFILE" + else + warning "$(gettext "%s is not writeable -- pkgver will not be updated")" \ + "$BUILDFILE" + fi + fi +} + +# Print 'source not found' error message and exit makepkg +missing_source_file() { + error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")" + plain "$(gettext "Aborting...")" + exit 1 # $E_MISSING_FILE } ## @@ -242,9 +650,9 @@ get_url() { get_full_version() { if [[ -z $1 ]]; then if [[ $epoch ]] && (( ! $epoch )); then - echo $pkgver-$pkgrel + printf "%s\n" "$pkgver-$pkgrel" else - echo $epoch:$pkgver-$pkgrel + printf "%s\n" "$epoch:$pkgver-$pkgrel" fi else for i in pkgver pkgrel epoch; do @@ -253,9 +661,32 @@ get_full_version() { [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\" done if (( ! $epoch_override )); then - echo $pkgver_override-$pkgrel_override + printf "%s\n" "$pkgver_override-$pkgrel_override" + else + printf "%s\n" "$epoch_override:$pkgver_override-$pkgrel_override" + fi + fi +} + +## +# usage : get_pkg_arch( [$pkgname] ) +# return : architecture of the package +## +get_pkg_arch() { + if [[ -z $1 ]]; then + if [[ $arch = "any" ]]; then + printf "%s\n" "any" + else + printf "%s\n" "$CARCH" + fi + else + local arch_override + eval $(declare -f package_$1 | sed -n 's/\(^[[:space:]]*arch=\)/arch_override=/p') + (( ${#arch_override[@]} == 0 )) && arch_override=("${arch[@]}") + if [[ $arch_override = "any" ]]; then + printf "%s\n" "any" else - echo $epoch_override:$pkgver_override-$pkgrel_override + printf "%s\n" "$CARCH" fi fi } @@ -264,63 +695,84 @@ get_full_version() { # Checks to see if options are present in makepkg.conf or PKGBUILD; # PKGBUILD options always take precedence. # -# usage : check_option( $option ) -# return : y - enabled -# n - disabled -# ? - not found +# usage : check_option( $option, $expected_val ) +# return : 0 - matches expected +# 1 - does not match expected +# 127 - not found ## check_option() { - local ret=$(in_opt_array "$1" ${options[@]}) - if [[ $ret != '?' ]]; then - echo $ret - return - fi + in_opt_array "$1" ${options[@]} + case $? in + 0) # assert enabled + [[ $2 = y ]] + return ;; + 1) # assert disabled + [[ $2 = n ]] + return + esac # fall back to makepkg.conf options - ret=$(in_opt_array "$1" ${OPTIONS[@]}) - if [[ $ret != '?' ]]; then - echo $ret - return - fi + in_opt_array "$1" ${OPTIONS[@]} + case $? in + 0) # assert enabled + [[ $2 = y ]] + return ;; + 1) # assert disabled + [[ $2 = n ]] + return + esac - echo '?' # Not Found + # not found + return 127 } ## # Check if option is present in BUILDENV # -# usage : check_buildenv( $option ) -# return : y - enabled -# n - disabled -# ? - not found +# usage : check_buildenv( $option, $expected_val ) +# return : 0 - matches expected +# 1 - does not match expected +# 127 - not found ## check_buildenv() { in_opt_array "$1" ${BUILDENV[@]} + case $? in + 0) # assert enabled + [[ $2 = "y" ]] + return ;; + 1) # assert disabled + [[ $2 = "n" ]] + return ;; + esac + + # not found + return 127 } ## # usage : in_opt_array( $needle, $haystack ) -# return : y - enabled -# n - disabled -# ? - not found +# return : 0 - enabled +# 1 - disabled +# 127 - not found ## in_opt_array() { local needle=$1; shift local opt for opt in "$@"; do - if [[ $opt = $needle ]]; then - echo 'y' # Enabled - return + if [[ $opt = "$needle" ]]; then + # enabled + return 0 elif [[ $opt = "!$needle" ]]; then - echo 'n' # Disabled - return + # disabled + return 1 fi done - echo '?' # Not Found + # not found + return 127 } @@ -333,120 +785,48 @@ in_array() { local needle=$1; shift local item for item in "$@"; do - [[ $item = $needle ]] && return 0 # Found + [[ $item = "$needle" ]] && return 0 # Found done return 1 # Not Found } -source_has_signatures(){ +source_has_signatures() { local file for file in "${source[@]}"; do - if [[ $file = *.@(sig?(n)|asc) ]]; then + if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then return 0 fi done return 1 } -get_downloadclient() { - # $1 = URL with valid protocol prefix - local url=$1 - local proto="${url%%://*}" - - # loop through DOWNLOAD_AGENTS variable looking for protocol - local i - for i in "${DLAGENTS[@]}"; do - local handler="${i%%::*}" - if [[ $proto = $handler ]]; then - local agent="${i##*::}" - break - fi - done - - # if we didn't find an agent, return an error - if [[ -z $agent ]]; then - error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF" - plain "$(gettext "Aborting...")" - exit 1 # $E_CONFIG_ERROR - fi - - # ensure specified program is installed - local program="${agent%% *}" - if [[ ! -x $program ]]; then - local baseprog="${program##*/}" - error "$(gettext "The download program %s is not installed.")" "$baseprog" - plain "$(gettext "Aborting...")" - exit 1 # $E_MISSING_PROGRAM - fi - - echo "$agent" -} - -download_file() { - # download command - local dlcmd=$1 - # URL of the file - local url=$2 - # destination file - local file=$3 - # temporary download file, default to last component of the URL - local dlfile="${url##*/}" - - # replace %o by the temporary dlfile if it exists - if [[ $dlcmd = *%o* ]]; then - dlcmd=${dlcmd//\%o/\"$file.part\"} - dlfile="$file.part" - fi - # add the URL, either in place of %u or at the end - if [[ $dlcmd = *%u* ]]; then - dlcmd=${dlcmd//\%u/\"$url\"} - else - dlcmd="$dlcmd \"$url\"" - fi - - local ret=0 - eval "$dlcmd || ret=\$?" - if (( ret )); then - [[ ! -s $dlfile ]] && rm -f -- "$dlfile" - return $ret - fi - - # rename the temporary download file to the final destination - if [[ $dlfile != "$file" ]]; then - mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file" - fi -} - run_pacman() { local cmd if [[ ! $1 = -@(T|Qq) ]]; then - printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@" + cmd=("$PACMAN" $PACMAN_OPTS "$@") else - printf -v cmd "%q " "$PACMAN" "$@" + cmd=("$PACMAN" "$@") fi if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then if type -p sudo >/dev/null; then - cmd="sudo $cmd" + cmd=(sudo "${cmd[@]}") else - cmd="su root -c '$cmd'" + cmd=(su root -c "$(printf '%q ' "${cmd[@]}")") fi fi - eval "$cmd" + "${cmd[@]}" } check_deps() { (( $# > 0 )) || return 0 - # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility - # Also, a non-zero return value is not unexpected and we are manually dealing them - set +E local ret=0 local pmout - pmout=$(run_pacman -T "$@") || ret=$? - set -E + pmout=$(run_pacman -T "$@") + ret=$? if (( ret == 127 )); then #unresolved deps - echo "$pmout" + printf "%s\n" "$pmout" elif (( ret )); then error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout" return "$ret" @@ -476,13 +856,11 @@ handle_deps() { fi # we might need the new system environment - # avoid triggering the ERR trap and exiting - set +e - local restoretrap=$(trap -p ERR) - trap - ERR + # save our shell options and turn off extglob + local shellopts=$(shopt -p) + shopt -u extglob source /etc/profile &>/dev/null - eval $restoretrap - set -e + eval "$shellopts" return $R_DEPS_SATISFIED } @@ -538,50 +916,6 @@ remove_deps() { fi } -download_sources() { - msg "$(gettext "Retrieving Sources...")" - - pushd "$SRCDEST" &>/dev/null - - local netfile - for netfile in "${source[@]}"; do - local file=$(get_filepath "$netfile" || true) - if [[ -n "$file" ]]; then - msg2 "$(gettext "Found %s")" "${file##*/}" - rm -f "$srcdir/${file##*/}" - ln -s "$file" "$srcdir/" - continue - fi - - file=$(get_filename "$netfile") - local url=$(get_url "$netfile") - - # if we get here, check to make sure it was a URL, else fail - if [[ $file = $url ]]; then - error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file" - exit 1 # $E_MISSING_FILE - fi - - # find the client we should use for this URL - local dlclient - dlclient=$(get_downloadclient "$url") || exit $? - - msg2 "$(gettext "Downloading %s...")" "$file" - # fix flyspray bug #3289 - local ret=0 - download_file "$dlclient" "$url" "$file" || ret=$? - if (( ret )); then - error "$(gettext "Failure while downloading %s")" "$file" - plain "$(gettext "Aborting...")" - exit 1 - fi - rm -f "$srcdir/$file" - ln -s "$SRCDEST/$file" "$srcdir/" - done - - popd &>/dev/null -} - get_integlist() { local integ local integlist=() @@ -594,9 +928,9 @@ get_integlist() { done if (( ${#integlist[@]} > 0 )); then - echo ${integlist[@]} + printf "%s\n" "${integlist[@]}" else - echo ${INTEGRITY_CHECK[@]} + printf "%s\n" "${INTEGRITY_CHECK[@]}" fi } @@ -626,7 +960,7 @@ generate_checksums() { local ct=0 local numsrc=${#source[@]} - echo -n "${integ}sums=(" + printf "%s" "${integ}sums=(" local i local indent='' @@ -636,12 +970,23 @@ generate_checksums() { local netfile for netfile in "${source[@]}"; do - local file - file="$(get_filepath "$netfile")" || missing_source_file "$netfile" - local sum="$(openssl dgst -${integ} "$file")" - sum=${sum##* } - (( ct )) && echo -n "$indent" - echo -n "'$sum'" + local proto sum + proto="$(get_protocol "$netfile")" + + case $proto in + git*|hg*|svn*) + sum="SKIP" + ;; + *) + local file + file="$(get_filepath "$netfile")" || missing_source_file "$netfile" + sum="$(openssl dgst -${integ} "$file")" + sum=${sum##* } + ;; + esac + + (( ct )) && printf "%s" "$indent" + printf "%s" "'$sum'" ct=$(($ct+1)) (( $ct < $numsrc )) && echo done @@ -667,7 +1012,13 @@ check_checksums() { for file in "${source[@]}"; do local found=1 file="$(get_filename "$file")" - echo -n " $file ... " >&2 + printf "%s" " $file ... " >&2 + + if [[ ${integrity_sums[$idx]} = 'SKIP' ]]; then + echo "$(gettext "Skipped")" >&2 + idx=$((idx + 1)) + continue + fi if ! file="$(get_filepath "$file")"; then printf -- "$(gettext "NOT FOUND")\n" >&2 @@ -676,10 +1027,10 @@ check_checksums() { fi if (( $found )) ; then - local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}") + local expectedsum="${integrity_sums[idx],,}" local realsum="$(openssl dgst -${integ} "$file")" realsum="${realsum##* }" - if [[ $expectedsum = $realsum ]]; then + if [[ $expectedsum = "$realsum" ]]; then printf -- "$(gettext "Passed")\n" >&2 else printf -- "$(gettext "FAILED")\n" >&2 @@ -837,10 +1188,10 @@ extract_sources() { local ret=0 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd" - if [[ $cmd = bsdtar ]]; then + if [[ $cmd = "bsdtar" ]]; then $cmd -xf "$file" || ret=$? else - rm -f "${file%.*}" + rm -f -- "${file%.*}" $cmd -dcf "$file" > "${file%.*}" || ret=$? fi if (( ret )); then @@ -869,6 +1220,40 @@ error_function() { exit 2 # $E_BUILD_FAILED } +cd_safe() { + if ! cd "$1"; then + error "$(gettext "Failed to change to directory %s")" "$1" + plain "$(gettext "Aborting...")" + exit 1 + fi +} + +source_safe() { + shopt -u extglob + if ! source "$@"; then + error "$(gettext "Failed to source %s")" "$1" + exit 1 + fi + shopt -s extglob +} + +run_function_safe() { + local restoretrap + + set -e + set -E + + restoretrap=$(trap -p ERR) + trap 'error_function $pkgfunc' ERR + + run_function "$1" + + eval $restoretrap + + set +E + set +e +} + run_function() { if [[ -z $1 ]]; then return 1 @@ -876,25 +1261,24 @@ run_function() { local pkgfunc="$1" # clear user-specified buildflags if requested - if [[ $(check_option buildflags) = "n" ]]; then - unset CFLAGS CXXFLAGS LDFLAGS + if check_option "buildflags" "n"; then + unset CPPFLAGS CFLAGS CXXFLAGS LDFLAGS fi # clear user-specified makeflags if requested - if [[ $(check_option makeflags) = "n" ]]; then + if check_option "makeflags" "n"; then unset MAKEFLAGS fi msg "$(gettext "Starting %s()...")" "$pkgfunc" - cd "$srcdir" + cd_safe "$srcdir" # ensure all necessary build variables are exported - export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST + export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST # save our shell options so pkgfunc() can't override what we need local shellopts=$(shopt -p) local ret=0 - local restoretrap if (( LOGGING )); then local fullver=$(get_full_version) local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log" @@ -916,40 +1300,38 @@ run_function() { tee "$BUILDLOG" < "$logpipe" & local teepid=$! - restoretrap=$(trap -p ERR) - trap 'error_function $pkgfunc' ERR $pkgfunc &>"$logpipe" - eval $restoretrap wait $teepid rm "$logpipe" else - restoretrap=$(trap -p ERR) - trap 'error_function $pkgfunc' ERR $pkgfunc 2>&1 - eval $restoretrap fi # reset our shell options eval "$shellopts" } +run_prepare() { + run_function_safe "prepare" +} + run_build() { # use distcc if it is requested (check buildenv and PKGBUILD opts) - if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then + if check_buildenv "distcc" "y" && ! check_option "distc" "n"; then [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH" export DISTCC_HOSTS fi # use ccache if it is requested (check buildenv and PKGBUILD opts) - if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then + if check_buildenv "ccache" "y" && ! check_option "ccache" "n"; then [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH" fi - run_function "build" + run_function_safe "build" } run_check() { - run_function "check" + run_function_safe "check" } run_package() { @@ -960,73 +1342,65 @@ run_package() { pkgfunc="package_$1" fi - run_function "$pkgfunc" + run_function_safe "$pkgfunc" } tidy_install() { - cd "$pkgdir" + cd_safe "$pkgdir" msg "$(gettext "Tidying install...")" - if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then + if check_option "docs" "n" && [[ -n ${DOC_DIRS[*]} ]]; then msg2 "$(gettext "Removing doc files...")" - rm -rf ${DOC_DIRS[@]} + rm -rf -- ${DOC_DIRS[@]} fi - if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then + if check_option "purge" "y" && [[ -n ${PURGE_TARGETS[*]} ]]; then msg2 "$(gettext "Purging unwanted files...")" local pt for pt in "${PURGE_TARGETS[@]}"; do - if [[ ${pt} = ${pt//\/} ]]; then - find . -type f -name "${pt}" -exec rm -f -- '{}' \; + if [[ ${pt} = "${pt//\/}" ]]; then + find . ! -type d -name "${pt}" -exec rm -f -- '{}' \; else rm -f ${pt} fi done fi - if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then + if check_option "zipman" "y" && [[ -n ${MAN_DIRS[*]} ]]; then msg2 "$(gettext "Compressing man and info pages...")" - local manpage ext file link hardlinks hl - find ${MAN_DIRS[@]} -type f 2>/dev/null | - while read manpage ; do - ext="${manpage##*.}" - file="${manpage##*/}" - if [[ $ext != gz && $ext != bz2 ]]; then - # update symlinks to this manpage - find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null | - while read link ; do + local file files inode link + while read -rd ' ' inode; do + read file + find ${MAN_DIRS[@]} -type l 2>/dev/null | + while read link ; do + if [[ "${file}" -ef "${link}" ]] ; then rm -f "$link" "${link}.gz" - ln -s "${file}.gz" "${link}.gz" - done - - # check file still exists (potentially already compressed due to hardlink) - if [[ -f ${manpage} ]]; then - # find hard links and remove them - # the '|| true' part keeps the script from bailing on the EOF returned - # by read at the end of the find output - IFS=$'\n' read -rd '' -a hardlinks < \ - <(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" \ - 2>/dev/null || true) || true - rm -f "${hardlinks[@]}" - # compress the original - gzip -9 "$manpage" - # recreate hard links removed earlier - for hl in "${hardlinks[@]}"; do - ln "${manpage}.gz" "${hl}.gz" - chmod 644 ${hl}.gz - done + if [[ ${file%/*} = ${link%/*} ]]; then + ln -s -- "${file##*/}.gz" "${link}.gz" + else + ln -s -- "/${file}.gz" "${link}.gz" + fi fi + done + if [[ -z ${files[$inode]} ]]; then + files[$inode]=$file + gzip -9 -f "$file" + else + rm -f "$file" + ln "${files[$inode]}.gz" "${file}.gz" + chmod 644 "${file}.gz" fi - done + done < <(find ${MAN_DIRS[@]} -type f \! -name "*.gz" \! -name "*.bz2" \ + -exec @INODECMD@ '{}' + 2>/dev/null) fi - if [[ $(check_option strip) = y ]]; then + if check_option "strip" "y"; then msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")" # make sure library stripping variables are defined to prevent excess stripping [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S" [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S" local binary - find . -type f -perm -u+w 2>/dev/null | while read binary ; do + find . -type f -perm -u+w -print0 2>/dev/null | while read -d '' binary ; do case "$(file -bi "$binary")" in *application/x-sharedlib*) # Libraries (.so) strip $STRIP_SHARED "$binary";; @@ -1038,17 +1412,17 @@ tidy_install() { done fi - if [[ $(check_option libtool) = "n" ]]; then + if check_option "libtool" "n"; then msg2 "$(gettext "Removing "%s" files...")" "libtool" find . ! -type d -name "*.la" -exec rm -f -- '{}' \; fi - if [[ $(check_option emptydirs) = "n" ]]; then + if check_option "emptydirs" "n"; then msg2 "$(gettext "Removing empty directories...")" - find . -depth -type d -empty -delete + find . -depth -type d -exec rmdir '{}' + 2>/dev/null fi - if [[ $(check_option upx) = "y" ]]; then + if check_option "upx" "y"; then msg2 "$(gettext "Compressing binaries with %s...")" "UPX" local binary find . -type f -perm -u+w 2>/dev/null | while read binary ; do @@ -1061,12 +1435,29 @@ tidy_install() { } find_libdepends() { - local libdepends - find "$pkgdir" -type f -perm -u+x | while read filename - do + local d sodepends; + + sodepends=0; + for d in "${depends[@]}"; do + if [[ $d = *.so ]]; then + sodepends=1; + break; + fi + done + + if (( sodepends == 0 )); then + printf '%s\n' "${depends[@]}" + return; + fi + + local libdeps filename soarch sofile soname soversion; + declare -A libdeps; + + while read filename; do # get architecture of the file; if soarch is empty it's not an ELF binary soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p') - [ -n "$soarch" ] || continue + [[ -n "$soarch" ]] || continue + # process all libraries needed by the binary for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p') do @@ -1074,42 +1465,97 @@ find_libdepends() { soname="${sofile%.so?(+(.+([0-9])))}".so # extract the major version: 1 soversion="${sofile##*\.so\.}" - if in_array "${soname}" ${depends[@]}; then - if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then - # libfoo.so=1-64 - echo "${soname}=${soversion}-${soarch}" - libdepends=(${libdepends[@]} "${soname}=${soversion}-${soarch}") + + if [[ ${libdeps[$soname]} ]]; then + if [[ ${libdeps[$soname]} != *${soversion}-${soarch}* ]]; then + libdeps[$soname]+=" ${soversion}-${soarch}" fi + else + libdeps[$soname]="${soversion}-${soarch}" fi done + done < <(find "$pkgdir" -type f -perm -u+x) + + local libdepends v + for d in "${depends[@]}"; do + case "$d" in + *.so) + if [[ ${libdeps[$d]} ]]; then + for v in ${libdeps[$d]}; do + libdepends+=("$d=$v") + done + else + warning "$(gettext "Library listed in %s is not required by any files: %s")" "'depends'" "$d" + libdepends+=("$d") + fi + ;; + *) + libdepends+=("$d") + ;; + esac done + + printf '%s\n' "${libdepends[@]}" } -find_libprovides() { - local libprovides - find "$pkgdir" -type f -name \*.so\* | while read filename - do - # check if we really have a shared object - if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then - # 64 - soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p') - # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1 - sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p') - [ -z "$sofile" ] && sofile="${filename##*/}" - # extract the library name: libfoo.so - soname="${sofile%%\.so\.*}.so" - # extract the major version: 1 - soversion="${sofile##*\.so\.}" - if in_array "${soname}" ${provides[@]}; then - if ! in_array "${soname}=${soversion}-${soarch}" ${libprovides[@]}; then - # libfoo.so=1-64 - echo "${soname}=${soversion}-${soarch}" - libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}") +find_libprovides() { + local p libprovides missing + for p in "${provides[@]}"; do + missing=0 + case "$p" in + *.so) + mapfile -t filename < <(find "$pkgdir" -type f -name $p\*) + if [[ $filename ]]; then + # packages may provide multiple versions of the same library + for fn in "${filename[@]}"; do + # check if we really have a shared object + if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then + # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1) + local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p') + if [[ -z "$sofile" ]]; then + warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p" + libprovides+=("$p") + continue + fi + + # get the library architecture (32 or 64 bit) + local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p') + + # extract the library major version + local soversion="${sofile##*\.so\.}" + + libprovides+=("${p}=${soversion}-${soarch}") + else + warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p" + libprovides+=("$p") + fi + done + else + libprovides+=("$p") + missing=1 fi - fi - fi + ;; + *) + libprovides+=("$p") + ;; + esac + + if (( missing )); then + warning "$(gettext "Can not find library listed in %s: %s")" "'provides'" "$p" + fi done + + printf '%s\n' "${libprovides[@]}" +} + +check_license() { + # TODO maybe remove this at some point + # warn if license array is not present or empty + if [[ -z $license ]]; then + warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT" + plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')" + fi } write_pkginfo() { @@ -1129,84 +1575,53 @@ write_pkginfo() { size="$(( ${size%%[^0-9]*} * 1024 ))" msg2 "$(gettext "Generating %s file...")" ".PKGINFO" - echo "# Generated by makepkg $myver" + echo "# Generated by makepkg $makepkg_version" if (( INFAKEROOT )); then echo "# using $(fakeroot -v)" fi echo "# $(LC_ALL=C date -u)" - echo "pkgname = $1" + printf "pkgname = %s\n" "$1" (( SPLITPKG )) && echo pkgbase = $pkgbase echo "pkgver = $(get_full_version)" - echo "pkgdesc = $pkgdesc" - echo "url = $url" - echo "builddate = $builddate" - echo "packager = $packager" - echo "size = $size" - echo "arch = $PKGARCH" - - [[ $license ]] && printf "license = %s\n" "${license[@]}" - [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}" - [[ $groups ]] && printf "group = %s\n" "${groups[@]}" - [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }" - [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}" - [[ $backup ]] && printf "backup = %s\n" "${backup[@]}" + printf "pkgdesc = %s\n" "$pkgdesc" + printf "url = %s\n" "$url" + printf "builddate = %s\n" "$builddate" + printf "packager = %s\n" "$packager" + printf "size = %s\n" "$size" + printf "arch = %s\n" "$pkgarch" + + mapfile -t provides < <(find_libprovides) + mapfile -t depends < <(find_libdepends) + + [[ $license ]] && printf "license = %s\n" "${license[@]}" + [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}" + [[ $groups ]] && printf "group = %s\n" "${groups[@]}" + [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}" + [[ $provides ]] && printf "provides = %s\n" "${provides[@]}" + [[ $backup ]] && printf "backup = %s\n" "${backup[@]}" + [[ $depends ]] && printf "depend = %s\n" "${depends[@]}" + [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }" + [[ $makedepends ]] && printf "makedepend = %s\n" "${makedepends[@]}" + [[ $checkdepends ]] && printf "checkdepend = %s\n" "${checkdepends[@]}" local it - - libprovides=$(find_libprovides) - libdepends=$(find_libdepends) - provides=("${provides[@]}" ${libprovides}) - depends=("${depends[@]}" ${libdepends}) - - for it in "${depends[@]}"; do - if [[ $it = *.so ]]; then - # check if the entry has been found by find_libdepends - # if not, it's unneeded; tell the user so he can remove it - printf -v re '(^|\s)%s=.*' "$it" - if [[ ! $libdepends =~ $re ]]; then - error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it" - return 1 - fi - else - echo "depend = $it" - fi - done - - for it in "${provides[@]}"; do - # ignore versionless entires (those come from the PKGBUILD) - if [[ $it = *.so ]]; then - # check if the entry has been found by find_libprovides - # if not, it's unneeded; tell the user so he can remove it - if [[ ! $libprovides =~ (^|\s)${it}=.* ]]; then - error "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$it" - return 1 - fi - else - echo "provides = $it" - fi - done - for it in "${packaging_options[@]}"; do - local ret="$(check_option $it)" - if [[ $ret != "?" ]]; then - if [[ $ret = y ]]; then - echo "makepkgopt = $it" - else - echo "makepkgopt = !$it" - fi - fi + check_option "$it" "y" + case $? in + 0) + printf "makepkgopt = %s\n" "$it" + ;; + 1) + printf "makepkgopt = %s\n" "!$it" + ;; + esac done - # TODO maybe remove this at some point - # warn if license array is not present or empty - if [[ -z $license ]]; then - warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT" - plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')" - fi + check_license } check_package() { - cd "$pkgdir" + cd_safe "$pkgdir" # check existence of backup files local file @@ -1235,7 +1650,7 @@ create_package() { check_package - cd "$pkgdir" + cd_safe "$pkgdir" msg "$(gettext "Creating package...")" local nameofpkg @@ -1245,15 +1660,11 @@ create_package() { nameofpkg="$1" fi - if [[ $arch = "any" ]]; then - PKGARCH="any" - else - PKGARCH=$CARCH - fi + pkgarch=$(get_pkg_arch) write_pkginfo $nameofpkg > .PKGINFO - local comp_files=".PKGINFO" + local comp_files=('.PKGINFO') # check for changelog/install files for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do @@ -1263,7 +1674,7 @@ create_package() { msg2 "$(gettext "Adding %s file...")" "$orig" cp "$startdir/${!orig}" "$dest" chmod 644 "$dest" - comp_files+=" $dest" + comp_files+=("$dest") fi done @@ -1271,7 +1682,7 @@ create_package() { msg2 "$(gettext "Compressing package...")" local fullver=$(get_full_version) - local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}" + local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${pkgarch}${PKGEXT}" local ret=0 [[ -f $pkg_file ]] && rm -f "$pkg_file" @@ -1285,12 +1696,12 @@ create_package() { # bsdtar's gzip compression always saves the time stamp, making one # archive created using the same command line distinct from another. # Disable bsdtar compression and use gzip -n for now. - bsdtar -cf - $comp_files * | + bsdtar -cf - "${comp_files[@]}" * | case "$PKGEXT" in - *tar.gz) gzip -c -f -n ;; - *tar.bz2) bzip2 -c -f ;; - *tar.xz) xz -c -z - ;; - *tar.Z) compress -c -f ;; + *tar.gz) ${COMPRESSGZ[@]:-gzip -c -f -n} ;; + *tar.bz2) ${COMPRESSBZ2[@]:-bzip2 -c -f} ;; + *tar.xz) ${COMPRESSXZ[@]:-xz -c -z -} ;; + *tar.Z) ${COMPRESSZ[@]:-compress -c -f} ;; *tar) cat ;; *) warning "$(gettext "'%s' is not a valid archive extension.")" \ "$PKGEXT"; cat ;; @@ -1350,12 +1761,14 @@ create_srcpackage() { local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)" mkdir "${srclinks}"/${pkgbase} + check_license + msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT" ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}" local file for file in "${source[@]}"; do - if [[ "$file" == $(get_filename "$file") ]] || (( SOURCEONLY == 2 )); then + if [[ "$file" = "$(get_filename "$file")" ]] || (( SOURCEONLY == 2 )); then local absfile absfile=$(get_filepath "$file") || missing_source_file "$file" msg2 "$(gettext "Adding %s...")" "${absfile##*/}" @@ -1392,7 +1805,7 @@ create_srcpackage() { # tar it up msg2 "$(gettext "Compressing source package...")" - cd "${srclinks}" + cd_safe "${srclinks}" if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then error "$(gettext "Failed to create source package file.")" exit 1 # TODO: error code @@ -1408,7 +1821,7 @@ create_srcpackage() { warning "$(gettext "Failed to create symlink to source package file.")" fi - cd "${startdir}" + cd_safe "${startdir}" rm -rf "${srclinks}" } @@ -1421,17 +1834,16 @@ install_package() { msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U" fi - local fullver pkg pkglist + local fullver pkgarch pkg pkglist + (( ASDEPS )) && pkglist+=('--asdeps') + for pkg in ${pkgname[@]}; do fullver=$(get_full_version $pkg) - if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then - pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}" - else - pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}" - fi + pkgarch=$(get_pkg_arch $pkg) + pkglist+=("$PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT}") done - if ! run_pacman -U $pkglist; then + if ! run_pacman -U ${pkglist[@]}; then warning "$(gettext "Failed to install built package(s).")" return 0 fi @@ -1441,7 +1853,7 @@ check_sanity() { # check for no-no's in the build script local i local ret=0 - for i in 'pkgname' 'pkgrel' 'pkgver'; do + for i in 'pkgname' 'pkgrel'; do if [[ -z ${!i} ]]; then error "$(gettext "%s is not allowed to be empty.")" "$i" ret=1 @@ -1465,20 +1877,15 @@ check_sanity() { ret=1 fi - awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" | - while IFS='=' read -r _ i; do - eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\" - if [[ $i = *[[:space:]:-]* ]]; then - error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver" - return 1 - fi - done || ret=1 + if (( ! PKGVERFUNC )) ; then + check_pkgver || ret=1 + fi awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" | while IFS='=' read -r _ i; do eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\" - if [[ $i = *[[:space:]-]* ]]; then - error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel" + if [[ $i != +([0-9])?(.+([0-9])) ]]; then + error "$(gettext "%s must be a decimal.")" "pkgrel" return 1 fi done || ret=1 @@ -1570,7 +1977,7 @@ check_sanity() { known=0 # check if option matches a known option or its inverse for kopt in ${packaging_options[@]} ${other_options[@]}; do - if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then + if [[ ${i} = "${kopt}" || ${i} = "!${kopt}" ]]; then known=1 fi done @@ -1602,6 +2009,26 @@ check_sanity() { return $ret } +check_pkgver() { + local ret=0 + + if [[ -z ${pkgver} ]]; then + error "$(gettext "%s is not allowed to be empty.")" "pkgver" + ret=1 + fi + + awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" | + while IFS='=' read -r _ i; do + eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\" + if [[ $i = *[[:space:]:-]* ]]; then + error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver" + return 1 + fi + done || ret=1 + + return $ret +} + check_software() { # check for needed software local ret=0 @@ -1609,12 +2036,12 @@ check_software() { # check for sudo if we will need it during makepkg execution if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then if ! type -p sudo >/dev/null; then - warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")" + warning "$(gettext "Cannot find the %s binary. Will use %s to acquire root privileges.")" "sudo" "su" fi fi # fakeroot - building as non-root user - if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then + if check_buildenv "fakeroot" "y" && (( EUID > 0 )); then if ! type -p fakeroot >/dev/null; then error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot" ret=1 @@ -1622,7 +2049,7 @@ check_software() { fi # gpg - package signing - if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then + if [[ $SIGNPKG == 'y' ]] || { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; }; then if ! type -p gpg >/dev/null; then error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg" ret=1 @@ -1646,7 +2073,7 @@ check_software() { fi # upx - binary compression - if [[ $(check_option upx) == 'y' ]]; then + if check_option "upx" "y"; then if ! type -p upx >/dev/null; then error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx" ret=1 @@ -1654,7 +2081,7 @@ check_software() { fi # distcc - compilation with distcc - if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then + if check_buildenv "distcc" "y" && ! check_option "distcc" "n" ]]; then if ! type -p distcc >/dev/null; then error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc" ret=1 @@ -1662,7 +2089,7 @@ check_software() { fi # ccache - compilation with ccache - if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then + if check_buildenv "ccache" "y" && ! check_option "ccache" "n"; then if ! type -p ccache >/dev/null; then error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache" ret=1 @@ -1670,7 +2097,7 @@ check_software() { fi # strip - strip symbols from binaries/libraries - if [[ $(check_option strip) = "y" ]]; then + if check_option "strip" "y"; then if ! type -p strip >/dev/null; then error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip" ret=1 @@ -1678,7 +2105,7 @@ check_software() { fi # gzip - compressig man and info pages - if [[ $(check_option zipman) = "y" ]]; then + if check_option "zipman" "y"; then if ! type -p gzip >/dev/null; then error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip" ret=1 @@ -1688,110 +2115,50 @@ check_software() { return $ret } -devel_check() { - newpkgver="" - - # Do not update pkgver if --holdver is set, when building a source package, repackaging, - # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w) - if (( HOLDVER || SOURCEONLY || REPKG )) || - [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = /dev/stdin ]]; then - return - fi - - if [[ -z $FORCE_VER ]]; then - # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so. - # This will only be used on the first call to makepkg; subsequent - # calls to makepkg via fakeroot will explicitly pass the version - # number to avoid having to determine the version number twice. - # Also do a check to make sure we have the VCS tool available. - oldpkgver=$pkgver - if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then - if ! type -p darcs >/dev/null; then - warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "darcs" "darcs" - return 0 - fi - msg "$(gettext "Determining latest %s revision...")" 'darcs' - newpkgver=$(date +%Y%m%d) - elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then - if ! type -p cvs >/dev/null; then - warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "cvs" "cvs" - return 0 - fi - msg "$(gettext "Determining latest %s revision...")" 'cvs' - newpkgver=$(date +%Y%m%d) - elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then - if ! type -p git >/dev/null; then - warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "git" "git" - return 0 - fi - msg "$(gettext "Determining latest %s revision...")" 'git' - newpkgver=$(date +%Y%m%d) - elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then - if ! type -p svn >/dev/null; then - warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "svn" "svn" - return 0 - fi - msg "$(gettext "Determining latest %s revision...")" 'svn' - newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p') - elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then - if ! type -p bzr >/dev/null; then - warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "bzr" "bzr" - return 0 - fi - msg "$(gettext "Determining latest %s revision...")" 'bzr' - newpkgver=$(bzr revno ${_bzrtrunk}) - elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then - if ! type -p hg >/dev/null; then - warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "hg" "hg" - return 0 - fi - msg "$(gettext "Determining latest %s revision...")" 'hg' - if [[ -d ./src/$_hgrepo ]] ; then - cd ./src/$_hgrepo - local ret=0 - hg pull || ret=$? - if (( ! ret )); then - hg update - elif (( ret != 1 )); then - return 1 - fi +check_build_status() { + if (( ! SPLITPKG )); then + fullver=$(get_full_version) + pkgarch=$(get_pkg_arch) + if [[ -f $PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT} ]] \ + && ! (( FORCE || SOURCEONLY || NOBUILD )); then + if (( INSTALL )); then + warning "$(gettext "A package has already been built, installing existing package...")" + install_package + exit $? else - [[ ! -d ./src/ ]] && mkdir ./src/ - hg clone $_hgroot/$_hgrepo ./src/$_hgrepo - cd ./src/$_hgrepo + error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f" + exit 1 fi - newpkgver=$(hg tip --template "{rev}") - cd ../../ fi - - if [[ -n $newpkgver ]]; then - msg2 "$(gettext "Version found: %s")" "$newpkgver" - fi - else - # Version number retrieved from fakeroot->makepkg argument - newpkgver=$FORCE_VER - fi -} - -devel_update() { - # This is lame, but if we're wanting to use an updated pkgver for - # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with - # the new pkgver and then re-source it. This is the most robust - # method for dealing with PKGBUILDs that use, e.g.: - # - # pkgver=23 - # ... - # _foo=pkgver - # - if [[ -n $newpkgver ]]; then - if [[ $newpkgver != "$pkgver" ]]; then - if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then - @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE" - @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE" - source "$BUILDFILE" + allpkgbuilt=1 + somepkgbuilt=0 + for pkg in ${pkgname[@]}; do + fullver=$(get_full_version $pkg) + pkgarch=$(get_pkg_arch $pkg) + if [[ -f $PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT} ]]; then + somepkgbuilt=1 + else + allpkgbuilt=0 + fi + done + if ! (( FORCE || SOURCEONLY || NOBUILD )); then + if (( allpkgbuilt )); then + if (( INSTALL )); then + warning "$(gettext "The package group has already been built, installing existing packages...")" + install_package + exit $? + else + error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f" + exit 1 + fi + fi + if (( somepkgbuilt && ! PKGVERFUNC )); then + error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f" + exit 1 fi fi + unset allpkgbuilt somepkgbuilt fi } @@ -1837,18 +2204,18 @@ canonicalize_path() { if [[ -d $path ]]; then ( - cd "$path" + cd_safe "$path" pwd -P ) else - echo "$path" + printf "%s\n" "$path" fi } -m4_include(library/parse_options.sh) +m4_include(library/parseopts.sh) usage() { - printf "makepkg (pacman) %s\n" "$myver" + printf "makepkg (pacman) %s\n" "$makepkg_version" echo printf -- "$(gettext "Usage: %s [options]")\n" "$0" echo @@ -1873,7 +2240,7 @@ usage() { printf -- "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg" printf -- "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT" printf -- "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf" - printf -- "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT" + printf -- "$(gettext " --holdver Do not update VCS sources")\n" printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg" printf -- "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT" printf -- "$(gettext " --nosign Do not create a signature for the package")\n" @@ -1886,6 +2253,7 @@ usage() { printf -- "$(gettext "These options can be passed to %s:")\n" "pacman" echo printf -- "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")\n" + printf -- "$(gettext " --asdeps Install packages as non-explicitly installed")\n" printf -- "$(gettext " --noprogressbar Do not show a progress bar when downloading files")\n" echo printf -- "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT" @@ -1893,7 +2261,7 @@ usage() { } version() { - printf "makepkg (pacman) %s\n" "$myver" + printf "makepkg (pacman) %s\n" "$makepkg_version" printf -- "$(gettext "\ Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>.\n\ Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\ @@ -1906,7 +2274,7 @@ There is NO WARRANTY, to the extent permitted by law.\n")" # determine whether we have gettext; make it a no-op if we do not if ! type -p gettext >/dev/null; then gettext() { - echo "$@" + printf "%s\n" "$@" } fi @@ -1914,23 +2282,25 @@ ARGLIST=("$@") # Parse Command Line Options. OPT_SHORT="AcdefFghiLmop:rRsSV" -OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps" -OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck" -OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps" -OPT_LONG+=",repackage,skipchecksums,skipinteg,skippgpcheck,sign,source,syncdeps" -OPT_LONG+=",version,config:" +OPT_LONG=('allsource' 'asroot' 'check' 'clean' 'config:' 'force' 'geninteg' + 'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'nobuild' 'nocolor' + 'nocheck' 'nodeps' 'noextract' 'nosign' 'pkg:' 'repackage' 'rmdeps' + 'skipchecksums' 'skipinteg' 'skippgpcheck' 'skippgpcheck' 'sign' + 'source' 'syncdeps' 'version') # Pacman Options -OPT_LONG+=",noconfirm,noprogressbar" -if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then - echo; usage; exit 1 # E_INVALID_OPTION; +OPT_LONG+=('asdeps' 'noconfirm' 'noprogressbar') + +if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then + exit 1 # E_INVALID_OPTION; fi -eval set -- "$OPT_TEMP" -unset OPT_SHORT OPT_LONG OPT_TEMP +set -- "${OPTRET[@]}" +unset OPT_SHORT OPT_LONG OPTRET while true; do case "$1" in # Pacman Options + --asdeps) ASDEPS=1;; --noconfirm) PACMAN_OPTS+=" --noconfirm" ;; --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;; @@ -1944,8 +2314,6 @@ while true; do -d|--nodeps) NODEPS=1 ;; -e|--noextract) NOEXTRACT=1 ;; -f|--force) FORCE=1 ;; - #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver - --forcever) shift; FORCE_VER=$1;; -F) INFAKEROOT=1 ;; -g|--geninteg) GENINTEG=1 ;; --holdver) HOLDVER=1 ;; @@ -1957,7 +2325,7 @@ while true; do --nosign) SIGNPKG='n' ;; -o|--nobuild) NOBUILD=1 ;; -p) shift; BUILDFILE=$1 ;; - --pkg) shift; PKGLIST=($1) ;; + --pkg) shift; IFS=, read -ra p <<<"$1"; PKGLIST+=("${p[@]}"); unset p ;; -r|--rmdeps) RMDEPS=1 ;; -R|--repackage) REPKG=1 ;; --skipchecksums) SKIPCHECKSUMS=1 ;; @@ -1970,8 +2338,7 @@ while true; do -h|--help) usage; exit 0 ;; # E_OK -V|--version) version; exit 0 ;; # E_OK - --) OPT_IND=0; shift; break;; - *) usage; exit 1 ;; # E_INVALID_OPTION + --) OPT_IND=0; shift; break 2;; esac shift done @@ -1983,7 +2350,6 @@ for signal in TERM HUP QUIT; do done trap 'trap_exit INT "$(gettext "Aborted by user! Exiting...")"' INT trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' ERR -set -E # preserve environment variables and canonicalize path [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST}) @@ -1993,13 +2359,14 @@ set -E [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT} [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT} [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY} +[[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER} # default config is makepkg.conf MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf} # Source the config file; fail if it is not found if [[ -r $MAKEPKG_CONF ]]; then - source "$MAKEPKG_CONF" + source_safe "$MAKEPKG_CONF" else error "$(gettext "%s not found.")" "$MAKEPKG_CONF" plain "$(gettext "Aborting...")" @@ -2009,7 +2376,7 @@ fi # Source user-specific makepkg.conf overrides, but only if no override config # file was specified if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then - source ~/.makepkg.conf + source_safe ~/.makepkg.conf fi # set pacman command if not already defined @@ -2017,7 +2384,7 @@ PACMAN=${PACMAN:-pacman} # check if messages are to be printed using color unset ALL_OFF BOLD BLUE GREEN RED YELLOW -if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then +if [[ -t 2 && ! $USE_COLOR = "n" ]] && check_buildenv "color" "y"; then # prefer terminal safe colored and bold text when tput is supported if tput setaf 0 &>/dev/null; then ALL_OFF="$(tput sgr0)" @@ -2041,8 +2408,11 @@ readonly ALL_OFF BOLD BLUE GREEN RED YELLOW BUILDDIR=${_BUILDDIR:-$BUILDDIR} BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined if [[ ! -d $BUILDDIR ]]; then - mkdir -p "$BUILDDIR" || - error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR" + if ! mkdir -p "$BUILDDIR"; then + error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR" + plain "$(gettext "Aborting...")" + exit 1 + fi chmod a-s "$BUILDDIR" fi if [[ ! -w $BUILDDIR ]]; then @@ -2050,8 +2420,6 @@ if [[ ! -w $BUILDDIR ]]; then plain "$(gettext "Aborting...")" exit 1 fi -srcdir="$BUILDDIR/src" -pkgdir="$BUILDDIR/pkg" PKGDEST=${_PKGDEST:-$PKGDEST} PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined @@ -2080,12 +2448,7 @@ fi PKGEXT=${_PKGEXT:-$PKGEXT} SRCEXT=${_SRCEXT:-$SRCEXT} GPGKEY=${_GPGKEY:-$GPGKEY} - -if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then - # The '\\0' is here to prevent gettext from thinking --holdver is an option - error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever" - exit 1 -fi +PACKAGER=${_PACKAGER:-$PACKAGER} if (( ! INFAKEROOT )); then if (( EUID == 0 && ! ASROOT )); then @@ -2099,7 +2462,7 @@ use the %s option.")" "makepkg" "--asroot" error "$(gettext "The %s option is meant for the root user only. Please\n\ rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot" exit 1 # $E_USER_ABORT - elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then + elif (( EUID > 0 )) && ! check_buildenv "fakeroot" "y"; then warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\ ownership of the packaged files. Try using the %s environment by\n\ placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF" @@ -2124,9 +2487,7 @@ if [[ ! -f $BUILDFILE ]]; then else # PKGBUILD passed through a pipe BUILDFILE=/dev/stdin - shopt -u extglob - source "$BUILDFILE" - shopt -s extglob + source_safe "$BUILDFILE" fi else crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true) @@ -2138,48 +2499,54 @@ else if [[ ${BUILDFILE:0:1} != "/" ]]; then BUILDFILE="$startdir/$BUILDFILE" fi - shopt -u extglob - source "$BUILDFILE" - shopt -s extglob + source_safe "$BUILDFILE" fi # set defaults if they weren't specified in buildfile pkgbase=${pkgbase:-${pkgname[0]}} epoch=${epoch:-0} +if [[ $BUILDDIR = "$startdir" ]]; then + srcdir="$BUILDDIR/src" + pkgdir="$BUILDDIR/pkg" +else + srcdir="$BUILDDIR/$pkgbase/src" + pkgdir="$BUILDDIR/$pkgbase/pkg" +fi + if (( GENINTEG )); then mkdir -p "$srcdir" chmod a-s "$srcdir" - cd "$srcdir" - download_sources + cd_safe "$srcdir" + download_sources fast generate_checksums exit 0 # $E_OK fi +if declare -f pkgver >/dev/null; then + PKGVERFUNC=1 +fi + # check the PKGBUILD for some basic requirements check_sanity || exit 1 # check we have the software required to process the PKGBUILD check_software || exit 1 -# We need to run devel_update regardless of whether we are in the fakeroot -# build process so that if the user runs makepkg --forcever manually, we -# 1) output the correct pkgver, and 2) use the correct filename when -# checking if the package file already exists - fixes FS #9194 -devel_check -devel_update - if (( ${#pkgname[@]} > 1 )); then SPLITPKG=1 fi # test for available PKGBUILD functions +if declare -f prepare >/dev/null; then + PREPAREFUNC=1 +fi if declare -f build >/dev/null; then BUILDFUNC=1 fi if declare -f check >/dev/null; then # "Hide" check() function if not going to be run - if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then + if [[ $RUN_CHECK = 'y' ]] || { ! check_buildenv "check" "n" && [[ $RUN_CHECK != "n" ]]; }; then CHECKFUNC=1 fi fi @@ -2195,8 +2562,7 @@ if [[ -n "${PKGLIST[@]}" ]]; then fi # check if gpg signature is to be created and if signing key is valid -[[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign) -if [[ $SIGNPKG == 'y' ]]; then +if { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; } || [[ $SIGNPKG == 'y' ]]; then if ! gpg --list-key ${GPGKEY} &>/dev/null; then if [[ ! -z $GPGKEY ]]; then error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}" @@ -2207,50 +2573,8 @@ if [[ $SIGNPKG == 'y' ]]; then fi fi - -if (( ! SPLITPKG )); then - fullver=$(get_full_version) - if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \ - || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \ - && ! (( FORCE || SOURCEONLY || NOBUILD )); then - if (( INSTALL )); then - warning "$(gettext "A package has already been built, installing existing package...")" - install_package - exit $? - else - error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f" - exit 1 - fi - fi -else - allpkgbuilt=1 - somepkgbuilt=0 - for pkg in ${pkgname[@]}; do - fullver=$(get_full_version $pkg) - if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \ - || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then - somepkgbuilt=1 - else - allpkgbuilt=0 - fi - done - if ! (( FORCE || SOURCEONLY || NOBUILD )); then - if (( allpkgbuilt )); then - if (( INSTALL )); then - warning "$(gettext "The package group has already been built, installing existing packages...")" - install_package - exit $? - else - error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f" - exit 1 - fi - fi - if (( somepkgbuilt )); then - error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f" - exit 1 - fi - fi - unset allpkgbuilt somepkgbuilt +if (( ! PKGVERFUNC )); then + check_build_status fi # Run the bare minimum in fakeroot @@ -2300,17 +2624,18 @@ if (( SOURCEONLY )); then # Get back to our src directory so we can begin with sources. mkdir -p "$srcdir" chmod a-s "$srcdir" - cd "$srcdir" - if ( (( ! SKIPCHECKSUMS )) || \ - ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \ - (( SOURCEONLY == 2 )); then + cd_safe "$srcdir" + if (( SOURCEONLY == 2 )); then download_sources + elif ( (( ! SKIPCHECKSUMS )) || \ + ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then + download_sources fast fi check_source_integrity - cd "$startdir" + cd_safe "$startdir" # if we are root or if fakeroot is not enabled, then we don't use it - if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then + if ! check_buildenv "fakeroot" "y" || (( EUID == 0 )); then create_srcpackage else enter_fakeroot @@ -2320,9 +2645,9 @@ if (( SOURCEONLY )); then exit 0 fi -if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then - # no warning message needed for nobuild, repkg - if (( NODEPS || ( REPKG && PKGFUNC ) )); then +if (( NODEPS || (NOBUILD && !DEP_BIN ) )); then + # no warning message needed for nobuild + if (( NODEPS )); then warning "$(gettext "Skipping dependency checks.")" fi elif type -p "${PACMAN%% *}" >/dev/null; then @@ -2363,7 +2688,7 @@ umask 0022 # get back to our src directory so we can begin with sources mkdir -p "$srcdir" chmod a-s "$srcdir" -cd "$srcdir" +cd_safe "$srcdir" if (( NOEXTRACT )); then warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/" @@ -2386,6 +2711,9 @@ else download_sources check_source_integrity extract_sources + if (( PREPAREFUNC )); then + run_prepare + fi fi if (( NOBUILD )); then @@ -2399,12 +2727,11 @@ else fi mkdir -p "$pkgdir" chmod a-s "$pkgdir" - cd "$startdir" + cd_safe "$startdir" # if we are root or if fakeroot is not enabled, then we don't use it - if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then + if ! check_buildenv "fakeroot" "y" || (( EUID == 0 )); then if (( ! REPKG )); then - devel_update (( BUILDFUNC )) && run_build (( CHECKFUNC )) && run_check fi @@ -2426,10 +2753,9 @@ else fi else if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then - devel_update (( BUILDFUNC )) && run_build (( CHECKFUNC )) && run_check - cd "$startdir" + cd_safe "$startdir" fi enter_fakeroot |