summaryrefslogtreecommitdiffstats
path: root/scripts/makepkg.sh.in
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/makepkg.sh.in')
-rw-r--r--scripts/makepkg.sh.in614
1 files changed, 380 insertions, 234 deletions
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 6fb36d27..ed5cdef7 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -28,10 +28,10 @@
# 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, grep, gzip, openssl, sed, tput (ncurses), xz
+# gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
# gettext initialization
-export TEXTDOMAIN='pacman'
+export TEXTDOMAIN='pacman-scripts'
export TEXTDOMAINDIR='@localedir@'
# file -i does not work on Mac OSX unless legacy mode is set
@@ -41,10 +41,8 @@ myver='@PACKAGE_VERSION@'
confdir='@sysconfdir@'
BUILDSCRIPT='@BUILDSCRIPT@'
startdir="$PWD"
-srcdir="$startdir/src"
-pkgdir="$startdir/pkg"
-packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge')
+packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx')
other_options=('ccache' 'distcc' 'buildflags' 'makeflags')
splitpkg_overrides=('pkgver' 'pkgrel' 'pkgdesc' 'arch' 'license' 'groups' \
'depends' 'optdepends' 'provides' 'conflicts' 'replaces' \
@@ -54,7 +52,6 @@ readonly -a packaging_options other_options splitpkg_overrides
# Options
ASROOT=0
CLEANUP=0
-CLEANCACHE=0
DEP_BIN=0
FORCE=0
INFAKEROOT=0
@@ -75,6 +72,7 @@ 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.
@@ -183,6 +181,17 @@ 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
+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"
@@ -391,7 +400,7 @@ run_pacman() {
local cmd
printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
if (( ! ASROOT )) && [[ ! $1 =~ ^-(T|Qq)$ ]]; then
- if [ "$(type -p sudo)" ]; then
+ if type -p sudo >/dev/null; then
cmd="sudo $cmd"
else
cmd="su root -c '$cmd'"
@@ -509,7 +518,8 @@ download_sources() {
local file=$(get_filepath "$netfile" || true)
if [[ -n "$file" ]]; then
msg2 "$(gettext "Found %s")" "${file##*/}"
- ln -sf "$file" "$srcdir/"
+ rm -f "$srcdir/$file"
+ ln -s "$file" "$srcdir/"
continue
fi
@@ -564,7 +574,7 @@ generate_checksums() {
plain ""
if ! type -p openssl >/dev/null; then
- error "$(gettext "Cannot find openssl.")"
+ error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
exit 1 # $E_MISSING_PROGRAM
fi
@@ -612,11 +622,6 @@ generate_checksums() {
check_checksums() {
(( ! ${#source[@]} )) && return 0
- if ! type -p openssl >/dev/null; 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
@@ -817,9 +822,6 @@ run_build() {
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)
@@ -855,7 +857,7 @@ tidy_install() {
fi
if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
- msg2 "$(gettext "Purging other files...")"
+ msg2 "$(gettext "Purging unwanted files...")"
local pt
for pt in "${PURGE_TARGETS[@]}"; do
if [[ ${pt} = ${pt//\/} ]]; then
@@ -877,8 +879,8 @@ tidy_install() {
# 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"
+ rm -f "$link" "${link}.gz"
+ ln -s "${file}.gz" "${link}.gz"
done
# check file still exists (potentially already compressed due to hardlink)
@@ -921,7 +923,7 @@ tidy_install() {
fi
if [[ $(check_option libtool) = "n" ]]; then
- msg2 "$(gettext "Removing libtool .la files...")"
+ msg2 "$(gettext "Removing "%s" files...")" "libtool"
find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
fi
@@ -929,6 +931,69 @@ tidy_install() {
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() {
@@ -941,7 +1006,7 @@ write_pkginfo() {
local size="$(@DUPATH@ -sk)"
size="$(( ${size%%[^0-9]*} * 1024 ))"
- msg2 "$(gettext "Generating .PKGINFO file...")"
+ msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
echo "# Generated by makepkg $myver"
if (( INFAKEROOT )); then
echo "# using $(fakeroot -v)"
@@ -960,13 +1025,44 @@ write_pkginfo() {
[[ $license ]] && printf "license = %s\n" "${license[@]}"
[[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
[[ $groups ]] && printf "group = %s\n" "${groups[@]}"
- [[ $depends ]] && printf "depend = %s\n" "${depends[@]}"
[[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}"
[[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
- [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
[[ $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
@@ -982,7 +1078,7 @@ write_pkginfo() {
# 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').")"
+ plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
fi
}
@@ -993,7 +1089,7 @@ check_package() {
local file
for file in "${backup[@]}"; do
if [[ ! -f $file ]]; then
- warning "$(gettext "Backup entry file not in package : %s")" "$file"
+ warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
fi
done
@@ -1009,7 +1105,7 @@ check_package() {
create_package() {
if [[ ! -d $pkgdir ]]; then
- error "$(gettext "Missing pkg/ directory.")"
+ error "$(gettext "Missing %s directory.")" "pkg/"
plain "$(gettext "Aborting...")"
exit 1 # $E_MISSING_PKGDIR
fi
@@ -1065,6 +1161,9 @@ create_package() {
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
@@ -1086,9 +1185,16 @@ create_package() {
exit 1 # TODO: error code
fi
+ create_signature "$pkg_file"
+
if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
- ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
+ 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
@@ -1096,24 +1202,30 @@ create_package() {
fi
}
-create_srcpackage() {
- cd "$startdir"
+create_signature() {
+ if [[ $SIGNPKG != 'y' ]]; then
+ return
+ fi
+ local ret=0
+ local filename="$1"
+ msg "$(gettext "Signing package...")"
- # 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
+ local SIGNWITHKEY=""
+ if [[ -n $GPGKEY ]]; then
+ SIGNWITHKEY="-u ${GPGKEY}"
fi
- if (( ! SKIPINTEG )); then
- # We can only check checksums if we have all files.
- check_checksums
+ # 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 "Skipping integrity checks.")"
+ warning "$(gettext "Failed to sign package file.")"
fi
- cd "$startdir"
+}
+create_srcpackage() {
msg "$(gettext "Creating source package...")"
local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
mkdir "${srclinks}"/${pkgbase}
@@ -1169,7 +1281,8 @@ create_srcpackage() {
fi
if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
- ln -sf "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
+ rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
+ ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
ret=$?
fi
@@ -1185,9 +1298,9 @@ install_package() {
(( ! INSTALL )) && return
if (( ! SPLITPKG )); then
- msg "$(gettext "Installing package %s with %s -U...")" "$pkgname" "$PACMAN"
+ msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
else
- msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN"
+ msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
fi
local fullver pkg pkglist
@@ -1248,7 +1361,7 @@ check_sanity() {
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"
+ plain "$(gettext "such as %s.")" "arch=('$CARCH')"
ret=1
fi
fi
@@ -1259,7 +1372,7 @@ check_sanity() {
sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
for i in ${provides_list[@]}; do
if [[ $i != ${i//</} || $i != ${i//>/} ]]; then
- error "$(gettext "Provides array cannot contain comparison (< or >) operators.")"
+ error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
ret=1
fi
done
@@ -1269,7 +1382,7 @@ check_sanity() {
sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
for i in "${backup_list[@]}"; do
if [[ ${i:0:1} = "/" ]]; then
- error "$(gettext "Backup entry should not contain leading slash : %s")" "$i"
+ error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
ret=1
fi
done
@@ -1280,7 +1393,7 @@ check_sanity() {
for i in "${optdepends_list[@]}"; do
local pkg=${i%%:*}
if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]+$ ]]; then
- error "$(gettext "Invalid syntax for optdepend : '%s'")" "$i"
+ error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
ret=1
fi
done
@@ -1311,7 +1424,7 @@ check_sanity() {
fi
done
if (( ! known )); then
- error "$(gettext "options array contains unknown option '%s'")" "$i"
+ error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
valid_options=0
fi
done
@@ -1322,7 +1435,7 @@ check_sanity() {
if (( ${#pkgname[@]} > 1 )); then
for i in ${pkgname[@]}; do
if ! declare -f package_${i} >/dev/null; then
- error "$(gettext "missing package function for split package '%s'")" "$i"
+ error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
ret=1
fi
done
@@ -1330,7 +1443,7 @@ check_sanity() {
for i in ${PKGLIST[@]}; do
if ! in_array $i ${pkgname[@]}; then
- error "$(gettext "requested package %s is not provided in %s")" "$i" "$BUILDFILE"
+ error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
ret=1
fi
done
@@ -1338,6 +1451,84 @@ check_sanity() {
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
+
+ # openssl - checksum operations
+ if (( ! SKIPINTEG )); 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=""
@@ -1353,30 +1544,48 @@ devel_check() {
# 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.
+ # Also do a check to make sure we have the VCS tool available.
oldpkgver=$pkgver
if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
- type -p darcs >/dev/null || return 0
+ 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
- type -p cvs >/dev/null || return 0
+ 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
- type -p git >/dev/null || return 0
+ 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
- type -p svn >/dev/null || return 0
+ 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
- type -p bzr >/dev/null || return 0
+ 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
- type -p hg >/dev/null || return 0
+ 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
@@ -1472,93 +1681,7 @@ canonicalize_path() {
fi
}
-# getopt like parser
-parse_options() {
- local short_options=$1; shift;
- local long_options=$1; shift;
- local ret=0;
- local unused_options=""
- local i
-
- 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
-}
+m4_include(library/parse_options.sh)
usage() {
printf "makepkg (pacman) %s\n" "$myver"
@@ -1566,14 +1689,13 @@ usage() {
printf "$(gettext "Usage: %s [options]")\n" "$0"
echo
echo "$(gettext "Options:")"
- printf "$(gettext " -A, --ignorearch Ignore incomplete arch field in %s")\n" "$BUILDSCRIPT"
+ 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 " -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)")"
+ 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 This help")"
+ 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")"
@@ -1581,23 +1703,26 @@ usage() {
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")"
+ printf "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
- echo "$(gettext " --asroot Allow makepkg to run as root user")"
- printf "$(gettext " --check Run the check() function in the %s")\n" "$BUILDSCRIPT"
+ 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 " --nocheck Do not run the check() function in the %s")\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 " --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:")"
+ 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 -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT"
+ printf "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
echo
}
@@ -1623,10 +1748,10 @@ ARGLIST=("$@")
# Parse Command Line Options.
OPT_SHORT="AcCdefFghiLmop:rRsV"
-OPT_LONG="allsource,asroot,ignorearch,check,clean,cleancache,nodeps"
+OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver"
-OPT_LONG+=",install,log,nocolor,nobuild,nocheck,pkg:,rmdeps"
-OPT_LONG+=",repackage,skipinteg,source,syncdeps,version,config:"
+OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
+OPT_LONG+=",repackage,skipinteg,sign,source,syncdeps,version,config:"
# Pacman Options
OPT_LONG+=",noconfirm,noprogressbar"
OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
@@ -1648,7 +1773,6 @@ while true; do
--asroot) ASROOT=1 ;;
-A|--ignorearch) IGNOREARCH=1 ;;
-c|--clean) CLEANUP=1 ;;
- -C|--cleancache) CLEANCACHE=1 ;;
--check) RUN_CHECK='y' ;;
--config) shift; MAKEPKG_CONF=$1 ;;
-d|--nodeps) NODEPS=1 ;;
@@ -1660,15 +1784,18 @@ while true; do
-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 ;;
--skipinteg) SKIPINTEG=1 ;;
+ --sign) SIGNPKG='y' ;;
--source) SOURCEONLY=1 ;;
-s|--syncdeps) DEP_BIN=1 ;;
@@ -1685,6 +1812,10 @@ done
[[ -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}
@@ -1729,6 +1860,21 @@ 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 [[ ! -w $PKGDEST ]]; then
@@ -1748,82 +1894,41 @@ 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--holdver and --forcever cannot both be specified" )"
+ error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
exit 1
fi
-if (( CLEANCACHE )); then
- #fix flyspray feature request #5223
- if [[ -n $SRCDEST && ! $SRCDEST -ef "${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")"
+ error "$(gettext "Running %s as root is a BAD idea and can cause")" "makepkg"
plain "$(gettext "permanent, catastrophic damage to your system. If you")"
- plain "$(gettext "wish to run as root, please use the --asroot option.")"
+ plain "$(gettext "wish to run as root, please use the %s option.")" "--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 --asroot option is meant for the root user only.")"
- plain "$(gettext "Please rerun makepkg without the --asroot flag.")"
+ error "$(gettext "The %s option is meant for the root user only.")" "--asroot"
+ plain "$(gettext "Please rerun %s without the %s flag.")" "makepkg" "--asroot"
exit 1 # $E_USER_ABORT
- elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
- if ! type -p fakeroot >/dev/null; 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"
+ elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
+ warning "$(gettext "Running %s as an unprivileged user will result in non-root")" "makepkg"
+ plain "$(gettext "ownership of the packaged files. Try using the %s environment by")" "fakeroot"
+ plain "$(gettext "placing %s in the %s array in %s.")" "'fakeroot'" "BUILDENV" "$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.")"
+ 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
-# 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
-
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
@@ -1841,7 +1946,7 @@ if [[ ! -f $BUILDFILE ]]; then
else
crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
if [[ -n $crlftest ]]; then
- error "$(gettext "%s contains CRLF characters and cannot be sourced.")" "$BUILDFILE"
+ error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
exit 1
fi
@@ -1867,6 +1972,9 @@ 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
@@ -1899,6 +2007,22 @@ if [[ -n "${PKGLIST[@]}" ]]; then
pkgname=("${PKGLIST[@]}")
fi
+# check if gpg signature is to be created and if signing key is valid
+if [[ -z "$SIGNPKG" && $(check_buildenv sign) == 'y' ]]; then
+ SIGNPKG='y'
+fi
+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 $epoch $pkgver $pkgrel)
if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \
@@ -1909,7 +2033,7 @@ if (( ! SPLITPKG )); then
install_package
exit $?
else
- error "$(gettext "A package has already been built. (use -f to overwrite)")"
+ error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
exit 1
fi
fi
@@ -1933,12 +2057,12 @@ else
install_package
exit $?
else
- error "$(gettext "The package group has already been built. (use -f to overwrite)")"
+ 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 -f to overwrite)")"
+ error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
exit 1
fi
fi
@@ -1947,6 +2071,12 @@ 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
@@ -1956,7 +2086,7 @@ if (( INFAKEROOT )); then
tidy_install
fi
else
- warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
+ warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
plain "$(gettext "File permissions may not be preserved.")"
fi
else
@@ -1968,7 +2098,7 @@ if (( INFAKEROOT )); then
run_split_packaging
fi
- msg "$(gettext "Leaving fakeroot environment.")"
+ msg "$(gettext "Leaving %s environment.")" "fakeroot"
exit 0 # $E_OK
fi
@@ -1979,10 +2109,32 @@ msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
if (( SOURCEONLY )); then
if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
&& (( ! FORCE )); then
- error "$(gettext "A source package has already been built. (use -f to overwrite)")"
+ error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
exit 1
fi
- create_srcpackage
+
+ # 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"
+
+ # 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
@@ -2017,7 +2169,7 @@ elif type -p "${PACMAN%% *}" >/dev/null; then
exit 1
fi
else
- warning "$(gettext "%s was not found in PATH; skipping dependency checks.")" "${PACMAN%% *}"
+ warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
fi
# ensure we have a sane umask set
@@ -2029,9 +2181,9 @@ 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")"
+ 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!")"
@@ -2061,7 +2213,7 @@ if (( NOBUILD )); then
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...")"
+ msg "$(gettext "Removing existing %s directory...")" "pkg/"
rm -rf "$pkgdir"
fi
mkdir -p "$pkgdir"
@@ -2083,7 +2235,7 @@ else
if (( ! REPKG )); then
tidy_install
else
- warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
+ warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
plain "$(gettext "File permissions may not be preserved.")"
fi
fi
@@ -2099,13 +2251,7 @@ else
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
+ enter_fakeroot
fi
fi