mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-23 00:08:50 -05:00
c2cf6a14cf
Commit 3d67d9b1
introduced multiple bash4 string manipulations.
Revert those in order retain compatibility with bash-3.2 which
is still widely used.
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2029 lines
53 KiB
Bash
2029 lines
53 KiB
Bash
#!/bin/bash -e
|
|
#
|
|
# makepkg - make packages compatible for use with pacman
|
|
# @configure_input@
|
|
#
|
|
# Copyright (c) 2006-2010 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:
|
|
# bsdtar (libarchive), bzip2, coreutils, fakeroot, find (findutils),
|
|
# gettext, grep, gzip, openssl, sed, tput (ncurses), xz
|
|
|
|
# gettext initialization
|
|
export TEXTDOMAIN='pacman'
|
|
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"
|
|
srcdir="$startdir/src"
|
|
pkgdir="$startdir/pkg"
|
|
|
|
packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge')
|
|
other_options=('ccache' 'distcc' 'makeflags' 'force')
|
|
splitpkg_overrides=('pkgver' 'pkgrel' '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
|
|
CLEANCACHE=0
|
|
DEP_BIN=0
|
|
FORCE=0
|
|
INFAKEROOT=0
|
|
GENINTEG=0
|
|
SKIPINTEG=0
|
|
INSTALL=0
|
|
NOBUILD=0
|
|
NODEPS=0
|
|
NOEXTRACT=0
|
|
RMDEPS=0
|
|
REPKG=0
|
|
LOGGING=0
|
|
SOURCEONLY=0
|
|
IGNOREARCH=0
|
|
HOLDVER=0
|
|
BUILDFUNC=0
|
|
PKGFUNC=0
|
|
SPLITPKG=0
|
|
PKGLIST=""
|
|
|
|
# Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
|
|
# when dealing with svn/cvs/etc PKGBUILDs.
|
|
FORCE_VER=""
|
|
|
|
PACMAN_OPTS=
|
|
|
|
### 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
|
|
# If it's a clean exit and -c/--clean has been passed...
|
|
msg "$(gettext "Cleaning up...")"
|
|
rm -rf "$pkgdir" "$srcdir"
|
|
if [[ -n $pkgbase ]]; then
|
|
# Can't do this unless the BUILDSCRIPT has been sourced.
|
|
if (( BUILDFUNC )); then
|
|
rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-build.log"*
|
|
fi
|
|
if (( PKGFUNC )); then
|
|
rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package.log"*
|
|
elif (( SPLITPKG )); then
|
|
for pkg in ${pkgname[@]}; do
|
|
rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package_${pkg}.log"*
|
|
done
|
|
fi
|
|
|
|
# clean up dangling symlinks to packages
|
|
for pkg in ${pkgname[@]}; do
|
|
for file in ${pkg}-*-*-${CARCH}${PKGEXT}; do
|
|
if [[ -h $file && ! -e $file ]]; then
|
|
rm -f $file
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
fi
|
|
|
|
remove_deps
|
|
}
|
|
|
|
|
|
##
|
|
# Signal Traps
|
|
##
|
|
set -E
|
|
trap 'clean_up' 0
|
|
trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
|
|
trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
|
|
trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
|
|
|
|
# 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#*::}"
|
|
}
|
|
|
|
##
|
|
# 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() {
|
|
echo $(in_opt_array "$1" ${BUILDENV[@]})
|
|
}
|
|
|
|
|
|
##
|
|
# usage : in_opt_array( $needle, $haystack )
|
|
# return : y - enabled
|
|
# n - disabled
|
|
# ? - not found
|
|
##
|
|
in_opt_array() {
|
|
local needle=$(tr '[:upper:]' '[:lower:]' <<< $1); shift
|
|
|
|
local opt
|
|
for opt in "$@"; do
|
|
opt=$(tr '[:upper:]' '[:lower:]' <<< $opt)
|
|
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
|
|
[[ -z $1 ]] && return 1 # Not Found
|
|
local item
|
|
for item in "$@"; do
|
|
[[ $item = $needle ]] && return 0 # Found
|
|
done
|
|
return 1 # Not Found
|
|
}
|
|
|
|
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
|
|
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=$(basename $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 ret=0
|
|
if (( ! ASROOT )) && [[ $1 != "-T" && $1 != "-Qq" ]]; then
|
|
if [ "$(type -p sudo)" ] && sudo -l $PACMAN &>/dev/null; then
|
|
sudo $PACMAN $PACMAN_OPTS "$@" || ret=$?
|
|
else
|
|
su -c "$PACMAN $PACMAN_OPTS $*" || ret=$?
|
|
fi
|
|
else
|
|
$PACMAN $PACMAN_OPTS "$@" || ret=$?
|
|
fi
|
|
return $ret
|
|
}
|
|
|
|
check_deps() {
|
|
(( $# > 0 )) || return
|
|
|
|
local ret=0
|
|
pmout=$(run_pacman -T "$@")
|
|
ret=$?
|
|
if (( ret == 127 )); then #unresolved deps
|
|
echo "$pmout"
|
|
elif (( ret )); then
|
|
error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
|
|
exit 1
|
|
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
|
|
local restoretrap=$(trap -p ERR)
|
|
trap - ERR
|
|
source /etc/profile &>/dev/null
|
|
eval $restoretrap
|
|
|
|
return $R_DEPS_SATISFIED
|
|
}
|
|
|
|
resolve_deps() {
|
|
local R_DEPS_SATISFIED=0
|
|
local R_DEPS_MISSING=1
|
|
|
|
local deplist="$(check_deps $*)"
|
|
if [[ -z $deplist ]]; then
|
|
return $R_DEPS_SATISFIED
|
|
fi
|
|
|
|
if handle_deps $deplist; then
|
|
# check deps again to make sure they were resolved
|
|
deplist="$(check_deps $*)"
|
|
[[ -z $deplist ]] && return $R_DEPS_SATISFIED
|
|
elif (( DEP_BIN )); then
|
|
error "$(gettext "Failed to install all missing dependencies.")"
|
|
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
|
|
if file=$(get_filepath "$netfile"); then
|
|
msg2 "$(gettext "Found %s")" "${file##*/}"
|
|
ln -sf "$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) ]; then
|
|
error "$(gettext "Cannot find 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
|
|
integ=$(tr '[:upper:]' '[:lower:]' <<< "$integ")
|
|
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() {
|
|
(( ! ${#source[@]} )) && return 0
|
|
|
|
if [ ! $(type -p openssl) ]; then
|
|
error "$(gettext "Cannot find openssl.")"
|
|
exit 1 # $E_MISSING_PROGRAM
|
|
fi
|
|
|
|
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
|
|
}
|
|
|
|
extract_sources() {
|
|
msg "$(gettext "Extracting Sources...")"
|
|
local netfile
|
|
for netfile in "${source[@]}"; do
|
|
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 ;;
|
|
*)
|
|
# Don't know what to use to extract this file,
|
|
# skip to the next file
|
|
continue;;
|
|
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
|
|
plain "$(gettext "Aborting...")"
|
|
remove_deps
|
|
fi
|
|
exit 2 # $E_BUILD_FAILED
|
|
}
|
|
|
|
run_function() {
|
|
if [[ -z $1 ]]; then
|
|
return 1
|
|
fi
|
|
pkgfunc="$1"
|
|
|
|
# clear user-specified makeflags if requested
|
|
if [[ $(check_option makeflags) = "n" ]]; then
|
|
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
|
|
if (( LOGGING )); then
|
|
BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${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")
|
|
mknod "$logpipe" p
|
|
exec 3>&1
|
|
tee "$BUILDLOG" < "$logpipe" &
|
|
exec 1>"$logpipe" 2>"$logpipe"
|
|
restoretrap=$(trap -p ERR)
|
|
trap 'error_function' ERR
|
|
$pkgfunc 2>&1
|
|
eval $restoretrap
|
|
sync
|
|
exec 1>&3 2>&3 3>&-
|
|
rm "$logpipe"
|
|
else
|
|
restoretrap=$(trap -p ERR)
|
|
trap 'error_function' 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
|
|
elif [[ $(check_option distcc) = "n" ]]; then
|
|
# if it is not wanted, clear the makeflags too
|
|
MAKEFLAGS=""
|
|
fi
|
|
|
|
# use ccache if it is requested (check buildenv and PKGBUILD opts)
|
|
if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
|
|
[[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
|
|
fi
|
|
|
|
run_function "build"
|
|
}
|
|
|
|
run_package() {
|
|
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 other 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"
|
|
ln -sf "${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 if find returned an
|
|
# error, such as when one of the man directories doesn't exist
|
|
hardlinks="$(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
|
|
for hl in ${hardlinks}; do
|
|
rm -f "${hl}";
|
|
done
|
|
# 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 && -n ${STRIP_DIRS[*]} ]]; 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 ${STRIP_DIRS[@]} -type f -perm -u+w 2>/dev/null | while read binary ; do
|
|
case "$(file -bi "$binary")" in
|
|
*application/x-sharedlib*) # Libraries (.so)
|
|
/usr/bin/strip $STRIP_SHARED "$binary";;
|
|
*application/x-archive*) # Libraries (.a)
|
|
/usr/bin/strip $STRIP_STATIC "$binary";;
|
|
*application/x-executable*) # Binaries
|
|
/usr/bin/strip $STRIP_BINARIES "$binary";;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
if [[ $(check_option libtool) = "n" ]]; then
|
|
msg2 "$(gettext "Removing libtool .la files...")"
|
|
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
|
|
}
|
|
|
|
write_pkginfo() {
|
|
local builddate=$(date -u "+%s")
|
|
if [[ -n $PACKAGER ]]; then
|
|
local packager="$PACKAGER"
|
|
else
|
|
local packager="Unknown Packager"
|
|
fi
|
|
local size="$(du -sk)"
|
|
size="$(( ${size%%[^0-9]*} * 1024 ))"
|
|
|
|
msg2 "$(gettext "Generating .PKGINFO file...")"
|
|
echo "# Generated by makepkg $myver" >.PKGINFO
|
|
if (( INFAKEROOT )); then
|
|
echo "# using $(fakeroot -v)" >>.PKGINFO
|
|
fi
|
|
echo "# $(LC_ALL=C date -u)" >>.PKGINFO
|
|
echo "pkgname = $1" >>.PKGINFO
|
|
(( SPLITPKG )) && echo pkgbase = $pkgbase >>.PKGINFO
|
|
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
|
|
echo "pkgdesc = $pkgdesc" >>.PKGINFO
|
|
echo "url = $url" >>.PKGINFO
|
|
echo "builddate = $builddate" >>.PKGINFO
|
|
echo "packager = $packager" >>.PKGINFO
|
|
echo "size = $size" >>.PKGINFO
|
|
echo "arch = $PKGARCH" >>.PKGINFO
|
|
if [[ $(check_option force) = "y" ]]; then
|
|
echo "force = true" >> .PKGINFO
|
|
fi
|
|
|
|
local it
|
|
for it in "${license[@]}"; do
|
|
echo "license = $it" >>.PKGINFO
|
|
done
|
|
for it in "${replaces[@]}"; do
|
|
echo "replaces = $it" >>.PKGINFO
|
|
done
|
|
for it in "${groups[@]}"; do
|
|
echo "group = $it" >>.PKGINFO
|
|
done
|
|
for it in "${depends[@]}"; do
|
|
echo "depend = $it" >>.PKGINFO
|
|
done
|
|
for it in "${optdepends[@]}"; do
|
|
echo "optdepend = $it" >>.PKGINFO
|
|
done
|
|
for it in "${conflicts[@]}"; do
|
|
echo "conflict = $it" >>.PKGINFO
|
|
done
|
|
for it in "${provides[@]}"; do
|
|
echo "provides = $it" >>.PKGINFO
|
|
done
|
|
for it in "${backup[@]}"; do
|
|
echo "backup = $it" >>.PKGINFO
|
|
done
|
|
for it in "${packaging_options[@]}"; do
|
|
local ret="$(check_option $it)"
|
|
if [[ $ret != "?" ]]; then
|
|
if [[ $ret = y ]]; then
|
|
echo "makepkgopt = $it" >>.PKGINFO
|
|
else
|
|
echo "makepkgopt = !$it" >>.PKGINFO
|
|
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: 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 "Invalid backup entry : %s")" "$file"
|
|
fi
|
|
done
|
|
|
|
# check for references to the build directory
|
|
if grep -R "${srcdir}" "${pkgdir}" &>/dev/null; then
|
|
warning "$(gettext "Package contains reference to %s")" "\$srcdir"
|
|
fi
|
|
}
|
|
|
|
create_package() {
|
|
if [[ ! -d $pkgdir ]]; then
|
|
error "$(gettext "Missing pkg/ directory.")"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_MISSING_PKGDIR
|
|
fi
|
|
|
|
check_package
|
|
|
|
cd "$pkgdir"
|
|
msg "$(gettext "Creating package...")"
|
|
|
|
if [[ -z $1 ]]; then
|
|
nameofpkg="$pkgname"
|
|
else
|
|
nameofpkg="$1"
|
|
fi
|
|
|
|
if [[ $arch = "any" ]]; then
|
|
PKGARCH="any"
|
|
else
|
|
PKGARCH=$CARCH
|
|
fi
|
|
|
|
write_pkginfo $nameofpkg
|
|
|
|
local comp_files=".PKGINFO"
|
|
|
|
# check for an install script
|
|
if [[ -n $install ]]; then
|
|
msg2 "$(gettext "Adding install script...")"
|
|
cp "$startdir/$install" .INSTALL
|
|
chmod 644 .INSTALL
|
|
comp_files="$comp_files .INSTALL"
|
|
fi
|
|
|
|
# do we have a changelog?
|
|
if [[ -n $changelog ]]; then
|
|
msg2 "$(gettext "Adding package changelog...")"
|
|
cp "$startdir/$changelog" .CHANGELOG
|
|
chmod 644 .CHANGELOG
|
|
comp_files="$comp_files .CHANGELOG"
|
|
fi
|
|
|
|
# tar it up
|
|
msg2 "$(gettext "Compressing package...")"
|
|
|
|
case "$PKGEXT" in
|
|
*tar.gz) EXT=${PKGEXT%.gz} ;;
|
|
*tar.bz2) EXT=${PKGEXT%.bz2} ;;
|
|
*tar.xz) EXT=${PKGEXT%.xz} ;;
|
|
*) warning "$(gettext "'%s' is not a valid archive extension.")" \
|
|
"$PKGEXT" ; EXT=$PKGEXT ;;
|
|
esac
|
|
local tar_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${EXT}"
|
|
local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}"
|
|
|
|
local ret=0
|
|
|
|
# when fileglobbing, we want * in an empty directory to expand to
|
|
# the null string rather than itself
|
|
shopt -s nullglob
|
|
bsdtar -cf - $comp_files * > "$tar_file" || ret=$?
|
|
shopt -u nullglob
|
|
|
|
if (( ! ret )); then
|
|
case "$PKGEXT" in
|
|
*tar.gz) gzip -f -n "$tar_file" ;;
|
|
*tar.bz2) bzip2 -f "$tar_file" ;;
|
|
*tar.xz) xz -z -f "$tar_file" ;;
|
|
esac
|
|
ret=$?
|
|
fi
|
|
|
|
if (( ret )); then
|
|
error "$(gettext "Failed to create package file.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
|
|
if (( ! ret )) && [[ "$PKGDEST" != "${startdir}" ]]; then
|
|
ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
|
|
ret=$?
|
|
fi
|
|
|
|
if (( ret )); then
|
|
warning "$(gettext "Failed to create symlink to package file.")"
|
|
fi
|
|
}
|
|
|
|
create_srcpackage() {
|
|
cd "$startdir"
|
|
|
|
# Get back to our src directory so we can begin with sources.
|
|
mkdir -p "$srcdir"
|
|
chmod a-s "$srcdir"
|
|
cd "$srcdir"
|
|
if (( ! SKIPINTEG || SOURCEONLY == 2 )); then
|
|
download_sources
|
|
fi
|
|
if (( ! SKIPINTEG )); then
|
|
# We can only check checksums if we have all files.
|
|
check_checksums
|
|
else
|
|
warning "$(gettext "Skipping integrity checks.")"
|
|
fi
|
|
cd "$startdir"
|
|
|
|
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 filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDSCRIPT")
|
|
local file
|
|
for file in $filelist; do
|
|
# evaluate any bash variables used
|
|
eval file=${file}
|
|
if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
|
|
msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
|
|
ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
|
|
fi
|
|
done
|
|
done
|
|
|
|
local TAR_OPT
|
|
case "$SRCEXT" in
|
|
*tar.gz) TAR_OPT="z" ;;
|
|
*tar.bz2) TAR_OPT="j" ;;
|
|
*tar.xz) TAR_OPT="J" ;;
|
|
*) warning "$(gettext "'%s' is not a valid archive extension.")" \
|
|
"$SRCEXT" ;;
|
|
esac
|
|
|
|
local pkg_file="$SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${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
|
|
cd "${startdir}"
|
|
rm -rf "${srclinks}"
|
|
}
|
|
|
|
install_package() {
|
|
(( ! INSTALL )) && return
|
|
|
|
if (( ! SPLITPKG )); then
|
|
msg "$(gettext "Installing package %s with %s -U...")" "$pkgname" "$PACMAN"
|
|
else
|
|
msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN"
|
|
fi
|
|
|
|
local pkglist
|
|
for pkg in ${pkgname[@]}; do
|
|
if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then
|
|
pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"
|
|
else
|
|
pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-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
|
|
if [[ -z $pkgname ]]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "pkgname"
|
|
return 1
|
|
fi
|
|
if [[ -z $pkgver ]]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "pkgver"
|
|
return 1
|
|
fi
|
|
if [[ -z $pkgrel ]]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "pkgrel"
|
|
return 1
|
|
fi
|
|
|
|
local name
|
|
for name in "${pkgname[@]}"; do
|
|
if [[ ${name:0:1} = "-" ]]; then
|
|
error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
if [[ ${pkgbase:0:1} = "-" ]]; then
|
|
error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
|
|
return 1
|
|
fi
|
|
if [[ $pkgver != ${pkgver//-/} ]]; then
|
|
error "$(gettext "%s is not allowed to contain hyphens.")" "pkgver"
|
|
return 1
|
|
fi
|
|
if [[ $pkgrel != ${pkgrel//-/} ]]; then
|
|
error "$(gettext "%s is not allowed to contain hyphens.")" "pkgrel"
|
|
return 1
|
|
fi
|
|
|
|
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 arch=('%s').")" "$CARCH"
|
|
return 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
local provide
|
|
for provide in ${provides[@]}; do
|
|
if [[ $provide != ${provide//</} || $provide != ${provide//>/} ]]; then
|
|
error "$(gettext "Provides array cannot contain comparison (< or >) operators.")"
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
local file
|
|
for file in "${backup[@]}"; do
|
|
if [[ ${file:0:1} = "/" ]]; then
|
|
error "$(gettext "Invalid backup entry : %s")" "$file"
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
local optdepend
|
|
for optdepend in "${optdepends[@]}"; do
|
|
pkg=${optdepend%%:*}
|
|
if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]*$ ]]; then
|
|
error "$(gettext "Invalid syntax for optdepend : '%s'")" "$optdepend"
|
|
fi
|
|
done
|
|
|
|
local i
|
|
for i in 'changelog' 'install'; do
|
|
local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
|
|
local file
|
|
for file in $filelist; do
|
|
# evaluate any bash variables used
|
|
eval file=${file}
|
|
if [[ ! -f $file ]]; then
|
|
error "$(gettext "%s file (%s) does not exist.")" "${i^}" "$file"
|
|
return 1
|
|
fi
|
|
done
|
|
done
|
|
|
|
local valid_options=1
|
|
local opt known kopt
|
|
for opt in ${options[@]}; do
|
|
known=0
|
|
# check if option matches a known option or its inverse
|
|
for kopt in ${packaging_options[@]} ${other_options[@]}; do
|
|
if [[ ${opt} = ${kopt} || ${opt} = "!${kopt}" ]]; then
|
|
known=1
|
|
fi
|
|
done
|
|
if (( ! known )); then
|
|
error "$(gettext "options array contains unknown option '%s'")" "$opt"
|
|
valid_options=0
|
|
fi
|
|
done
|
|
if (( ! valid_options )); then
|
|
return 1
|
|
fi
|
|
|
|
if (( ${#pkgname[@]} > 1 )); then
|
|
for pkg in ${pkgname[@]}; do
|
|
if [ "$(type -t package_${pkg})" != "function" ]; then
|
|
error "$(gettext "missing package function for split package '%s'")" "$pkg"
|
|
return 1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [[ -n "${PKGLIST[@]}" ]]; then
|
|
for pkg in ${PKGLIST[@]}; do
|
|
if ! in_array $pkg ${pkgname[@]}; then
|
|
error "$(gettext "requested package %s is not provided in %s")" "$pkg" "$BUILDFILE"
|
|
return 1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
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 ]]; 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 brief check to make sure we have the VCS tool available.
|
|
oldpkgver=$pkgver
|
|
if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
|
|
[ $(type -p darcs) ] || return 0
|
|
msg "$(gettext "Determining latest darcs revision...")"
|
|
newpkgver=$(date +%Y%m%d)
|
|
elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
|
|
[ $(type -p cvs) ] || return 0
|
|
msg "$(gettext "Determining latest cvs revision...")"
|
|
newpkgver=$(date +%Y%m%d)
|
|
elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
|
|
[ $(type -p git) ] || return 0
|
|
msg "$(gettext "Determining latest git revision...")"
|
|
newpkgver=$(date +%Y%m%d)
|
|
elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
|
|
[ $(type -p svn) ] || return 0
|
|
msg "$(gettext "Determining latest svn revision...")"
|
|
newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
|
|
elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
|
|
[ $(type -p bzr) ] || return 0
|
|
msg "$(gettext "Determining latest bzr revision...")"
|
|
newpkgver=$(bzr revno ${_bzrtrunk})
|
|
elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
|
|
[ $(type -p hg) ] || return 0
|
|
msg "$(gettext "Determining latest hg revision...")"
|
|
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() {
|
|
for var in ${splitpkg_overrides[@]}; do
|
|
indirect="${var}_backup"
|
|
eval "${indirect}=(\"\${$var[@]}\")"
|
|
done
|
|
}
|
|
|
|
restore_package_variables() {
|
|
for var in ${splitpkg_overrides[@]}; do
|
|
indirect="${var}_backup"
|
|
if [[ -n ${!indirect} ]]; then
|
|
eval "${var}=(\"\${$indirect[@]}\")"
|
|
else
|
|
unset ${var}
|
|
fi
|
|
done
|
|
}
|
|
|
|
# getopt like parser
|
|
parse_options() {
|
|
local short_options=$1; shift;
|
|
local long_options=$1; shift;
|
|
local ret=0;
|
|
local unused_options=""
|
|
|
|
while [[ -n $1 ]]; do
|
|
if [[ ${1:0:2} = '--' ]]; then
|
|
if [[ -n ${1:2} ]]; then
|
|
local match=""
|
|
for i in ${long_options//,/ }; do
|
|
if [[ ${1:2} = ${i//:} ]]; then
|
|
match=$i
|
|
break
|
|
fi
|
|
done
|
|
if [[ -n $match ]]; then
|
|
if [[ ${1:2} = $match ]]; then
|
|
printf ' %s' "$1"
|
|
else
|
|
if [[ -n $2 ]]; then
|
|
printf ' %s' "$1"
|
|
shift
|
|
printf " '%s'" "$1"
|
|
else
|
|
echo "makepkg: option '$1' $(gettext "requires an argument")" >&2
|
|
ret=1
|
|
fi
|
|
fi
|
|
else
|
|
echo "makepkg: $(gettext "unrecognized option") '$1'" >&2
|
|
ret=1
|
|
fi
|
|
else
|
|
shift
|
|
break
|
|
fi
|
|
elif [[ ${1:0:1} = '-' ]]; then
|
|
for ((i=1; i<${#1}; i++)); do
|
|
if [[ $short_options =~ ${1:i:1} ]]; then
|
|
if [[ $short_options =~ "${1:i:1}:" ]]; then
|
|
if [[ -n ${1:$i+1} ]]; then
|
|
printf ' -%s' "${1:i:1}"
|
|
printf " '%s'" "${1:$i+1}"
|
|
else
|
|
if [[ -n $2 ]]; then
|
|
printf ' -%s' "${1:i:1}"
|
|
shift
|
|
printf " '%s'" "${1}"
|
|
else
|
|
echo "makepkg: option $(gettext "requires an argument") -- '${1:i:1}'" >&2
|
|
ret=1
|
|
fi
|
|
fi
|
|
break
|
|
else
|
|
printf ' -%s' "${1:i:1}"
|
|
fi
|
|
else
|
|
echo "makepkg: $(gettext "invalid option") -- '${1:i:1}'" >&2
|
|
ret=1
|
|
fi
|
|
done
|
|
else
|
|
unused_options="${unused_options} '$1'"
|
|
fi
|
|
shift
|
|
done
|
|
|
|
printf " --"
|
|
if [[ -n $unused_options ]]; then
|
|
for i in ${unused_options[@]}; do
|
|
printf ' %s' "$i"
|
|
done
|
|
fi
|
|
if [[ -n $1 ]]; then
|
|
while [[ -n $1 ]]; do
|
|
printf " '%s'" "${1}"
|
|
shift
|
|
done
|
|
fi
|
|
printf "\n"
|
|
|
|
return $ret
|
|
}
|
|
|
|
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 arch field in %s")\n" "$BUILDSCRIPT"
|
|
echo "$(gettext " -c, --clean Clean up work files after build")"
|
|
echo "$(gettext " -C, --cleancache Clean up source files from the cache")"
|
|
echo "$(gettext " -d, --nodeps Skip all dependency checks")"
|
|
echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")"
|
|
echo "$(gettext " -f, --force Overwrite existing package")"
|
|
echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
|
|
echo "$(gettext " -h, --help This help")"
|
|
echo "$(gettext " -i, --install Install package after successful build")"
|
|
echo "$(gettext " -L, --log Log package build process")"
|
|
echo "$(gettext " -m, --nocolor Disable colorized output messages")"
|
|
echo "$(gettext " -o, --nobuild Download and extract files only")"
|
|
printf "$(gettext " -p <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")"
|
|
echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")"
|
|
echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
|
|
echo "$(gettext " --asroot Allow makepkg to run as root user")"
|
|
printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
|
|
echo "$(gettext " --holdver Prevent automatic version bumping for development PKGBUILDs")"
|
|
echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
|
|
echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")"
|
|
echo "$(gettext " --source Generate a source-only tarball without downloaded sources")"
|
|
echo
|
|
echo "$(gettext "These options can be passed to pacman:")"
|
|
echo
|
|
echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
|
|
echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
|
|
echo
|
|
printf "$(gettext "If -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT"
|
|
echo
|
|
}
|
|
|
|
version() {
|
|
printf "makepkg (pacman) %s\n" "$myver"
|
|
printf "$(gettext "\
|
|
Copyright (c) 2006-2010 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 -t gettext) ]; then
|
|
gettext() {
|
|
echo "$@"
|
|
}
|
|
fi
|
|
|
|
ARGLIST=("$@")
|
|
|
|
# Parse Command Line Options.
|
|
OPT_SHORT="AcCdefFghiLmop:rRsV"
|
|
OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps"
|
|
OPT_LONG="$OPT_LONG,noextract,force,forcever:,geninteg,help,holdver"
|
|
OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg"
|
|
OPT_LONG="$OPT_LONG,source,syncdeps,version,config:"
|
|
# Pacman Options
|
|
OPT_LONG="$OPT_LONG,noconfirm,noprogressbar"
|
|
OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
|
|
if [[ $OPT_TEMP = *'PARSE_OPTIONS FAILED'* ]]; then
|
|
# This is a small hack to stop the script bailing with 'set -e'
|
|
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="$PACMAN_OPTS --noconfirm" ;;
|
|
--noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;;
|
|
|
|
# Makepkg Options
|
|
--allsource) SOURCEONLY=2 ;;
|
|
--asroot) ASROOT=1 ;;
|
|
-A|--ignorearch) IGNOREARCH=1 ;;
|
|
-c|--clean) CLEANUP=1 ;;
|
|
-C|--cleancache) CLEANCACHE=1 ;;
|
|
--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 ;;
|
|
-L|--log) LOGGING=1 ;;
|
|
-m|--nocolor) USE_COLOR='n' ;;
|
|
-o|--nobuild) NOBUILD=1 ;;
|
|
-p) shift; BUILDFILE=$1 ;;
|
|
--pkg) shift; PKGLIST=$1 ;;
|
|
-r|--rmdeps) RMDEPS=1 ;;
|
|
-R|--repackage) REPKG=1 ;;
|
|
--skipinteg) SKIPINTEG=1 ;;
|
|
--source) SOURCEONLY=1 ;;
|
|
-s|--syncdeps) DEP_BIN=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
|
|
|
|
#preserve environment variables
|
|
_PKGDEST=${PKGDEST}
|
|
_SRCDEST=${SRCDEST}
|
|
_SRCPKGDEST=${SRCPKGDEST}
|
|
|
|
# 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
|
|
if [[ -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
|
|
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)"
|
|
fi
|
|
readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
|
|
|
|
# override settings with an environment variable for batch processing
|
|
PKGDEST=${_PKGDEST:-$PKGDEST}
|
|
PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
|
|
if [[ ! -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:-$PKGDEST} #default to $PKGDEST if undefined
|
|
|
|
|
|
if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
|
|
# The '\\0' is here to prevent gettext from thinking --holdver is an option
|
|
error "$(gettext "\\0--holdver and --forcever cannot both be specified" )"
|
|
exit 1
|
|
fi
|
|
|
|
if (( CLEANCACHE )); then
|
|
#fix flyspray feature request #5223
|
|
if [[ -n $SRCDEST && $SRCDEST != $startdir ]]; then
|
|
msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST"
|
|
echo -n "$(gettext " Are you sure you wish to do this? ")"
|
|
echo -n "$(gettext "[y/N]")"
|
|
read answer
|
|
answer=$(tr '[:lower:]' '[:upper:]' <<< "$answer")
|
|
if [[ $answer = $(gettext YES) || $answer = $(gettext Y) ]]; then
|
|
rm "$SRCDEST"/*
|
|
if (( $? )); then
|
|
error "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST"
|
|
exit 1
|
|
else
|
|
# removal worked
|
|
msg "$(gettext "Source cache cleaned.")"
|
|
exit 0
|
|
fi
|
|
else
|
|
# answer = no
|
|
msg "$(gettext "No files have been removed.")"
|
|
exit 0
|
|
fi
|
|
else
|
|
# $SRCDEST is $startdir, two possibilities
|
|
error "$(gettext "Source destination must be defined in %s.")" "$MAKEPKG_CONF"
|
|
plain "$(gettext "In addition, please run makepkg -C outside of your cache directory.")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if (( ! INFAKEROOT )); then
|
|
if (( EUID == 0 && ! ASROOT )); then
|
|
# Warn those who like to live dangerously.
|
|
error "$(gettext "Running makepkg as root is a BAD idea and can cause")"
|
|
plain "$(gettext "permanent, catastrophic damage to your system. If you")"
|
|
plain "$(gettext "wish to run as root, please use the --asroot option.")"
|
|
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 --asroot option is meant for the root user only.")"
|
|
plain "$(gettext "Please rerun makepkg without the --asroot flag.")"
|
|
exit 1 # $E_USER_ABORT
|
|
elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
|
|
if [ ! $(type -p fakeroot) ]; then
|
|
error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")"
|
|
plain "$(gettext "in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
|
|
exit 1
|
|
fi
|
|
elif (( EUID > 0 )); then
|
|
warning "$(gettext "Running makepkg as an unprivileged user will result in non-root")"
|
|
plain "$(gettext "ownership of the packaged files. Try using the fakeroot environment by")"
|
|
plain "$(gettext "placing 'fakeroot' in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
|
|
sleep 1
|
|
fi
|
|
else
|
|
if [[ -z $FAKEROOTKEY ]]; then
|
|
error "$(gettext "Do not use the '-F' option. This option is only for use by makepkg.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
fi
|
|
|
|
# check for sudo if we will need it during makepkg execution
|
|
if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
|
|
if [ ! "$(type -p sudo)" ]; then
|
|
warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
|
|
fi
|
|
fi
|
|
|
|
unset pkgname pkgbase pkgver pkgrel 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 CRLF characters and cannot be sourced.")" "$BUILDFILE"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ${BUILDFILE:0:1} != "/" ]]; then
|
|
BUILDFILE="$startdir/$BUILDFILE"
|
|
fi
|
|
source "$BUILDFILE"
|
|
fi
|
|
|
|
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
|
|
|
|
# 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
|
|
# The exclamation mark is required here to avoid triggering the ERR trap when
|
|
# a tested function does not exist.
|
|
if [[ $(! type -t build) = "function" ]]; then
|
|
BUILDFUNC=1
|
|
fi
|
|
if [ "$(type -t package)" = "function" ]; then
|
|
PKGFUNC=1
|
|
elif [ $SPLITPKG -eq 0 -a "$(type -t package_${pkgname})" = "function" ]; then
|
|
SPLITPKG=1
|
|
fi
|
|
|
|
pkgbase=${pkgbase:-${pkgname[0]}}
|
|
|
|
if [[ -n "${PKGLIST[@]}" ]]; then
|
|
unset pkgname
|
|
pkgname="${PKGLIST[@]}"
|
|
fi
|
|
|
|
if (( ! SPLITPKG )); then
|
|
if [[ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
|
|
|| -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-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 -f to overwrite)")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
else
|
|
allpkgbuilt=1
|
|
somepkgbuilt=0
|
|
for pkg in ${pkgname[@]}; do
|
|
if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
|
|
|| -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-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 -f to overwrite)")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
if (( somepkgbuilt )); then
|
|
error "$(gettext "Part of the package group has already been built. (use -f to overwrite)")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
unset allpkgbuilt somepkgbuilt
|
|
fi
|
|
|
|
# Run the bare minimum in fakeroot
|
|
if (( INFAKEROOT )); then
|
|
if (( ! SPLITPKG )); then
|
|
if (( ! PKGFUNC )); then
|
|
if (( ! REPKG )); then
|
|
if (( BUILDFUNC )); then
|
|
run_build
|
|
tidy_install
|
|
fi
|
|
else
|
|
warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
|
|
plain "$(gettext "File permissions may not be preserved.")"
|
|
fi
|
|
else
|
|
run_package
|
|
tidy_install
|
|
fi
|
|
create_package
|
|
else
|
|
for pkg in ${pkgname[@]}; do
|
|
pkgdir="$pkgdir/$pkg"
|
|
mkdir -p "$pkgdir"
|
|
chmod a-s "$pkgdir"
|
|
backup_package_variables
|
|
run_package $pkg
|
|
tidy_install
|
|
create_package $pkg
|
|
restore_package_variables
|
|
pkgdir="${pkgdir%/*}"
|
|
done
|
|
fi
|
|
|
|
msg "$(gettext "Leaving fakeroot environment.")"
|
|
exit 0 # $E_OK
|
|
fi
|
|
|
|
msg "$(gettext "Making package: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
|
|
|
|
# if we are creating a source-only package, go no further
|
|
if (( SOURCEONLY )); then
|
|
if [[ -f $SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT} ]] \
|
|
&& (( ! FORCE )); then
|
|
error "$(gettext "A source package has already been built. (use -f to overwrite)")"
|
|
exit 1
|
|
fi
|
|
create_srcpackage
|
|
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%% *}") ]; then
|
|
if (( RMDEPS )); then
|
|
original_pkglist=($(run_pacman -Qq | sort)) # 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 (( RMDEPS )); then
|
|
current_pkglist=($(run_pacman -Qq | sort)) # 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 PATH; skipping dependency checks.")" "${PACMAN%% *}"
|
|
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 src/ tree")"
|
|
warning "$(gettext "Skipping source integrity checks -- using existing src/ tree")"
|
|
warning "$(gettext "Skipping source extraction -- using existing src/ tree")"
|
|
|
|
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
|
|
if (( ! SKIPINTEG )); then
|
|
check_checksums
|
|
else
|
|
warning "$(gettext "Skipping integrity checks.")"
|
|
fi
|
|
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 pkg/ directory...")"
|
|
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
|
|
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 package() function is deprecated.")"
|
|
plain "$(gettext "File permissions may not be preserved.")"
|
|
fi
|
|
fi
|
|
create_package
|
|
else
|
|
for pkg in ${pkgname[@]}; do
|
|
pkgdir="$pkgdir/$pkg"
|
|
mkdir -p "$pkgdir"
|
|
chmod a-s "$pkgdir"
|
|
backup_package_variables
|
|
run_package $pkg
|
|
tidy_install
|
|
create_package $pkg
|
|
restore_package_variables
|
|
pkgdir="${pkgdir%/*}"
|
|
done
|
|
fi
|
|
else
|
|
if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
|
|
devel_update
|
|
(( BUILDFUNC )) && run_build
|
|
cd "$startdir"
|
|
fi
|
|
|
|
msg "$(gettext "Entering fakeroot environment...")"
|
|
|
|
if [[ -n $newpkgver ]]; then
|
|
fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
|
|
else
|
|
fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
msg "$(gettext "Finished making: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
|
|
|
|
install_package
|
|
|
|
exit 0 #E_OK
|
|
|
|
# vim: set ts=2 sw=2 noet:
|