mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-22 15:58:50 -05:00
b8ef22312b
This applies to pkgver, pkgrel, and epoch and ensures that any trailing whitespace outside of the context of the variable declaration itself is properly trimmed. The Bash parser will ignore this, and so should we. We don't need to worry about leading space because it would force a syntax error, or fail validation. Signed-off-by: Dave Reisner <dreisner@archlinux.org> Signed-off-by: Dan McGee <dan@archlinux.org>
2403 lines
66 KiB
Bash
2403 lines
66 KiB
Bash
#!/bin/bash -e
|
|
#
|
|
# makepkg - make packages compatible for use with pacman
|
|
# @configure_input@
|
|
#
|
|
# Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
|
|
# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
|
# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
|
# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
|
# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
|
|
# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
|
|
# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
|
|
#
|
|
# 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, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
# makepkg uses quite a few external programs during its execution. You
|
|
# need to have at least the following installed for makepkg to function:
|
|
# awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
|
|
# gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
|
|
|
|
# gettext initialization
|
|
export TEXTDOMAIN='pacman-scripts'
|
|
export TEXTDOMAINDIR='@localedir@'
|
|
|
|
# file -i does not work on Mac OSX unless legacy mode is set
|
|
export COMMAND_MODE='legacy'
|
|
|
|
myver='@PACKAGE_VERSION@'
|
|
confdir='@sysconfdir@'
|
|
BUILDSCRIPT='@BUILDSCRIPT@'
|
|
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' \
|
|
'groups' 'depends' 'optdepends' 'provides' 'conflicts' \
|
|
'replaces' 'backup' 'options' 'install' 'changelog')
|
|
readonly -a packaging_options other_options splitpkg_overrides
|
|
|
|
# Options
|
|
ASROOT=0
|
|
CLEANUP=0
|
|
DEP_BIN=0
|
|
FORCE=0
|
|
INFAKEROOT=0
|
|
GENINTEG=0
|
|
SKIPCHECKSUMS=0
|
|
SKIPPGPCHECK=0
|
|
INSTALL=0
|
|
NOBUILD=0
|
|
NODEPS=0
|
|
NOEXTRACT=0
|
|
RMDEPS=0
|
|
REPKG=0
|
|
LOGGING=0
|
|
SOURCEONLY=0
|
|
IGNOREARCH=0
|
|
HOLDVER=0
|
|
BUILDFUNC=0
|
|
CHECKFUNC=0
|
|
PKGFUNC=0
|
|
SPLITPKG=0
|
|
PKGLIST=()
|
|
SIGNPKG=''
|
|
|
|
# Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
|
|
# when dealing with svn/cvs/etc PKGBUILDs.
|
|
FORCE_VER=""
|
|
|
|
PACMAN_OPTS=
|
|
|
|
shopt -s extglob
|
|
|
|
### SUBROUTINES ###
|
|
|
|
plain() {
|
|
local mesg=$1; shift
|
|
printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
|
|
}
|
|
|
|
msg() {
|
|
local mesg=$1; shift
|
|
printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
|
|
}
|
|
|
|
msg2() {
|
|
local mesg=$1; shift
|
|
printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
|
|
}
|
|
|
|
warning() {
|
|
local mesg=$1; shift
|
|
printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
|
|
}
|
|
|
|
error() {
|
|
local mesg=$1; shift
|
|
printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
|
|
}
|
|
|
|
|
|
##
|
|
# Special exit call for traps, Don't print any error messages when inside,
|
|
# the fakeroot call, the error message will be printed by the main call.
|
|
##
|
|
trap_exit() {
|
|
if (( ! INFAKEROOT )); then
|
|
echo
|
|
error "$@"
|
|
fi
|
|
[[ -n $srclinks ]] && rm -rf "$srclinks"
|
|
exit 1
|
|
}
|
|
|
|
|
|
##
|
|
# Clean up function. Called automatically when the script exits.
|
|
##
|
|
clean_up() {
|
|
local EXIT_CODE=$?
|
|
|
|
if (( INFAKEROOT )); then
|
|
# Don't clean up when leaving fakeroot, we're not done yet.
|
|
return
|
|
fi
|
|
|
|
if (( ! EXIT_CODE && CLEANUP )); then
|
|
local pkg file
|
|
|
|
# If it's a clean exit and -c/--clean has been passed...
|
|
msg "$(gettext "Cleaning up...")"
|
|
rm -rf "$pkgdir" "$srcdir"
|
|
if [[ -n $pkgbase ]]; then
|
|
local fullver=$(get_full_version)
|
|
# Can't do this unless the BUILDSCRIPT has been sourced.
|
|
if (( BUILDFUNC )); then
|
|
rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
|
|
fi
|
|
if (( CHECKFUNC )); then
|
|
rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
|
|
fi
|
|
if (( PKGFUNC )); then
|
|
rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
|
|
elif (( SPLITPKG )); then
|
|
for pkg in ${pkgname[@]}; do
|
|
rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
|
|
done
|
|
fi
|
|
|
|
# clean up dangling symlinks to packages
|
|
for pkg in ${pkgname[@]}; do
|
|
for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do
|
|
if [[ -h $file && ! -e $file ]]; then
|
|
rm -f $file
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
fi
|
|
|
|
remove_deps
|
|
}
|
|
|
|
|
|
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
|
|
}
|
|
|
|
|
|
# a source entry can have two forms :
|
|
# 1) "filename::http://path/to/file"
|
|
# 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")"
|
|
|
|
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
|
|
}
|
|
|
|
# extract the filename from a source entry
|
|
get_filename() {
|
|
# if a filename is specified, use it
|
|
local filename="${1%%::*}"
|
|
# if it is just an URL, we only keep the last component
|
|
echo "${filename##*/}"
|
|
}
|
|
|
|
# extract the URL from a source entry
|
|
get_url() {
|
|
# strip an eventual filename
|
|
echo "${1#*::}"
|
|
}
|
|
|
|
##
|
|
# usage : get_full_version( [$pkgname] )
|
|
# return : full version spec, including epoch (if necessary), pkgver, pkgrel
|
|
##
|
|
get_full_version() {
|
|
if [[ -z $1 ]]; then
|
|
if [[ $epoch ]] && (( ! $epoch )); then
|
|
echo $pkgver-$pkgrel
|
|
else
|
|
echo $epoch:$pkgver-$pkgrel
|
|
fi
|
|
else
|
|
for i in pkgver pkgrel epoch; do
|
|
local indirect="${i}_override"
|
|
eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
|
|
[[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
|
|
done
|
|
if (( ! $epoch_override )); then
|
|
echo $pkgver_override-$pkgrel_override
|
|
else
|
|
echo $epoch_override:$pkgver_override-$pkgrel_override
|
|
fi
|
|
fi
|
|
}
|
|
|
|
##
|
|
# 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
|
|
##
|
|
check_option() {
|
|
local ret=$(in_opt_array "$1" ${options[@]})
|
|
if [[ $ret != '?' ]]; then
|
|
echo $ret
|
|
return
|
|
fi
|
|
|
|
# fall back to makepkg.conf options
|
|
ret=$(in_opt_array "$1" ${OPTIONS[@]})
|
|
if [[ $ret != '?' ]]; then
|
|
echo $ret
|
|
return
|
|
fi
|
|
|
|
echo '?' # Not Found
|
|
}
|
|
|
|
|
|
##
|
|
# Check if option is present in BUILDENV
|
|
#
|
|
# usage : check_buildenv( $option )
|
|
# return : y - enabled
|
|
# n - disabled
|
|
# ? - not found
|
|
##
|
|
check_buildenv() {
|
|
in_opt_array "$1" ${BUILDENV[@]}
|
|
}
|
|
|
|
|
|
##
|
|
# usage : in_opt_array( $needle, $haystack )
|
|
# return : y - enabled
|
|
# n - disabled
|
|
# ? - not found
|
|
##
|
|
in_opt_array() {
|
|
local needle=$1; shift
|
|
|
|
local opt
|
|
for opt in "$@"; do
|
|
if [[ $opt = $needle ]]; then
|
|
echo 'y' # Enabled
|
|
return
|
|
elif [[ $opt = "!$needle" ]]; then
|
|
echo 'n' # Disabled
|
|
return
|
|
fi
|
|
done
|
|
|
|
echo '?' # Not Found
|
|
}
|
|
|
|
|
|
##
|
|
# usage : in_array( $needle, $haystack )
|
|
# return : 0 - found
|
|
# 1 - not found
|
|
##
|
|
in_array() {
|
|
local needle=$1; shift
|
|
local item
|
|
for item in "$@"; do
|
|
[[ $item = $needle ]] && return 0 # Found
|
|
done
|
|
return 1 # Not Found
|
|
}
|
|
|
|
source_has_signatures(){
|
|
local file
|
|
for file in "${source[@]}"; do
|
|
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
|
|
printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
|
|
if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
|
|
if type -p sudo >/dev/null; then
|
|
cmd="sudo $cmd"
|
|
else
|
|
cmd="su root -c '$cmd'"
|
|
fi
|
|
fi
|
|
eval "$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
|
|
|
|
if (( ret == 127 )); then #unresolved deps
|
|
echo "$pmout"
|
|
elif (( ret )); then
|
|
error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
|
|
return "$ret"
|
|
fi
|
|
}
|
|
|
|
handle_deps() {
|
|
local R_DEPS_SATISFIED=0
|
|
local R_DEPS_MISSING=1
|
|
|
|
(( $# == 0 )) && return $R_DEPS_SATISFIED
|
|
|
|
local deplist="$*"
|
|
|
|
if (( ! DEP_BIN )); then
|
|
return $R_DEPS_MISSING
|
|
fi
|
|
|
|
if (( DEP_BIN )); then
|
|
# install missing deps from binary packages (using pacman -S)
|
|
msg "$(gettext "Installing missing dependencies...")"
|
|
|
|
if ! run_pacman -S --asdeps $deplist; then
|
|
error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
fi
|
|
|
|
# we might need the new system environment
|
|
# avoid triggering the ERR trap and exiting
|
|
set +e
|
|
local restoretrap=$(trap -p ERR)
|
|
trap - ERR
|
|
source /etc/profile &>/dev/null
|
|
eval $restoretrap
|
|
set -e
|
|
|
|
return $R_DEPS_SATISFIED
|
|
}
|
|
|
|
resolve_deps() {
|
|
local R_DEPS_SATISFIED=0
|
|
local R_DEPS_MISSING=1
|
|
|
|
# deplist cannot be declared like this: local deplist=$(foo)
|
|
# Otherwise, the return value will depend on the assignment.
|
|
local deplist
|
|
deplist="$(set +E; check_deps $*)" || exit 1
|
|
[[ -z $deplist ]] && return $R_DEPS_SATISFIED
|
|
|
|
if handle_deps $deplist; then
|
|
# check deps again to make sure they were resolved
|
|
deplist="$(set +E; check_deps $*)" || exit 1
|
|
[[ -z $deplist ]] && return $R_DEPS_SATISFIED
|
|
fi
|
|
|
|
msg "$(gettext "Missing Dependencies:")"
|
|
local dep
|
|
for dep in $deplist; do
|
|
msg2 "$dep"
|
|
done
|
|
|
|
return $R_DEPS_MISSING
|
|
}
|
|
|
|
remove_deps() {
|
|
(( ! RMDEPS )) && return
|
|
|
|
# check for packages removed during dependency install (e.g. due to conflicts)
|
|
# removing all installed packages is risky in this case
|
|
if [[ -n $(comm -23 <(printf "%s\n" "${original_pkglist[@]}") \
|
|
<(printf "%s\n" "${current_pkglist[@]}")) ]]; then
|
|
warning "$(gettext "Failed to remove installed dependencies.")"
|
|
return 0
|
|
fi
|
|
|
|
local deplist=($(comm -13 <(printf "%s\n" "${original_pkglist[@]}") \
|
|
<(printf "%s\n" "${current_pkglist[@]}")))
|
|
(( ${#deplist[@]} == 0 )) && return
|
|
|
|
msg "Removing installed dependencies..."
|
|
# exit cleanly on failure to remove deps as package has been built successfully
|
|
if ! run_pacman -Rn ${deplist[@]}; then
|
|
warning "$(gettext "Failed to remove installed dependencies.")"
|
|
return 0
|
|
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=$(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=()
|
|
|
|
for integ in md5 sha1 sha256 sha384 sha512; do
|
|
local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
|
|
if [[ -n "$integrity_sums" ]]; then
|
|
integlist=(${integlist[@]} $integ)
|
|
fi
|
|
done
|
|
|
|
if (( ${#integlist[@]} > 0 )); then
|
|
echo ${integlist[@]}
|
|
else
|
|
echo ${INTEGRITY_CHECK[@]}
|
|
fi
|
|
}
|
|
|
|
generate_checksums() {
|
|
msg "$(gettext "Generating checksums for source files...")"
|
|
plain ""
|
|
|
|
if ! type -p openssl >/dev/null; then
|
|
error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
|
|
exit 1 # $E_MISSING_PROGRAM
|
|
fi
|
|
|
|
local integlist
|
|
if (( $# == 0 )); then
|
|
integlist=$(get_integlist)
|
|
else
|
|
integlist=$@
|
|
fi
|
|
|
|
local integ
|
|
for integ in ${integlist[@]}; do
|
|
case "$integ" in
|
|
md5|sha1|sha256|sha384|sha512) : ;;
|
|
*)
|
|
error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
|
|
exit 1;; # $E_CONFIG_ERROR
|
|
esac
|
|
|
|
local ct=0
|
|
local numsrc=${#source[@]}
|
|
echo -n "${integ}sums=("
|
|
|
|
local i
|
|
local indent=''
|
|
for (( i = 0; i < ${#integ} + 6; i++ )); do
|
|
indent="$indent "
|
|
done
|
|
|
|
local netfile
|
|
for netfile in "${source[@]}"; do
|
|
local file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
|
|
local sum="$(openssl dgst -${integ} "$file")"
|
|
sum=${sum##* }
|
|
(( ct )) && echo -n "$indent"
|
|
echo -n "'$sum'"
|
|
ct=$(($ct+1))
|
|
(( $ct < $numsrc )) && echo
|
|
done
|
|
|
|
echo ")"
|
|
done
|
|
}
|
|
|
|
check_checksums() {
|
|
(( SKIPCHECKSUMS )) && return 0
|
|
(( ! ${#source[@]} )) && return 0
|
|
|
|
local correlation=0
|
|
local integ required
|
|
for integ in md5 sha1 sha256 sha384 sha512; do
|
|
local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
|
|
if (( ${#integrity_sums[@]} == ${#source[@]} )); then
|
|
msg "$(gettext "Validating source files with %s...")" "${integ}sums"
|
|
correlation=1
|
|
local errors=0
|
|
local idx=0
|
|
local file
|
|
for file in "${source[@]}"; do
|
|
local found=1
|
|
file="$(get_filename "$file")"
|
|
echo -n " $file ... " >&2
|
|
|
|
if ! file="$(get_filepath "$file")"; then
|
|
echo "$(gettext "NOT FOUND")" >&2
|
|
errors=1
|
|
found=0
|
|
fi
|
|
|
|
if (( $found )) ; then
|
|
local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
|
|
local realsum="$(openssl dgst -${integ} "$file")"
|
|
realsum="${realsum##* }"
|
|
if [[ $expectedsum = $realsum ]]; then
|
|
echo "$(gettext "Passed")" >&2
|
|
else
|
|
echo "$(gettext "FAILED")" >&2
|
|
errors=1
|
|
fi
|
|
fi
|
|
|
|
idx=$((idx + 1))
|
|
done
|
|
|
|
if (( errors )); then
|
|
error "$(gettext "One or more files did not pass the validity check!")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
elif (( ${#integrity_sums[@]} )); then
|
|
error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
done
|
|
|
|
if (( ! correlation )); then
|
|
error "$(gettext "Integrity checks are missing.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
}
|
|
|
|
check_pgpsigs() {
|
|
(( SKIPPGPCHECK )) && return 0
|
|
! source_has_signatures && return 0
|
|
|
|
msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
|
|
|
|
local file pubkey
|
|
local warning=0
|
|
local errors=0
|
|
local statusfile=$(mktemp)
|
|
|
|
for file in "${source[@]}"; do
|
|
file="$(get_filename "$file")"
|
|
if [[ ! $file = *.@(sig?(n)|asc) ]]; then
|
|
continue
|
|
fi
|
|
|
|
printf " %s ... " "${file%.*}" >&2
|
|
|
|
if ! file="$(get_filepath "$file")"; then
|
|
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
|
|
errors=1
|
|
continue
|
|
fi
|
|
|
|
if ! sourcefile="$(get_filepath "${file%.*}")"; then
|
|
printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
|
|
errors=1
|
|
continue
|
|
fi
|
|
|
|
if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
|
|
printf '%s' "$(gettext "FAILED")" >&2
|
|
if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
|
|
printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
|
|
warnings=1
|
|
else
|
|
errors=1
|
|
fi
|
|
printf '\n' >&2
|
|
else
|
|
if grep -q "REVKEYSIG" "$statusfile"; then
|
|
printf '%s (%s)' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
|
|
errors=1
|
|
else
|
|
printf '%s' "$(gettext "Passed")" >&2
|
|
if grep -q "EXPSIG" "$statusfile"; then
|
|
printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
|
|
warnings=1
|
|
elif grep -q "EXPKEYSIG" "$statusfile"; then
|
|
printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
|
|
warnings=1
|
|
fi
|
|
fi
|
|
printf '\n' >&2
|
|
fi
|
|
done
|
|
|
|
rm -f "$statusfile"
|
|
|
|
if (( errors )); then
|
|
error "$(gettext "One or more PGP signatures could not be verified!")"
|
|
exit 1
|
|
fi
|
|
|
|
if (( warnings )); then
|
|
warning "$(gettext "Warnings have occurred while verifying the signatures.")"
|
|
plain "$(gettext "Please make sure you really trust them.")"
|
|
fi
|
|
}
|
|
|
|
check_source_integrity() {
|
|
if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
|
|
warning "$(gettext "Skipping all source file integrity checks.")"
|
|
elif (( SKIPCHECKSUMS )); then
|
|
warning "$(gettext "Skipping verification of source file checksums.")"
|
|
check_pgpsigs
|
|
elif (( SKIPPGPCHECK )); then
|
|
warning "$(gettext "Skipping verification of source file PGP signatures.")"
|
|
check_checksums
|
|
else
|
|
check_checksums
|
|
check_pgpsigs
|
|
fi
|
|
}
|
|
|
|
extract_sources() {
|
|
msg "$(gettext "Extracting Sources...")"
|
|
local netfile
|
|
for netfile in "${source[@]}"; do
|
|
local file=$(get_filename "$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
|
|
local file_type=$(file -bizL "$file")
|
|
local ext=${file##*.}
|
|
local cmd=''
|
|
case "$file_type" in
|
|
*application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
|
|
cmd="bsdtar" ;;
|
|
*application/x-gzip*)
|
|
case "$ext" in
|
|
gz|z|Z) cmd="gzip" ;;
|
|
*) continue;;
|
|
esac ;;
|
|
*application/x-bzip*)
|
|
case "$ext" in
|
|
bz2|bz) cmd="bzip2" ;;
|
|
*) continue;;
|
|
esac ;;
|
|
*application/x-xz*)
|
|
case "$ext" in
|
|
xz) cmd="xz" ;;
|
|
*) continue;;
|
|
esac ;;
|
|
*)
|
|
# See if bsdtar can recognize the file
|
|
if bsdtar -tf "$file" -q '*' &>/dev/null; then
|
|
cmd="bsdtar"
|
|
else
|
|
continue
|
|
fi ;;
|
|
esac
|
|
|
|
local ret=0
|
|
msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
|
|
if [[ $cmd = bsdtar ]]; then
|
|
$cmd -xf "$file" || ret=$?
|
|
else
|
|
rm -f "${file%.*}"
|
|
$cmd -dcf "$file" > "${file%.*}" || ret=$?
|
|
fi
|
|
if (( ret )); then
|
|
error "$(gettext "Failed to extract %s")" "$file"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
if (( EUID == 0 )); then
|
|
# change perms of all source files to root user & root group
|
|
chown -R 0:0 "$srcdir"
|
|
fi
|
|
}
|
|
|
|
error_function() {
|
|
if [[ -p $logpipe ]]; then
|
|
rm "$logpipe"
|
|
fi
|
|
# first exit all subshells, then print the error
|
|
if (( ! BASH_SUBSHELL )); then
|
|
error "$(gettext "A failure occurred in %s().")" "$1"
|
|
plain "$(gettext "Aborting...")"
|
|
remove_deps
|
|
fi
|
|
exit 2 # $E_BUILD_FAILED
|
|
}
|
|
|
|
run_function() {
|
|
if [[ -z $1 ]]; then
|
|
return 1
|
|
fi
|
|
local pkgfunc="$1"
|
|
|
|
# clear user-specified buildflags if requested
|
|
if [[ $(check_option buildflags) = "n" ]]; then
|
|
unset CFLAGS CXXFLAGS LDFLAGS
|
|
fi
|
|
|
|
# clear user-specified makeflags if requested
|
|
if [[ $(check_option makeflags) = "n" ]]; then
|
|
unset MAKEFLAGS
|
|
fi
|
|
|
|
msg "$(gettext "Starting %s()...")" "$pkgfunc"
|
|
cd "$srcdir"
|
|
|
|
# ensure all necessary build variables are exported
|
|
export 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"
|
|
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
|
|
|
|
# ensure overridden package variables survive tee with split packages
|
|
logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
|
|
mkfifo "$logpipe"
|
|
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_build() {
|
|
# use distcc if it is requested (check buildenv and PKGBUILD opts)
|
|
if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "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
|
|
[[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
|
|
fi
|
|
|
|
run_function "build"
|
|
}
|
|
|
|
run_check() {
|
|
run_function "check"
|
|
}
|
|
|
|
run_package() {
|
|
local pkgfunc
|
|
if [[ -z $1 ]]; then
|
|
pkgfunc="package"
|
|
else
|
|
pkgfunc="package_$1"
|
|
fi
|
|
|
|
run_function "$pkgfunc"
|
|
}
|
|
|
|
tidy_install() {
|
|
cd "$pkgdir"
|
|
msg "$(gettext "Tidying install...")"
|
|
|
|
if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
|
|
msg2 "$(gettext "Removing doc files...")"
|
|
rm -rf ${DOC_DIRS[@]}
|
|
fi
|
|
|
|
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 -- '{}' \;
|
|
else
|
|
rm -f ${pt}
|
|
fi
|
|
done
|
|
fi
|
|
|
|
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
|
|
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
|
|
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
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
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
|
|
case "$(file -bi "$binary")" in
|
|
*application/x-sharedlib*) # Libraries (.so)
|
|
strip $STRIP_SHARED "$binary";;
|
|
*application/x-archive*) # Libraries (.a)
|
|
strip $STRIP_STATIC "$binary";;
|
|
*application/x-executable*) # Binaries
|
|
strip $STRIP_BINARIES "$binary";;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
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
|
|
msg2 "$(gettext "Removing empty directories...")"
|
|
find . -depth -type d -empty -delete
|
|
fi
|
|
|
|
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
|
|
if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
|
|
upx $UPXFLAGS "$binary" &>/dev/null ||
|
|
warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
find_libdepends() {
|
|
local libdepends
|
|
find "$pkgdir" -type f -perm -u+x | 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
|
|
# 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
|
|
# extract the library name: libfoo.so
|
|
soname="${sofile%%\.so\.*}.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}")
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
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}")
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
write_pkginfo() {
|
|
local builddate=$(date -u "+%s")
|
|
if [[ -n $PACKAGER ]]; then
|
|
local packager="$PACKAGER"
|
|
else
|
|
local packager="Unknown Packager"
|
|
fi
|
|
local size="$(@DUPATH@ -sk)"
|
|
size="$(( ${size%%[^0-9]*} * 1024 ))"
|
|
|
|
msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
|
|
echo "# Generated by makepkg $myver"
|
|
if (( INFAKEROOT )); then
|
|
echo "# using $(fakeroot -v)"
|
|
fi
|
|
echo "# $(LC_ALL=C date -u)"
|
|
echo "pkgname = $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[@]}"
|
|
|
|
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
|
|
if [[ ! $libdepends =~ (^|\s)${it}=.* ]]; 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
|
|
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_package() {
|
|
cd "$pkgdir"
|
|
|
|
# check existence of backup files
|
|
local file
|
|
for file in "${backup[@]}"; do
|
|
if [[ ! -f $file ]]; then
|
|
warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
|
|
fi
|
|
done
|
|
|
|
# check for references to the build and package directory
|
|
if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
|
|
warning "$(gettext "Package contains reference to %s")" "\$srcdir"
|
|
fi
|
|
if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
|
|
warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
|
|
fi
|
|
|
|
}
|
|
|
|
create_package() {
|
|
if [[ ! -d $pkgdir ]]; then
|
|
error "$(gettext "Missing %s directory.")" "pkg/"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_MISSING_PKGDIR
|
|
fi
|
|
|
|
check_package
|
|
|
|
cd "$pkgdir"
|
|
msg "$(gettext "Creating package...")"
|
|
|
|
local nameofpkg
|
|
if [[ -z $1 ]]; then
|
|
nameofpkg="$pkgname"
|
|
else
|
|
nameofpkg="$1"
|
|
fi
|
|
|
|
if [[ $arch = "any" ]]; then
|
|
PKGARCH="any"
|
|
else
|
|
PKGARCH=$CARCH
|
|
fi
|
|
|
|
write_pkginfo $nameofpkg > .PKGINFO
|
|
|
|
local comp_files=".PKGINFO"
|
|
|
|
# check for changelog/install files
|
|
for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
|
|
IFS='/' read -r orig dest < <(printf '%s\n' "$i")
|
|
|
|
if [[ -n ${!orig} ]]; then
|
|
msg2 "$(gettext "Adding %s file...")" "$orig"
|
|
cp "$startdir/${!orig}" "$dest"
|
|
chmod 644 "$dest"
|
|
comp_files+=" $dest"
|
|
fi
|
|
done
|
|
|
|
# tar it up
|
|
msg2 "$(gettext "Compressing package...")"
|
|
|
|
local fullver=$(get_full_version)
|
|
local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}"
|
|
local ret=0
|
|
|
|
[[ -f $pkg_file ]] && rm -f "$pkg_file"
|
|
[[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
|
|
|
|
# when fileglobbing, we want * in an empty directory to expand to
|
|
# the null string rather than itself
|
|
shopt -s nullglob
|
|
# TODO: Maybe this can be set globally for robustness
|
|
shopt -s -o pipefail
|
|
# 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 * |
|
|
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) cat ;;
|
|
*) warning "$(gettext "'%s' is not a valid archive extension.")" \
|
|
"$PKGEXT"; cat ;;
|
|
esac > "${pkg_file}" || ret=$?
|
|
|
|
shopt -u nullglob
|
|
shopt -u -o pipefail
|
|
|
|
if (( ret )); then
|
|
error "$(gettext "Failed to create package file.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
|
|
create_signature "$pkg_file"
|
|
|
|
if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
|
|
rm -f "${pkg_file/$PKGDEST/$startdir}"
|
|
ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
|
|
ret=$?
|
|
if [[ -f $pkg_file.sig ]]; then
|
|
rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
|
|
ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
|
|
fi
|
|
fi
|
|
|
|
if (( ret )); then
|
|
warning "$(gettext "Failed to create symlink to package file.")"
|
|
fi
|
|
}
|
|
|
|
create_signature() {
|
|
if [[ $SIGNPKG != 'y' ]]; then
|
|
return
|
|
fi
|
|
local ret=0
|
|
local filename="$1"
|
|
msg "$(gettext "Signing package...")"
|
|
|
|
local SIGNWITHKEY=""
|
|
if [[ -n $GPGKEY ]]; then
|
|
SIGNWITHKEY="-u ${GPGKEY}"
|
|
fi
|
|
# The signature will be generated directly in ascii-friendly format
|
|
gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
|
|
|
|
|
|
if (( ! ret )); then
|
|
msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
|
|
else
|
|
warning "$(gettext "Failed to sign package file.")"
|
|
fi
|
|
}
|
|
|
|
create_srcpackage() {
|
|
local ret=0
|
|
msg "$(gettext "Creating source package...")"
|
|
local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
|
|
mkdir "${srclinks}"/${pkgbase}
|
|
|
|
msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
|
|
ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
|
|
|
|
local file
|
|
for file in "${source[@]}"; do
|
|
if [[ -f $file ]]; then
|
|
msg2 "$(gettext "Adding %s...")" "$file"
|
|
ln -s "${startdir}/$file" "$srclinks/$pkgbase"
|
|
elif (( SOURCEONLY == 2 )); then
|
|
local absfile=$(get_filepath "$file") || missing_source_file "$file"
|
|
msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
|
|
ln -s "$absfile" "$srclinks/$pkgbase"
|
|
fi
|
|
done
|
|
|
|
local i
|
|
for i in 'changelog' 'install'; do
|
|
local file
|
|
while read -r file; do
|
|
# evaluate any bash variables used
|
|
eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
|
|
if [[ $file && ! -f "${srclinks}/${pkgbase}/$file" ]]; then
|
|
msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
|
|
ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
|
|
fi
|
|
done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
|
|
done
|
|
|
|
local TAR_OPT
|
|
case "$SRCEXT" in
|
|
*tar.gz) TAR_OPT="z" ;;
|
|
*tar.bz2) TAR_OPT="j" ;;
|
|
*tar.xz) TAR_OPT="J" ;;
|
|
*tar.Z) TAR_OPT="Z" ;;
|
|
*tar) TAR_OPT="" ;;
|
|
*) warning "$(gettext "'%s' is not a valid archive extension.")" \
|
|
"$SRCEXT" ;;
|
|
esac
|
|
|
|
local fullver=$(get_full_version)
|
|
local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
|
|
|
|
# tar it up
|
|
msg2 "$(gettext "Compressing source package...")"
|
|
cd "${srclinks}"
|
|
if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
|
|
error "$(gettext "Failed to create source package file.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
|
|
if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
|
|
rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
|
|
ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
|
|
ret=$?
|
|
fi
|
|
|
|
if (( ret )); then
|
|
warning "$(gettext "Failed to create symlink to source package file.")"
|
|
fi
|
|
|
|
cd "${startdir}"
|
|
rm -rf "${srclinks}"
|
|
}
|
|
|
|
install_package() {
|
|
(( ! INSTALL )) && return
|
|
|
|
if (( ! SPLITPKG )); then
|
|
msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
|
|
else
|
|
msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
|
|
fi
|
|
|
|
local fullver pkg pkglist
|
|
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
|
|
done
|
|
|
|
if ! run_pacman -U $pkglist; then
|
|
warning "$(gettext "Failed to install built package(s).")"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
check_sanity() {
|
|
# check for no-no's in the build script
|
|
local i
|
|
local ret=0
|
|
for i in 'pkgname' 'pkgrel' 'pkgver'; do
|
|
if [[ -z ${!i} ]]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "$i"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
for i in "${pkgname[@]}"; do
|
|
if [[ ${i:0:1} = "-" ]]; then
|
|
error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
if [[ ${pkgbase:0:1} = "-" ]]; then
|
|
error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
|
|
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
|
|
|
|
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"
|
|
return 1
|
|
fi
|
|
done || ret=1
|
|
|
|
awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
|
|
while IFS='=' read -r _ i; do
|
|
eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
|
|
if [[ $i != *([[:digit:]]) ]]; then
|
|
error "$(gettext "%s must be an integer.")" "epoch"
|
|
return 1
|
|
fi
|
|
done || ret=1
|
|
|
|
if [[ $arch != 'any' ]]; then
|
|
if ! in_array $CARCH ${arch[@]}; then
|
|
if (( ! IGNOREARCH )); then
|
|
error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
|
|
plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
|
|
plain "$(gettext "such as %s.")" "arch=('$CARCH')"
|
|
ret=1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if (( ${#pkgname[@]} > 1 )); then
|
|
for i in ${pkgname[@]}; do
|
|
local arch_list=""
|
|
eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
|
|
if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
|
|
if ! in_array $CARCH ${arch_list[@]}; then
|
|
if (( ! IGNOREARCH )); then
|
|
error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
|
|
ret=1
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
local provides_list=()
|
|
eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
|
|
sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
|
|
for i in ${provides_list[@]}; do
|
|
if [[ $i == *['<>']* ]]; then
|
|
error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
local backup_list=()
|
|
eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
|
|
sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
|
|
for i in "${backup_list[@]}"; do
|
|
if [[ ${i:0:1} = "/" ]]; then
|
|
error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
local optdepends_list=()
|
|
eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
|
|
sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
|
|
for i in "${optdepends_list[@]}"; do
|
|
local pkg=${i%%:[[:space:]]*}
|
|
# the '-' character _must_ be first or last in the character range
|
|
if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then
|
|
error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
for i in 'changelog' 'install'; do
|
|
local file
|
|
while read -r file; do
|
|
# evaluate any bash variables used
|
|
eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
|
|
if [[ $file && ! -f $file ]]; then
|
|
error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
|
|
ret=1
|
|
fi
|
|
done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
|
|
done
|
|
|
|
local valid_options=1
|
|
local known kopt options_list
|
|
eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
|
|
sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
|
|
for i in ${options_list[@]}; do
|
|
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
|
|
known=1
|
|
fi
|
|
done
|
|
if (( ! known )); then
|
|
error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
|
|
valid_options=0
|
|
fi
|
|
done
|
|
if (( ! valid_options )); then
|
|
ret=1
|
|
fi
|
|
|
|
if (( ${#pkgname[@]} > 1 )); then
|
|
for i in ${pkgname[@]}; do
|
|
if ! declare -f package_${i} >/dev/null; then
|
|
error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
|
|
ret=1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
for i in ${PKGLIST[@]}; do
|
|
if ! in_array $i ${pkgname[@]}; then
|
|
error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
return $ret
|
|
}
|
|
|
|
check_software() {
|
|
# check for needed software
|
|
local ret=0
|
|
|
|
# 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.")"
|
|
fi
|
|
fi
|
|
|
|
# fakeroot - building as non-root user
|
|
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
|
|
fi
|
|
fi
|
|
|
|
# gpg - package signing
|
|
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
|
|
fi
|
|
fi
|
|
|
|
# gpg - source verification
|
|
if (( ! SKIPPGPCHECK )) && source_has_signatures; then
|
|
if ! type -p gpg >/dev/null; then
|
|
error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
|
|
ret=1
|
|
fi
|
|
fi
|
|
|
|
# openssl - checksum operations
|
|
if (( ! SKIPCHECKSUMS )); then
|
|
if ! type -p openssl >/dev/null; then
|
|
error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
|
|
ret=1
|
|
fi
|
|
fi
|
|
|
|
# upx - binary compression
|
|
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
|
|
fi
|
|
fi
|
|
|
|
# distcc - compilation with distcc
|
|
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
|
|
fi
|
|
fi
|
|
|
|
# ccache - compilation with ccache
|
|
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
|
|
fi
|
|
fi
|
|
|
|
# strip - strip symbols from binaries/libraries
|
|
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
|
|
fi
|
|
fi
|
|
|
|
# gzip - compressig man and info pages
|
|
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
|
|
fi
|
|
fi
|
|
|
|
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
|
|
hg pull
|
|
hg update
|
|
else
|
|
[[ ! -d ./src/ ]] && mkdir ./src/
|
|
hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
|
|
cd ./src/$_hgrepo
|
|
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"
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
backup_package_variables() {
|
|
local var
|
|
for var in ${splitpkg_overrides[@]}; do
|
|
local indirect="${var}_backup"
|
|
eval "${indirect}=(\"\${$var[@]}\")"
|
|
done
|
|
}
|
|
|
|
restore_package_variables() {
|
|
local var
|
|
for var in ${splitpkg_overrides[@]}; do
|
|
local indirect="${var}_backup"
|
|
if [[ -n ${!indirect} ]]; then
|
|
eval "${var}=(\"\${$indirect[@]}\")"
|
|
else
|
|
unset ${var}
|
|
fi
|
|
done
|
|
}
|
|
|
|
run_split_packaging() {
|
|
local pkgname_backup=${pkgname[@]}
|
|
for pkgname in ${pkgname_backup[@]}; do
|
|
pkgdir="$pkgdir/$pkgname"
|
|
mkdir -p "$pkgdir"
|
|
chmod a-s "$pkgdir"
|
|
backup_package_variables
|
|
run_package $pkgname
|
|
tidy_install
|
|
create_package $pkgname
|
|
restore_package_variables
|
|
pkgdir="${pkgdir%/*}"
|
|
done
|
|
pkgname=${pkgname_backup[@]}
|
|
}
|
|
|
|
# Canonicalize a directory path if it exists
|
|
canonicalize_path() {
|
|
local path="$1";
|
|
|
|
if [[ -d $path ]]; then
|
|
(
|
|
cd "$path"
|
|
pwd -P
|
|
)
|
|
else
|
|
echo "$path"
|
|
fi
|
|
}
|
|
|
|
m4_include(library/parse_options.sh)
|
|
|
|
usage() {
|
|
printf "makepkg (pacman) %s\n" "$myver"
|
|
echo
|
|
printf "$(gettext "Usage: %s [options]")\n" "$0"
|
|
echo
|
|
echo "$(gettext "Options:")"
|
|
printf "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
|
|
echo "$(gettext " -c, --clean Clean up work files after build")"
|
|
echo "$(gettext " -d, --nodeps Skip all dependency checks")"
|
|
printf "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
|
|
echo "$(gettext " -f, --force Overwrite existing package")"
|
|
echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
|
|
echo "$(gettext " -h, --help Show this help message and exit")"
|
|
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 <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
|
|
echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
|
|
echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
|
|
printf "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
|
|
echo "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")"
|
|
echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
|
|
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 " --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"
|
|
echo "$(gettext " --nosign Do not create a signature for the package")"
|
|
echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
|
|
printf "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
|
|
echo "$(gettext " --skipchecksums Do not verify checksums of the source files")"
|
|
echo "$(gettext " --skipinteg Do not perform any verification checks on source files")"
|
|
echo "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")"
|
|
echo
|
|
printf "$(gettext "These options can be passed to %s:")\n" "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 %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
|
|
echo
|
|
}
|
|
|
|
version() {
|
|
printf "makepkg (pacman) %s\n" "$myver"
|
|
printf "$(gettext "\
|
|
Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\
|
|
Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
|
|
This is free software; see the source for copying conditions.\n\
|
|
There is NO WARRANTY, to the extent permitted by law.\n")"
|
|
}
|
|
|
|
# PROGRAM START
|
|
|
|
# determine whether we have gettext; make it a no-op if we do not
|
|
if ! type -p gettext >/dev/null; then
|
|
gettext() {
|
|
echo "$@"
|
|
}
|
|
fi
|
|
|
|
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:"
|
|
|
|
# Pacman Options
|
|
OPT_LONG+=",noconfirm,noprogressbar"
|
|
if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
|
|
echo; usage; exit 1 # E_INVALID_OPTION;
|
|
fi
|
|
eval set -- "$OPT_TEMP"
|
|
unset OPT_SHORT OPT_LONG OPT_TEMP
|
|
|
|
while true; do
|
|
case "$1" in
|
|
# Pacman Options
|
|
--noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
|
|
--noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
|
|
|
|
# Makepkg Options
|
|
--allsource) SOURCEONLY=2 ;;
|
|
--asroot) ASROOT=1 ;;
|
|
-A|--ignorearch) IGNOREARCH=1 ;;
|
|
-c|--clean) CLEANUP=1 ;;
|
|
--check) RUN_CHECK='y' ;;
|
|
--config) shift; MAKEPKG_CONF=$1 ;;
|
|
-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 ;;
|
|
-i|--install) INSTALL=1 ;;
|
|
--key) shift; GPGKEY=$1 ;;
|
|
-L|--log) LOGGING=1 ;;
|
|
-m|--nocolor) USE_COLOR='n' ;;
|
|
--nocheck) RUN_CHECK='n' ;;
|
|
--nosign) SIGNPKG='n' ;;
|
|
-o|--nobuild) NOBUILD=1 ;;
|
|
-p) shift; BUILDFILE=$1 ;;
|
|
--pkg) shift; PKGLIST=($1) ;;
|
|
-r|--rmdeps) RMDEPS=1 ;;
|
|
-R|--repackage) REPKG=1 ;;
|
|
--skipchecksums) SKIPCHECKSUMS=1 ;;
|
|
--skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
|
|
--skippgpcheck) SKIPPGPCHECK=1;;
|
|
--sign) SIGNPKG='y' ;;
|
|
-s|--syncdeps) DEP_BIN=1 ;;
|
|
-S|--source) SOURCEONLY=1 ;;
|
|
|
|
-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
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# setup signal traps
|
|
trap 'clean_up' 0
|
|
for signal in TERM HUP QUIT; do
|
|
trap "trap_exit \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal"
|
|
done
|
|
trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
|
|
trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
|
|
set -E
|
|
|
|
# preserve environment variables and canonicalize path
|
|
[[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
|
|
[[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
|
|
[[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
|
|
[[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
|
|
[[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
|
|
[[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
|
|
[[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
|
|
|
|
# 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"
|
|
else
|
|
error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_CONFIG_ERROR
|
|
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
|
|
fi
|
|
|
|
# set pacman command if not already defined
|
|
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
|
|
# prefer terminal safe colored and bold text when tput is supported
|
|
if tput setaf 0 &>/dev/null; then
|
|
ALL_OFF="$(tput sgr0)"
|
|
BOLD="$(tput bold)"
|
|
BLUE="${BOLD}$(tput setaf 4)"
|
|
GREEN="${BOLD}$(tput setaf 2)"
|
|
RED="${BOLD}$(tput setaf 1)"
|
|
YELLOW="${BOLD}$(tput setaf 3)"
|
|
else
|
|
ALL_OFF="\e[1;0m"
|
|
BOLD="\e[1;1m"
|
|
BLUE="${BOLD}\e[1;34m"
|
|
GREEN="${BOLD}\e[1;32m"
|
|
RED="${BOLD}\e[1;31m"
|
|
YELLOW="${BOLD}\e[1;33m"
|
|
fi
|
|
fi
|
|
readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
|
|
|
|
# override settings with an environment variable for batch processing
|
|
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"
|
|
chmod a-s "$BUILDDIR"
|
|
fi
|
|
if [[ ! -w $BUILDDIR ]]; then
|
|
error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
srcdir="$BUILDDIR/src"
|
|
pkgdir="$BUILDDIR/pkg"
|
|
|
|
PKGDEST=${_PKGDEST:-$PKGDEST}
|
|
PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
|
|
if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
|
|
error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
|
|
SRCDEST=${_SRCDEST:-$SRCDEST}
|
|
SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
|
|
if [[ ! -w $SRCDEST ]] ; then
|
|
error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
|
|
SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
|
|
SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
|
|
|
|
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
|
|
|
|
if (( ! INFAKEROOT )); then
|
|
if (( EUID == 0 && ! ASROOT )); then
|
|
# Warn those who like to live dangerously.
|
|
error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
|
|
catastrophic damage to your system. If you wish to run as root, please\n\
|
|
use the %s option.")" "makepkg" "--asroot"
|
|
exit 1 # $E_USER_ABORT
|
|
elif (( EUID > 0 && ASROOT )); then
|
|
# Warn those who try to use the --asroot option when they are not root
|
|
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
|
|
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"
|
|
sleep 1
|
|
fi
|
|
else
|
|
if [[ -z $FAKEROOTKEY ]]; then
|
|
error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
fi
|
|
|
|
unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
|
|
unset md5sums replaces depends conflicts backup source install changelog build
|
|
unset makedepends optdepends options noextract
|
|
|
|
BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
|
|
if [[ ! -f $BUILDFILE ]]; then
|
|
if [[ -t 0 ]]; then
|
|
error "$(gettext "%s does not exist.")" "$BUILDFILE"
|
|
exit 1
|
|
else
|
|
# PKGBUILD passed through a pipe
|
|
BUILDFILE=/dev/stdin
|
|
source "$BUILDFILE"
|
|
fi
|
|
else
|
|
crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
|
|
if [[ -n $crlftest ]]; then
|
|
error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ${BUILDFILE:0:1} != "/" ]]; then
|
|
BUILDFILE="$startdir/$BUILDFILE"
|
|
fi
|
|
source "$BUILDFILE"
|
|
fi
|
|
|
|
# set defaults if they weren't specified in buildfile
|
|
pkgbase=${pkgbase:-${pkgname[0]}}
|
|
epoch=${epoch:-0}
|
|
|
|
if (( GENINTEG )); then
|
|
mkdir -p "$srcdir"
|
|
chmod a-s "$srcdir"
|
|
cd "$srcdir"
|
|
download_sources
|
|
generate_checksums
|
|
exit 0 # $E_OK
|
|
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 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
|
|
CHECKFUNC=1
|
|
fi
|
|
fi
|
|
if declare -f package >/dev/null; then
|
|
PKGFUNC=1
|
|
elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
|
|
SPLITPKG=1
|
|
fi
|
|
|
|
if [[ -n "${PKGLIST[@]}" ]]; then
|
|
unset pkgname
|
|
pkgname=("${PKGLIST[@]}")
|
|
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 ! gpg --list-key ${GPGKEY} &>/dev/null; then
|
|
if [[ ! -z $GPGKEY ]]; then
|
|
error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
|
|
else
|
|
error "$(gettext "There is no key in your keyring.")"
|
|
fi
|
|
exit 1
|
|
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
|
|
fi
|
|
|
|
# Run the bare minimum in fakeroot
|
|
if (( INFAKEROOT )); then
|
|
if (( SOURCEONLY )); then
|
|
create_srcpackage
|
|
msg "$(gettext "Leaving %s environment.")" "fakeroot"
|
|
exit 0 # $E_OK
|
|
fi
|
|
|
|
if (( ! SPLITPKG )); then
|
|
if (( ! PKGFUNC )); then
|
|
if (( ! REPKG )); then
|
|
if (( BUILDFUNC )); then
|
|
run_build
|
|
(( CHECKFUNC )) && run_check
|
|
tidy_install
|
|
fi
|
|
else
|
|
warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
|
|
plain "$(gettext "File permissions may not be preserved.")"
|
|
fi
|
|
else
|
|
run_package
|
|
tidy_install
|
|
fi
|
|
create_package
|
|
else
|
|
run_split_packaging
|
|
fi
|
|
|
|
msg "$(gettext "Leaving %s environment.")" "fakeroot"
|
|
exit 0 # $E_OK
|
|
fi
|
|
|
|
fullver=$(get_full_version)
|
|
msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
|
|
|
|
# if we are creating a source-only package, go no further
|
|
if (( SOURCEONLY )); then
|
|
if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
|
|
&& (( ! FORCE )); then
|
|
error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
|
|
exit 1
|
|
fi
|
|
|
|
# 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
|
|
download_sources
|
|
fi
|
|
check_source_integrity
|
|
cd "$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
|
|
create_srcpackage
|
|
else
|
|
enter_fakeroot
|
|
fi
|
|
|
|
msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
|
|
exit 0
|
|
fi
|
|
|
|
if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
|
|
# no warning message needed for nobuild, repkg
|
|
if (( NODEPS || ( REPKG && PKGFUNC ) )); then
|
|
warning "$(gettext "Skipping dependency checks.")"
|
|
fi
|
|
elif type -p "${PACMAN%% *}" >/dev/null; then
|
|
if (( RMDEPS )); then
|
|
original_pkglist=($(run_pacman -Qq)) # required by remove_dep
|
|
fi
|
|
deperr=0
|
|
|
|
msg "$(gettext "Checking runtime dependencies...")"
|
|
resolve_deps ${depends[@]} || deperr=1
|
|
|
|
msg "$(gettext "Checking buildtime dependencies...")"
|
|
resolve_deps ${makedepends[@]} || deperr=1
|
|
|
|
if (( CHECKFUNC )); then
|
|
resolve_deps ${checkdepends[@]} || deperr=1
|
|
fi
|
|
|
|
if (( RMDEPS )); then
|
|
current_pkglist=($(run_pacman -Qq)) # required by remove_deps
|
|
fi
|
|
|
|
if (( deperr )); then
|
|
error "$(gettext "Could not resolve all dependencies.")"
|
|
exit 1
|
|
fi
|
|
else
|
|
warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
|
|
fi
|
|
|
|
# ensure we have a sane umask set
|
|
umask 0022
|
|
|
|
# get back to our src directory so we can begin with sources
|
|
mkdir -p "$srcdir"
|
|
chmod a-s "$srcdir"
|
|
cd "$srcdir"
|
|
|
|
if (( NOEXTRACT )); then
|
|
warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
|
|
warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
|
|
warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
|
|
|
|
if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
|
|
error "$(gettext "The source directory is empty, there is nothing to build!")"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
elif (( REPKG )); then
|
|
if (( ! PKGFUNC && ! SPLITPKG )) \
|
|
&& [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
|
|
error "$(gettext "The package directory is empty, there is nothing to repackage!")"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
else
|
|
download_sources
|
|
check_source_integrity
|
|
extract_sources
|
|
fi
|
|
|
|
if (( NOBUILD )); then
|
|
msg "$(gettext "Sources are ready.")"
|
|
exit 0 #E_OK
|
|
else
|
|
# check for existing pkg directory; don't remove if we are repackaging
|
|
if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
|
|
msg "$(gettext "Removing existing %s directory...")" "pkg/"
|
|
rm -rf "$pkgdir"
|
|
fi
|
|
mkdir -p "$pkgdir"
|
|
chmod a-s "$pkgdir"
|
|
cd "$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 (( ! REPKG )); then
|
|
devel_update
|
|
(( BUILDFUNC )) && run_build
|
|
(( CHECKFUNC )) && run_check
|
|
fi
|
|
if (( ! SPLITPKG )); then
|
|
if (( PKGFUNC )); then
|
|
run_package
|
|
tidy_install
|
|
else
|
|
if (( ! REPKG )); then
|
|
tidy_install
|
|
else
|
|
warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
|
|
plain "$(gettext "File permissions may not be preserved.")"
|
|
fi
|
|
fi
|
|
create_package
|
|
else
|
|
run_split_packaging
|
|
fi
|
|
else
|
|
if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
|
|
devel_update
|
|
(( BUILDFUNC )) && run_build
|
|
(( CHECKFUNC )) && run_check
|
|
cd "$startdir"
|
|
fi
|
|
|
|
enter_fakeroot
|
|
fi
|
|
fi
|
|
|
|
fullver=$(get_full_version)
|
|
msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
|
|
|
|
install_package
|
|
|
|
exit 0 #E_OK
|
|
|
|
# vim: set ts=2 sw=2 noet:
|