summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO38
-rw-r--r--.gitignore3
-rw-r--r--00.optipng.patch17
-rw-r--r--01.upx.patch17
-rw-r--r--02.lto.patch20
-rw-r--r--03.pgo.patch47
-rw-r--r--PKGBUILD60
-rw-r--r--conf.optipng-upx.patch21
-rw-r--r--conf.pgo-lto.patch20
-rw-r--r--makepkg2384
-rw-r--r--makepkg.conf148
-rw-r--r--opticonf.patch43
-rwxr-xr-xoptipng.sh44
-rwxr-xr-xupx.sh46
14 files changed, 2908 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..6fd6c8aeab45
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,38 @@
+# Generated by mksrcinfo v8
+# Sun Mar 20 15:05:53 UTC 2016
+pkgbase = makepkg-optimize
+ pkgdesc = Additional package optimization routines for makepkg
+ pkgver = 1
+ pkgrel = 1
+ url = https://projects.archlinux.org/pacman.git/
+ arch = x86_64
+ license = GPL
+ makedepends = pacman
+ depends = pacman
+ depends = upx
+ depends = optipng
+ source = 00.optipng.patch
+ source = 01.upx.patch
+ source = 02.lto.patch
+ source = 03.pgo.patch
+ source = upx.sh
+ source = optipng.sh
+ source = conf.pgo-lto.patch
+ source = conf.optipng-upx.patch
+ source = opticonf.patch
+ source = makepkg
+ source = makepkg.conf
+ sha512sums = 67fb9359cd5dc52413ad2ca7e91b445826d7cf6b7ad3db0d2b3845310ab0bdfc41c2e70cec564e26269521ac313f7202c44996a24266380e48e88927bd1012e2
+ sha512sums = b4896082fd7fc4a69abc5fc98bf22c92a94cef9ccae5d3e5d1825cd3f04dcff1bce622a3f7fdc00bd43b5e1d091825d119b3a91d354f1ab58e6a8fe3af72b0e2
+ sha512sums = e8d9112c8ff66136451d2746a91c2c43083541322ca5430a0bc6bf03e65ace5ff00296ffea4582075a325d02ddf1d880483025d1fcfba2ce749e12d6418b413b
+ sha512sums = fa2a5aea8df56e0427c0fc37c7bb48ba4314176024177aebb8b890a415b23d7306a90f8987ab05e3b4f8e448ebf2475531970f7c161fe7088b37ac908b778850
+ sha512sums = db55e9d4302035447854ec34d44d454a1a68882437129c00de388f56413cff71e133848df5a09962c40f2bd0203f5e5c692af4e100e67072da4b504ef4752ca4
+ sha512sums = 60ca209609ddbf617e63c7103d675da17671efc91db066a1e11dd1df78f9c8abf267f1cd417ff3b5db59411cf6e7df134e6bd8b06c73442410f14c13b1f5dd53
+ sha512sums = de9fd2a9f394250e841a8e5228a180dad9e04aceb1427843056e6c4a4c6b066d36f607eb7493527258741c9521dcd58f3dd1e2191e5add5db0c871eee9e6e133
+ sha512sums = cef2f8f3e82fa668c490f305bb01a344391958ca3f0be95da09e6008b30ecf996803dfda863a73e340c71937c7691d115bfe7e109c71d71eb65b5052bb179504
+ sha512sums = 16c2b0e666234f1a493e7456f4c387fbabd24b10514c93fa4338520e8f537e9a12de0d833a6148fe871452d87f6e1b3454b2bde332b9ba4c4e7680616b7eeede
+ sha512sums = 6df2ac2133f72ac2f3533fa9e3cc9337849dd5afbba2fd66b5d4d8b0b65a892c04771ceb6407eac357755fef87ac940d7848ccad915c387e465ad46b1ed496a3
+ sha512sums = 9e04d88c43cc25d21854ffc536cf9fd682d150fed08440a44a60b4e67285c28163cb069182355e718b2a6b6df8d536d8b32dcaac76f04d346cd658850b46769d
+
+pkgname = makepkg-optimize
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..a90e3355d235
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.pkg.tar.xz
+pkg/
+src/
diff --git a/00.optipng.patch b/00.optipng.patch
new file mode 100644
index 000000000000..0c02a0ce1140
--- /dev/null
+++ b/00.optipng.patch
@@ -0,0 +1,17 @@
+--- makepkg-optimize
++++ makepkg-optimize
+@@ -1556,6 +1556,14 @@
+ fi
+ fi
+
++ # optipng - PNG image optimization
++ if check_option "optipng" "y"; then
++ if ! type -p optipng >/dev/null; then
++ error "$(gettext "Cannot find the %s binary required for optimizing PNG images.")" "optipng"
++ ret=1
++ fi
++ fi
++
+ # distcc - compilation with distcc
+ if check_buildoption "distcc" "y"; then
+ if ! type -p distcc >/dev/null; then
diff --git a/01.upx.patch b/01.upx.patch
new file mode 100644
index 000000000000..1883b75fdbf4
--- /dev/null
+++ b/01.upx.patch
@@ -0,0 +1,17 @@
+--- makepkg-optimize
++++ makepkg-optimize
+@@ -1556,6 +1556,14 @@
+ 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
++
+ # optipng - PNG image optimization
+ if check_option "optipng" "y"; then
+ if ! type -p optipng >/dev/null; then
diff --git a/02.lto.patch b/02.lto.patch
new file mode 100644
index 000000000000..eb611f431acb
--- /dev/null
+++ b/02.lto.patch
@@ -0,0 +1,20 @@
+--- makepkg-optimize
++++ makepkg-optimize
+@@ -866,6 +866,17 @@ run_build() {
+ export DISTCC_HOSTS
+ fi
+
++ # Use lto if it is requested (check buildenv and PKGBUILD opts)
++ if check_buildoption "lto" "y" && [[ -f "$(gcc -print-search-dirs | grep install | awk '{print $2 "liblto_plugin.so"}')" ]]; then
++ CFLAGS+=" -flto=$(getconf _NPROCESSORS_ONLN)"
++ CXXFLAGS+=" -flto=$(getconf _NPROCESSORS_ONLN)"
++ LDFLAGS+=" $CFLAGS $CXXFLAGS -Wl,-fuse-linker-plugin"
++ LTOPLUGIN="$(gcc -print-search-dirs | grep install | awk '{print $2 "liblto_plugin.so"}')"
++ ARFLAGS+=" --plugin $LTOPLUGIN"
++ RANLIBFLAGS+=" --plugin $LTOPLUGIN"
++ NMFLAGS+=" --plugin $LTOPLUGIN"
++ fi
++
+ run_function_safe "build"
+ }
+
diff --git a/03.pgo.patch b/03.pgo.patch
new file mode 100644
index 000000000000..43b47ee551c8
--- /dev/null
+++ b/03.pgo.patch
@@ -0,0 +1,47 @@
+--- makepkg-optimize
++++ makepkg-optimize
+@@ -877,6 +877,21 @@ run_build() {
+ NMFLAGS+=" --plugin $LTOPLUGIN"
+ fi
+
++ # Generate or utilize pgo if it is requested (check buildenv and PKGBUILD opts)
++ if check_buildoption "pgo" "y"; then
++ if [ ! -d "$PROFDEST/$pkgbase.gen" ]; then
++ mkdir "$PROFDEST/$pkgbase.gen"
++ CFLAGS+=" -fprofile-generate -fprofile-dir=$PROFDEST/$pkgbase.gen"
++ CXXFLAGS+=" -fprofile-generate -fprofile-dir=$PROFDEST/$pkgbase.gen"
++ LDFLAGS+=" -Wl,-lgcov"
++ elif [ ! -d "$PROFDEST/$pkgbase.used" ]; then
++ mv "$PROFDEST/$pkgbase.gen" "$PROFDEST/$pkgbase.used"
++ CFLAGS+=" -fprofile-correction -fprofile-use -fprofile-dir=$PROFDEST/$pkgbase.used"
++ CXXFLAGS+=" -fprofile-correction -fprofile-use -fprofile-dir=$PROFDEST/$pkgbase.used"
++ fi
++ fi
++
++
+ run_function_safe "build"
+ }
+
+@@ -2012,6 +2027,7 @@ trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' E
+ # preserve environment variables and canonicalize path
+ [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
+ [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
++[[ -n ${PROFDEST} ]] && _PROFDEST=$(canonicalize_path ${PROFDEST})
+ [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
+ [[ -n ${LOGDEST} ]] && _LOGDEST=$(canonicalize_path ${LOGDEST})
+ [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
+@@ -2109,6 +2125,14 @@ if (( SOURCEONLY )); then
+ IGNOREARCH=1
+ fi
+
++PROFDEST=${_PROFDEST:-$PROFDEST}
++PROFDEST=${PROFDEST:-$startdir} #default to $startdir if undefined
++if [[ ! -w $PROFDEST ]] ; then
++ error "$(gettext "You do not have write permission to store profiles in %s.")" "$PROFDEST"
++ plain "$(gettext "Aborting...")"
++ exit 1
++fi
++
+ LOGDEST=${_LOGDEST:-$LOGDEST}
+ LOGDEST=${LOGDEST:-$startdir} #default to $startdir if undefined
+ if (( LOGGING )) && [[ ! -w $LOGDEST ]]; then
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..fe2c48fe0530
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,60 @@
+# Maintainer: Que Quotion ( quequotion at g mail dot com )
+
+pkgname=makepkg-optimize
+pkgver=1
+pkgrel=1
+pkgdesc='Additional package optimization routines for makepkg'
+arch=('x86_64')
+license=('GPL')
+url='https://projects.archlinux.org/pacman.git/'
+depends=('pacman' 'upx' 'optipng')
+makedepends=('pacman')
+source=('00.optipng.patch' '01.upx.patch' '02.lto.patch' '03.pgo.patch'
+ 'upx.sh' 'optipng.sh'
+ 'conf.pgo-lto.patch' 'conf.optipng-upx.patch' 'opticonf.patch'
+ 'makepkg' 'makepkg.conf')
+sha512sums=('67fb9359cd5dc52413ad2ca7e91b445826d7cf6b7ad3db0d2b3845310ab0bdfc41c2e70cec564e26269521ac313f7202c44996a24266380e48e88927bd1012e2'
+ 'b4896082fd7fc4a69abc5fc98bf22c92a94cef9ccae5d3e5d1825cd3f04dcff1bce622a3f7fdc00bd43b5e1d091825d119b3a91d354f1ab58e6a8fe3af72b0e2'
+ 'e8d9112c8ff66136451d2746a91c2c43083541322ca5430a0bc6bf03e65ace5ff00296ffea4582075a325d02ddf1d880483025d1fcfba2ce749e12d6418b413b'
+ 'fa2a5aea8df56e0427c0fc37c7bb48ba4314176024177aebb8b890a415b23d7306a90f8987ab05e3b4f8e448ebf2475531970f7c161fe7088b37ac908b778850'
+ 'db55e9d4302035447854ec34d44d454a1a68882437129c00de388f56413cff71e133848df5a09962c40f2bd0203f5e5c692af4e100e67072da4b504ef4752ca4'
+ '60ca209609ddbf617e63c7103d675da17671efc91db066a1e11dd1df78f9c8abf267f1cd417ff3b5db59411cf6e7df134e6bd8b06c73442410f14c13b1f5dd53'
+ 'de9fd2a9f394250e841a8e5228a180dad9e04aceb1427843056e6c4a4c6b066d36f607eb7493527258741c9521dcd58f3dd1e2191e5add5db0c871eee9e6e133'
+ 'cef2f8f3e82fa668c490f305bb01a344391958ca3f0be95da09e6008b30ecf996803dfda863a73e340c71937c7691d115bfe7e109c71d71eb65b5052bb179504'
+ '16c2b0e666234f1a493e7456f4c387fbabd24b10514c93fa4338520e8f537e9a12de0d833a6148fe871452d87f6e1b3454b2bde332b9ba4c4e7680616b7eeede'
+ '6df2ac2133f72ac2f3533fa9e3cc9337849dd5afbba2fd66b5d4d8b0b65a892c04771ceb6407eac357755fef87ac940d7848ccad915c387e465ad46b1ed496a3'
+ '9e04d88c43cc25d21854ffc536cf9fd682d150fed08440a44a60b4e67285c28163cb069182355e718b2a6b6df8d536d8b32dcaac76f04d346cd658850b46769d')
+
+prepare() {
+ # Use the user's currently installed versions of both
+ #cp /usr/bin/makepkg ./makepkg-optimize
+ #cp /etc/makepkg.conf ./makepkg-optimize.conf
+
+ # Replace with above after pacman update
+ mkdir $pkgname
+ cd $pkgname
+ cp ../makepkg makepkg-optimize
+ cp ../makepkg.conf makepkg-optimize.conf
+
+ # Separate config file
+ patch -Np0 < ../opticonf.patch
+ patch -Np0 < ../conf.optipng-upx.patch
+ patch -Np0 < ../conf.pgo-lto.patch
+
+ # Add features in series
+ patch -Np0 < ../00.optipng.patch
+ patch -Np0 < ../01.upx.patch
+ patch -Np0 < ../02.lto.patch
+ patch -Np0 < ../03.pgo.patch
+}
+
+package() {
+ cd $pkgname
+ mkdir -p $pkgdir/usr/{bin,share/makepkg/tidy}/
+ install -m755 makepkg-optimize $pkgdir/usr/bin/
+ #Uncomment once dropped from pacman.
+ #install -m755 ../optipng.sh $pkgdir/usr/share/makepkg/tidy/optipng.sh
+ #install -m755 ../upx.sh $pkgdir/usr/share/makepkg/tidy/upx.sh
+ mkdir -p $pkgdir/etc/
+ install -m644 makepkg-optimize.conf $pkgdir/etc/
+}
diff --git a/conf.optipng-upx.patch b/conf.optipng-upx.patch
new file mode 100644
index 000000000000..1dac002a2bc7
--- /dev/null
+++ b/conf.optipng-upx.patch
@@ -0,0 +1,21 @@
+--- makepkg-optimize.conf
++++ makepkg-optimize.conf
+@@ -83,6 +83,8 @@
+ #-- emptydirs: Leave empty directories in packages
+ #-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip
+ #-- purge: Remove files specified by PURGE_TARGETS
++#-- upx: Compress binary executable files using UPX
++#-- optipng: Optimize PNG images with optipng
+ #-- debug: Add debugging flags as specified in DEBUG_* variables
+ #
+ OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !optipng !upx !debug)
+@@ -126,6 +129,8 @@
+ DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc})
+ #-- Files to be removed from all packages (if purge is specified)
+ PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
++#-- Compression parameters for UPX
++UPXFLAGS="--ultra-brute"
+
+ #########################################################################
+ # PACKAGE OUTPUT
+
diff --git a/conf.pgo-lto.patch b/conf.pgo-lto.patch
new file mode 100644
index 000000000000..8121e6bea69a
--- /dev/null
+++ b/conf.pgo-lto.patch
@@ -0,0 +1,20 @@
+--- makepkg-optimize.conf
++++ makepkg-optimize.conf
+@@ -83,6 +83,8 @@
+ #-- ccache: Use ccache to cache compilation
+ #-- check: Run the check() function if present in the PKGBUILD
+ #-- sign: Generate PGP signature file
++#-- lto: Use link-time optimization to reduce compiled binary size and possibly improve performance
++#-- pgo: Generate or use profile guided optimization to reduce compile binary size and improve performance
+ #
+ BUILDENV=(!distcc color !ccache !check !sign)
+ #
+@@ -142,6 +144,8 @@
+ #SRCDEST=/home/sources
+ #-- Source packages: specify a fixed directory where all src packages will be placed
+ #SRCPKGDEST=/home/srcpackages
++#-- Profile cache: specify a fixed directory where profiles will be stored
++#PROFDEST=/home/sources
+ #-- Log files: specify a fixed directory where all log files will be placed
+ #LOGDEST=/home/makepkglogs
+ #-- Packager: name/email of the person or organization building packages
diff --git a/makepkg b/makepkg
new file mode 100644
index 000000000000..ea559634c2d3
--- /dev/null
+++ b/makepkg
@@ -0,0 +1,2384 @@
+#!/usr/bin/bash
+#
+# makepkg - make packages compatible for use with pacman
+# Generated from makepkg.sh.in; do not edit by hand.
+#
+# Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
+# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
+# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
+# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# makepkg uses quite a few external programs during its execution. You
+# need to have at least the following installed for makepkg to function:
+# awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
+# gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
+
+# gettext initialization
+export TEXTDOMAIN='pacman-scripts'
+export TEXTDOMAINDIR='/usr/share/locale'
+
+# file -i does not work on Mac OSX unless legacy mode is set
+export COMMAND_MODE='legacy'
+# Ensure CDPATH doesn't screw with our cd calls
+unset CDPATH
+# Ensure GREP_OPTIONS doesn't screw with our grep calls
+unset GREP_OPTIONS
+
+declare -r makepkg_version='5.0.1'
+declare -r confdir='/etc'
+declare -r BUILDSCRIPT='PKGBUILD'
+declare -r startdir="$PWD"
+
+LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
+
+build_options=('ccache' 'distcc' 'buildflags' 'makeflags')
+splitpkg_overrides=('pkgdesc' 'arch' 'url' 'license' 'groups' 'depends'
+ 'optdepends' 'provides' 'conflicts' 'replaces' 'backup'
+ 'options' 'install' 'changelog')
+readonly -a build_options splitpkg_overrides
+
+known_hash_algos=('md5' 'sha1' 'sha224' 'sha256' 'sha384' 'sha512' 'whirlpool')
+
+# Options
+ASDEPS=0
+BUILDFUNC=0
+CHECKFUNC=0
+CLEANBUILD=0
+CLEANUP=0
+DEP_BIN=0
+FORCE=0
+GENINTEG=0
+HOLDVER=0
+IGNOREARCH=0
+INFAKEROOT=0
+INSTALL=0
+LOGGING=0
+NEEDED=0
+NOARCHIVE=0
+NOBUILD=0
+NODEPS=0
+NOEXTRACT=0
+PKGFUNC=0
+PKGVERFUNC=0
+PREPAREFUNC=0
+REPKG=0
+RMDEPS=0
+SKIPCHECKSUMS=0
+SKIPPGPCHECK=0
+SIGNPKG=''
+SPLITPKG=0
+SOURCEONLY=0
+VERIFYSOURCE=0
+
+PACMAN_OPTS=
+
+shopt -s extglob
+
+### SUBROUTINES ###
+
+# Import libmakepkg
+for lib in "$LIBRARY"/*.sh; do
+ source "$lib"
+done
+
+##
+# 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() {
+ local signal=$1; shift
+
+ if (( ! INFAKEROOT )); then
+ echo
+ error "$@"
+ fi
+ [[ -n $srclinks ]] && rm -rf "$srclinks"
+
+ # unset the trap for this signal, and then call the default handler
+ trap -- "$signal"
+ kill "-$signal" "$$"
+}
+
+
+##
+# Clean up function. Called automatically when the script exits.
+##
+clean_up() {
+ local EXIT_CODE=$?
+
+ if (( INFAKEROOT )); then
+ # Don't clean up when leaving fakeroot, we're not done yet.
+ return
+ fi
+
+ if (( ! EXIT_CODE && CLEANUP )); then
+ local pkg file
+
+ # If it's a clean exit and -c/--clean has been passed...
+ msg "$(gettext "Cleaning up...")"
+ rm -rf "$pkgdirbase" "$srcdir"
+ if [[ -n $pkgbase ]]; then
+ local fullver=$(get_full_version)
+ # Can't do this unless the BUILDSCRIPT has been sourced.
+ if (( BUILDFUNC )); then
+ rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
+ fi
+ if (( CHECKFUNC )); then
+ rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
+ fi
+ if (( PKGFUNC )); then
+ rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
+ elif (( SPLITPKG )); then
+ for pkg in ${pkgname[@]}; do
+ rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
+ done
+ fi
+
+ # clean up dangling symlinks to packages
+ for pkg in ${pkgname[@]}; do
+ for file in ${pkg}-*-*-*{${PKGEXT},${SRCEXT}}; do
+ if [[ -h $file && ! -e $file ]]; then
+ rm -f "$file"
+ fi
+ done
+ done
+ fi
+ fi
+
+ remove_deps
+}
+
+enter_fakeroot() {
+ msg "$(gettext "Entering %s environment...")" "fakeroot"
+ fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
+}
+
+# Automatically update pkgver variable if a pkgver() function is provided
+# Re-sources the PKGBUILD afterwards to allow for other variables that use $pkgver
+update_pkgver() {
+ newpkgver=$(run_function_safe pkgver)
+ if ! check_pkgver "$newpkgver"; then
+ error "$(gettext "pkgver() generated an invalid version: %s")" "$newpkgver"
+ exit 1
+ fi
+
+ if [[ -n $newpkgver && $newpkgver != "$pkgver" ]]; then
+ if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
+ if ! sed --follow-symlinks -i "s:^pkgver=[^ ]*:pkgver=$newpkgver:" "$BUILDFILE"; then
+ error "$(gettext "Failed to update %s from %s to %s")" \
+ "pkgver" "$pkgver" "$newpkgver"
+ exit 1
+ fi
+ sed --follow-symlinks -i "s:^pkgrel=[^ ]*:pkgrel=1:" "$BUILDFILE"
+ source_safe "$BUILDFILE"
+ local fullver=$(get_full_version)
+ msg "$(gettext "Updated version: %s")" "$pkgbase $fullver"
+ else
+ warning "$(gettext "%s is not writeable -- pkgver will not be updated")" \
+ "$BUILDFILE"
+ fi
+ fi
+}
+
+# Print 'source not found' error message and exit makepkg
+missing_source_file() {
+ error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
+ plain "$(gettext "Aborting...")"
+ exit 1 # $E_MISSING_FILE
+}
+
+source_has_signatures() {
+ local file all_sources
+
+ get_all_sources_for_arch 'all_sources'
+ for file in "${all_sources[@]}"; do
+ if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+run_pacman() {
+ local cmd
+ if [[ $1 != -@(T|Qq) ]]; then
+ cmd=("$PACMAN_PATH" $PACMAN_OPTS "$@")
+ else
+ cmd=("$PACMAN_PATH" "$@")
+ fi
+ if [[ $1 != -@(T|Qq|Q) ]]; then
+ if type -p sudo >/dev/null; then
+ cmd=(sudo "${cmd[@]}")
+ else
+ cmd=(su root -c "$(printf '%q ' "${cmd[@]}")")
+ fi
+ fi
+ "${cmd[@]}"
+}
+
+check_deps() {
+ (( $# > 0 )) || return 0
+
+ local ret=0
+ local pmout
+ pmout=$(run_pacman -T "$@")
+ ret=$?
+
+ if (( ret == 127 )); then #unresolved deps
+ printf "%s\n" "$pmout"
+ elif (( ret )); then
+ error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
+ return "$ret"
+ fi
+}
+
+handle_deps() {
+ local R_DEPS_SATISFIED=0
+ local R_DEPS_MISSING=1
+
+ (( $# == 0 )) && return $R_DEPS_SATISFIED
+
+ local deplist="$*"
+
+ if (( ! DEP_BIN )); then
+ return $R_DEPS_MISSING
+ fi
+
+ if (( DEP_BIN )); then
+ # install missing deps from binary packages (using pacman -S)
+ msg "$(gettext "Installing missing dependencies...")"
+
+ if ! run_pacman -S --asdeps $deplist; then
+ error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
+ exit 1 # TODO: error code
+ fi
+ fi
+
+ # we might need the new system environment
+ # save our shell options and turn off extglob
+ local shellopts=$(shopt -p)
+ shopt -u extglob
+ source /etc/profile &>/dev/null
+ eval "$shellopts"
+
+ return $R_DEPS_SATISFIED
+}
+
+resolve_deps() {
+ local R_DEPS_SATISFIED=0
+ local R_DEPS_MISSING=1
+
+ # deplist cannot be declared like this: local deplist=$(foo)
+ # Otherwise, the return value will depend on the assignment.
+ local deplist
+ deplist="$(set +E; check_deps $*)" || exit 1
+ [[ -z $deplist ]] && return $R_DEPS_SATISFIED
+
+ if handle_deps $deplist; then
+ # check deps again to make sure they were resolved
+ deplist="$(set +E; check_deps $*)" || exit 1
+ [[ -z $deplist ]] && return $R_DEPS_SATISFIED
+ fi
+
+ msg "$(gettext "Missing dependencies:")"
+ local dep
+ for dep in $deplist; do
+ msg2 "$dep"
+ done
+
+ return $R_DEPS_MISSING
+}
+
+remove_deps() {
+ (( ! RMDEPS )) && return
+
+ # check for packages removed during dependency install (e.g. due to conflicts)
+ # removing all installed packages is risky in this case
+ if [[ -n $(grep -xvFf <(printf '%s\n' "${current_pkglist[@]}") \
+ <(printf '%s\n' "${original_pkglist[@]}")) ]]; then
+ warning "$(gettext "Failed to remove installed dependencies.")"
+ return 0
+ fi
+
+ local deplist
+ deplist=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
+ <(printf "%s\n" "${current_pkglist[@]}")))
+ if [[ -z $deplist ]]; then
+ return 0
+ fi
+
+ 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
+}
+
+get_integlist() {
+ local integ
+ local integlist=()
+
+ for integ in "${known_hash_algos[@]}"; do
+ local sumname="${integ}sums[@]"
+ if [[ -n ${!sumname} ]]; then
+ integlist+=("$integ")
+ fi
+ done
+
+ if (( ${#integlist[@]} > 0 )); then
+ printf "%s\n" "${integlist[@]}"
+ else
+ printf "%s\n" "${INTEGRITY_CHECK[@]}"
+ fi
+}
+
+generate_one_checksum() {
+ local integ=$1 arch=$2 sources numsrc indentsz idx
+
+ if [[ $arch ]]; then
+ array_build sources "source_$arch"
+ else
+ array_build sources 'source'
+ fi
+
+ numsrc=${#sources[*]}
+ if (( numsrc == 0 )); then
+ return
+ fi
+
+ if [[ $arch ]]; then
+ printf "%ssums_%s=(%n" "$integ" "$arch" indentsz
+ else
+ printf "%ssums=(%n" "$integ" indentsz
+ fi
+
+ for (( idx = 0; idx < numsrc; ++idx )); do
+ local netfile=${sources[idx]}
+ local proto sum
+ proto="$(get_protocol "$netfile")"
+
+ case $proto in
+ bzr*|git*|hg*|svn*)
+ sum="SKIP"
+ ;;
+ *)
+ if [[ $netfile != *.@(sig?(n)|asc) ]]; then
+ local file
+ file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
+ sum="$(openssl dgst -${integ} "$file")"
+ sum=${sum##* }
+ else
+ sum="SKIP"
+ fi
+ ;;
+ esac
+
+ # indent checksum on lines after the first
+ printf "%*s%s" $(( idx ? indentsz : 0 )) '' "'$sum'"
+
+ # print a newline on lines before the last
+ (( idx < (numsrc - 1) )) && echo
+ done
+
+ echo ")"
+}
+
+generate_checksums() {
+ msg "$(gettext "Generating checksums for source files...")"
+
+ if ! type -p openssl >/dev/null; then
+ error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
+ exit 1 # $E_MISSING_PROGRAM
+ fi
+
+ local integlist
+ if (( $# == 0 )); then
+ IFS=$'\n' read -rd '' -a integlist < <(get_integlist)
+ else
+ integlist=("$@")
+ fi
+
+ local integ
+ for integ in "${integlist[@]}"; do
+ if ! in_array "$integ" "${known_hash_algos[@]}"; then
+ error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
+ exit 1 # $E_CONFIG_ERROR
+ fi
+
+ generate_one_checksum "$integ"
+ for a in "${arch[@]}"; do
+ generate_one_checksum "$integ" "$a"
+ done
+ done
+}
+
+verify_integrity_one() {
+ local source_name=$1 integ=$2 expectedsum=$3
+
+ local file="$(get_filename "$source_name")"
+ printf ' %s ... ' "$file" >&2
+
+ if [[ $expectedsum = 'SKIP' ]]; then
+ printf '%s\n' "$(gettext "Skipped")" >&2
+ return
+ fi
+
+ if ! file="$(get_filepath "$file")"; then
+ printf '%s\n' "$(gettext "NOT FOUND")" >&2
+ return 1
+ fi
+
+ local realsum="$(openssl dgst -${integ} "$file")"
+ realsum="${realsum##* }"
+ if [[ ${expectedsum,,} = "$realsum" ]]; then
+ printf '%s\n' "$(gettext "Passed")" >&2
+ else
+ printf '%s\n' "$(gettext "FAILED")" >&2
+ return 1
+ fi
+
+ return 0
+}
+
+verify_integrity_sums() {
+ local integ=$1 arch=$2 integrity_sums=() sources=() srcname
+
+ if [[ $arch ]]; then
+ array_build integrity_sums "${integ}sums_$arch"
+ srcname=source_$arch
+ else
+ array_build integrity_sums "${integ}sums"
+ srcname=source
+ fi
+
+ array_build sources "$srcname"
+ if (( ${#integrity_sums[@]} == 0 && ${#sources[@]} == 0 )); then
+ return 1
+ fi
+
+ if (( ${#integrity_sums[@]} == ${#sources[@]} )); then
+ msg "$(gettext "Validating %s files with %s...")" "$srcname" "${integ}sums"
+ local idx errors=0
+ for (( idx = 0; idx < ${#sources[*]}; idx++ )); do
+ verify_integrity_one "${sources[idx]}" "$integ" "${integrity_sums[idx]}" || errors=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
+ else
+ return 1
+ fi
+}
+
+check_checksums() {
+ local integ a
+ declare -A correlation
+ (( SKIPCHECKSUMS )) && return 0
+
+ # Initialize a map which we'll use to verify that every source array has at
+ # least some kind of checksum array associated with it.
+ (( ${#source[*]} )) && correlation['source']=1
+ case $1 in
+ all)
+ for a in "${arch[@]}"; do
+ array_build _ source_"$a" && correlation["source_$a"]=1
+ done
+ ;;
+ *)
+ array_build _ source_"$CARCH" && correlation["source_$CARCH"]=1
+ ;;
+ esac
+
+ for integ in "${known_hash_algos[@]}"; do
+ verify_integrity_sums "$integ" && unset "correlation[source]"
+
+ case $1 in
+ all)
+ for a in "${arch[@]}"; do
+ verify_integrity_sums "$integ" "$a" && unset "correlation[source_$a]"
+ done
+ ;;
+ *)
+ verify_integrity_sums "$integ" "$CARCH" && unset "correlation[source_$CARCH]"
+ ;;
+ esac
+ done
+
+ if (( ${#correlation[*]} )); then
+ error "$(gettext "Integrity checks are missing for: %s")" "${!correlation[*]}"
+ exit 1 # TODO: error code
+ fi
+}
+
+parse_gpg_statusfile() {
+ local type arg1 arg6 arg10
+
+ while read -r _ type arg1 _ _ _ _ arg6 _ _ _ arg10 _; do
+ case "$type" in
+ GOODSIG)
+ pubkey=$arg1
+ success=1
+ status="good"
+ ;;
+ EXPSIG)
+ pubkey=$arg1
+ success=1
+ status="expired"
+ ;;
+ EXPKEYSIG)
+ pubkey=$arg1
+ success=1
+ status="expiredkey"
+ ;;
+ REVKEYSIG)
+ pubkey=$arg1
+ success=0
+ status="revokedkey"
+ ;;
+ BADSIG)
+ pubkey=$arg1
+ success=0
+ status="bad"
+ ;;
+ ERRSIG)
+ pubkey=$arg1
+ success=0
+ if [[ $arg6 == 9 ]]; then
+ status="missingkey"
+ else
+ status="error"
+ fi
+ ;;
+ VALIDSIG)
+ if [[ $arg10 ]]; then
+ # If the file was signed with a subkey, arg10 contains
+ # the fingerprint of the primary key
+ fingerprint=$arg10
+ else
+ fingerprint=$arg1
+ fi
+ ;;
+ TRUST_UNDEFINED|TRUST_NEVER)
+ trusted=0
+ ;;
+ TRUST_MARGINAL|TRUST_FULLY|TRUST_ULTIMATE)
+ trusted=1
+ ;;
+ esac
+ done < "$1"
+}
+
+check_pgpsigs() {
+ (( SKIPPGPCHECK )) && return 0
+ ! source_has_signatures && return 0
+
+ msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
+
+ local file ext decompress found pubkey success status fingerprint trusted
+ local warning=0
+ local errors=0
+ local statusfile=$(mktemp)
+ local all_sources
+
+ case $1 in
+ all)
+ get_all_sources 'all_sources'
+ ;;
+ *)
+ get_all_sources_for_arch 'all_sources'
+ ;;
+ esac
+ for file in "${all_sources[@]}"; do
+ file="$(get_filename "$file")"
+ if [[ $file != *.@(sig?(n)|asc) ]]; then
+ continue
+ fi
+
+ printf " %s ... " "${file%.*}" >&2
+
+ if ! file="$(get_filepath "$file")"; then
+ printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
+ errors=1
+ continue
+ fi
+
+ found=0
+ for ext in "" gz bz2 xz lrz lzo Z; do
+ if sourcefile="$(get_filepath "${file%.*}${ext:+.$ext}")"; then
+ found=1
+ break;
+ fi
+ done
+ if (( ! found )); then
+ printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
+ errors=1
+ continue
+ fi
+
+ case "$ext" in
+ gz) decompress="gzip -c -d -f" ;;
+ bz2) decompress="bzip2 -c -d -f" ;;
+ xz) decompress="xz -c -d" ;;
+ lrz) decompress="lrzip -q -d" ;;
+ lzo) decompress="lzop -c -d -q" ;;
+ Z) decompress="uncompress -c -f" ;;
+ "") decompress="cat" ;;
+ esac
+
+ $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile" --verify "$file" - 2> /dev/null
+ # these variables are assigned values in parse_gpg_statusfile
+ success=0
+ status=
+ pubkey=
+ fingerprint=
+ trusted=
+ parse_gpg_statusfile "$statusfile"
+ if (( ! $success )); then
+ printf '%s' "$(gettext "FAILED")" >&2
+ case "$status" in
+ "missingkey")
+ printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
+ ;;
+ "revokedkey")
+ printf " ($(gettext "public key %s has been revoked"))" "$pubkey" >&2
+ ;;
+ "bad")
+ printf ' (%s)' "$(gettext "bad signature from public key") $pubkey" >&2
+ ;;
+ "error")
+ printf ' (%s)' "$(gettext "error during signature verification")" >&2
+ ;;
+ esac
+ errors=1
+ else
+ if (( ${#validpgpkeys[@]} == 0 && !trusted )); then
+ printf "%s ($(gettext "the public key %s is not trusted"))" $(gettext "FAILED") "$fingerprint" >&2
+ errors=1
+ elif (( ${#validpgpkeys[@]} > 0 )) && ! in_array "$fingerprint" "${validpgpkeys[@]}"; then
+ printf "%s (%s %s)" "$(gettext "FAILED")" "$(gettext "invalid public key")" "$fingerprint"
+ errors=1
+ else
+ printf '%s' "$(gettext "Passed")" >&2
+ case "$status" in
+ "expired")
+ printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
+ warnings=1
+ ;;
+ "expiredkey")
+ printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
+ warnings=1
+ ;;
+ esac
+ fi
+ fi
+ printf '\n' >&2
+ done
+
+ rm -f "$statusfile"
+
+ if (( errors )); then
+ error "$(gettext "One or more PGP signatures could not be verified!")"
+ exit 1
+ fi
+
+ if (( warnings )); then
+ warning "$(gettext "Warnings have occurred while verifying the signatures.")"
+ plain "$(gettext "Please make sure you really trust them.")"
+ fi
+}
+
+check_source_integrity() {
+ if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
+ warning "$(gettext "Skipping all source file integrity checks.")"
+ elif (( SKIPCHECKSUMS )); then
+ warning "$(gettext "Skipping verification of source file checksums.")"
+ check_pgpsigs "$@"
+ elif (( SKIPPGPCHECK )); then
+ warning "$(gettext "Skipping verification of source file PGP signatures.")"
+ check_checksums "$@"
+ else
+ check_checksums "$@"
+ check_pgpsigs "$@"
+ fi
+}
+
+error_function() {
+ if [[ -p $logpipe ]]; then
+ rm "$logpipe"
+ fi
+ # first exit all subshells, then print the error
+ if (( ! BASH_SUBSHELL )); then
+ error "$(gettext "A failure occurred in %s().")" "$1"
+ plain "$(gettext "Aborting...")"
+ fi
+ exit 2 # $E_BUILD_FAILED
+}
+
+source_safe() {
+ shopt -u extglob
+ if ! source "$@"; then
+ error "$(gettext "Failed to source %s")" "$1"
+ exit 1
+ fi
+ shopt -s extglob
+}
+
+merge_arch_attrs() {
+ local attr supported_attrs=(
+ provides conflicts depends replaces optdepends
+ makedepends checkdepends)
+
+ for attr in "${supported_attrs[@]}"; do
+ eval "$attr+=(\"\${${attr}_$CARCH[@]}\")"
+ done
+
+ # ensure that calling this function is idempotent.
+ unset -v "${supported_attrs[@]/%/_$CARCH}"
+}
+
+source_buildfile() {
+ source_safe "$@"
+}
+
+run_function_safe() {
+ local restoretrap
+
+ set -e
+ set -E
+
+ restoretrap=$(trap -p ERR)
+ trap 'error_function $pkgfunc' ERR
+
+ run_function "$1"
+
+ eval $restoretrap
+
+ set +E
+ set +e
+}
+
+run_function() {
+ if [[ -z $1 ]]; then
+ return 1
+ fi
+ local pkgfunc="$1"
+
+ # clear user-specified buildflags if requested
+ if check_option "buildflags" "n"; then
+ unset CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
+ fi
+
+ if check_option "debug" "y"; then
+ CFLAGS+=" $DEBUG_CFLAGS"
+ CXXFLAGS+=" $DEBUG_CXXFLAGS"
+ fi
+
+ # clear user-specified makeflags if requested
+ if check_option "makeflags" "n"; then
+ unset MAKEFLAGS
+ fi
+
+ msg "$(gettext "Starting %s()...")" "$pkgfunc"
+ cd_safe "$srcdir"
+
+ # ensure all necessary build variables are exported
+ export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
+ # save our shell options so pkgfunc() can't override what we need
+ local shellopts=$(shopt -p)
+
+ local ret=0
+ if (( LOGGING )); then
+ local fullver=$(get_full_version)
+ local BUILDLOG="$LOGDEST/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
+ if [[ -f $BUILDLOG ]]; then
+ local i=1
+ while true; do
+ if [[ -f $BUILDLOG.$i ]]; then
+ i=$(($i +1))
+ else
+ break
+ fi
+ done
+ mv "$BUILDLOG" "$BUILDLOG.$i"
+ fi
+
+ # ensure overridden package variables survive tee with split packages
+ logpipe=$(mktemp -u "$LOGDEST/logpipe.XXXXXXXX")
+ mkfifo "$logpipe"
+ tee "$BUILDLOG" < "$logpipe" &
+ local teepid=$!
+
+ $pkgfunc &>"$logpipe"
+
+ wait $teepid
+ rm "$logpipe"
+ else
+ "$pkgfunc"
+ fi
+ # reset our shell options
+ eval "$shellopts"
+}
+
+run_prepare() {
+ run_function_safe "prepare"
+}
+
+run_build() {
+ local ccache=0
+
+ # use ccache if it is requested (check buildenv and PKGBUILD opts)
+ if check_buildoption "ccache" "y" && [[ -d /usr/lib/ccache/bin ]]; then
+ export PATH="/usr/lib/ccache/bin:$PATH"
+ ccache=1
+ fi
+
+ # use distcc if it is requested (check buildenv and PKGBUILD opts)
+ if check_buildoption "distcc" "y"; then
+ if (( ccache )); then
+ export CCACHE_PREFIX="${CCACHE_PREFIX:+$CCACHE_PREFIX }distcc"
+ export CCACHE_BASEDIR="$srcdir"
+ elif [[ -d /usr/lib/distcc/bin ]]; then
+ export PATH="/usr/lib/distcc/bin:$PATH"
+ fi
+ export DISTCC_HOSTS
+ fi
+
+ run_function_safe "build"
+}
+
+run_check() {
+ run_function_safe "check"
+}
+
+run_package() {
+ local pkgfunc
+ if [[ -z $1 ]]; then
+ pkgfunc="package"
+ else
+ pkgfunc="package_$1"
+ fi
+
+ run_function_safe "$pkgfunc"
+}
+
+find_libdepends() {
+ local d sodepends;
+
+ sodepends=0;
+ for d in "${depends[@]}"; do
+ if [[ $d = *.so ]]; then
+ sodepends=1;
+ break;
+ fi
+ done
+
+ if (( sodepends == 0 )); then
+ printf '%s\n' "${depends[@]}"
+ return;
+ fi
+
+ local libdeps filename soarch sofile soname soversion;
+ declare -A libdeps;
+
+ while read -r 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?(+(.+([0-9])))}".so
+ # extract the major version: 1
+ soversion="${sofile##*\.so\.}"
+
+ if [[ ${libdeps[$soname]} ]]; then
+ if [[ ${libdeps[$soname]} != *${soversion}-${soarch}* ]]; then
+ libdeps[$soname]+=" ${soversion}-${soarch}"
+ fi
+ else
+ libdeps[$soname]="${soversion}-${soarch}"
+ fi
+ done
+ done < <(find "$pkgdir" -type f -perm -u+x)
+
+ local libdepends v
+ for d in "${depends[@]}"; do
+ case "$d" in
+ *.so)
+ if [[ ${libdeps[$d]} ]]; then
+ for v in ${libdeps[$d]}; do
+ libdepends+=("$d=$v")
+ done
+ else
+ warning "$(gettext "Library listed in %s is not required by any files: %s")" "'depends'" "$d"
+ libdepends+=("$d")
+ fi
+ ;;
+ *)
+ libdepends+=("$d")
+ ;;
+ esac
+ done
+
+ printf '%s\n' "${libdepends[@]}"
+}
+
+
+find_libprovides() {
+ local p libprovides missing
+ for p in "${provides[@]}"; do
+ missing=0
+ case "$p" in
+ *.so)
+ mapfile -t filename < <(find "$pkgdir" -type f -name $p\*)
+ if [[ $filename ]]; then
+ # packages may provide multiple versions of the same library
+ for fn in "${filename[@]}"; do
+ # check if we really have a shared object
+ if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
+ # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
+ local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
+ if [[ -z "$sofile" ]]; then
+ warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
+ libprovides+=("$p")
+ continue
+ fi
+
+ # get the library architecture (32 or 64 bit)
+ local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
+
+ # extract the library major version
+ local soversion="${sofile##*\.so\.}"
+
+ libprovides+=("${p}=${soversion}-${soarch}")
+ else
+ warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
+ libprovides+=("$p")
+ fi
+ done
+ else
+ libprovides+=("$p")
+ missing=1
+ fi
+ ;;
+ *)
+ libprovides+=("$p")
+ ;;
+ esac
+
+ if (( missing )); then
+ warning "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$p"
+ fi
+ done
+
+ printf '%s\n' "${libprovides[@]}"
+}
+
+srcinfo_open_section() {
+ printf '%s = %s\n' "$1" "$2"
+}
+
+srcinfo_close_section() {
+ echo
+}
+
+srcinfo_write_attr() {
+ # $1: attr name
+ # $2: attr values
+
+ local attrname=$1 attrvalues=("${@:2}")
+
+ # normalize whitespace, strip leading and trailing
+ attrvalues=("${attrvalues[@]//+([[:space:]])/ }")
+ attrvalues=("${attrvalues[@]#[[:space:]]}")
+ attrvalues=("${attrvalues[@]%[[:space:]]}")
+
+ printf "\t$attrname = %s\n" "${attrvalues[@]}"
+}
+
+pkgbuild_extract_to_srcinfo() {
+ # $1: pkgname
+ # $2: attr name
+ # $3: multivalued
+
+ local pkgname=$1 attrname=$2 isarray=$3 outvalue=
+
+ if get_pkgbuild_attribute "$pkgname" "$attrname" "$isarray" 'outvalue'; then
+ srcinfo_write_attr "$attrname" "${outvalue[@]}"
+ fi
+}
+
+srcinfo_write_section_details() {
+ local attr package_arch a
+ local multivalued_arch_attrs=(source provides conflicts depends replaces
+ optdepends makedepends checkdepends
+ {md5,sha{1,224,256,384,512}}sums)
+
+ for attr in "${singlevalued[@]}"; do
+ pkgbuild_extract_to_srcinfo "$1" "$attr" 0
+ done
+
+ for attr in "${multivalued[@]}"; do
+ pkgbuild_extract_to_srcinfo "$1" "$attr" 1
+ done
+
+ get_pkgbuild_attribute "$1" 'arch' 1 'package_arch'
+ for a in "${package_arch[@]}"; do
+ # 'any' is special. there's no support for, e.g. depends_any.
+ [[ $a = any ]] && continue
+
+ for attr in "${multivalued_arch_attrs[@]}"; do
+ pkgbuild_extract_to_srcinfo "$1" "${attr}_$a" 1
+ done
+ done
+}
+
+srcinfo_write_global() {
+ local singlevalued=(pkgdesc pkgver pkgrel epoch url install changelog)
+ local multivalued=(arch groups license checkdepends makedepends
+ depends optdepends provides conflicts replaces
+ noextract options backup
+ source validpgpkeys {md5,sha{1,224,256,384,512}}sums)
+
+ srcinfo_open_section 'pkgbase' "${pkgbase:-$pkgname}"
+ srcinfo_write_section_details ''
+ srcinfo_close_section
+}
+
+srcinfo_write_package() {
+ local singlevalued=(pkgdesc url install changelog)
+ local multivalued=(arch groups license checkdepends depends optdepends
+ provides conflicts replaces options backup)
+
+ srcinfo_open_section 'pkgname' "$1"
+ srcinfo_write_section_details "$1"
+ srcinfo_close_section
+}
+
+write_srcinfo_header() {
+ printf "# Generated by makepkg %s\n" "$makepkg_version"
+ printf "# %s\n" "$(LC_ALL=C date -u)"
+}
+
+write_srcinfo_content() {
+ local pkg
+
+ srcinfo_write_global
+
+ for pkg in "${pkgname[@]}"; do
+ srcinfo_write_package "$pkg"
+ done
+}
+
+write_srcinfo() {
+ write_srcinfo_header
+ write_srcinfo_content
+}
+
+write_pkginfo() {
+ local builddate=$(date -u "+%s")
+ if [[ -n $PACKAGER ]]; then
+ local packager="$PACKAGER"
+ else
+ local packager="Unknown Packager"
+ fi
+
+ local size="$(/usr/bin/du -sk --apparent-size)"
+ size="$(( ${size%%[^0-9]*} * 1024 ))"
+
+ merge_arch_attrs
+
+ msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
+ printf "# Generated by makepkg %s\n" "$makepkg_version"
+ printf "# using %s\n" "$(fakeroot -v)"
+ printf "# %s\n" "$(LC_ALL=C date -u)"
+
+ printf "pkgname = %s\n" "$pkgname"
+ if (( SPLITPKG )) || [[ "$pkgbase" != "$pkgname" ]]; then
+ printf "pkgbase = %s\n" "$pkgbase"
+ fi
+
+ local fullver=$(get_full_version)
+ printf "pkgver = %s\n" "$fullver"
+ if [[ "$fullver" != "$basever" ]]; then
+ printf "basever = %s\n" "$basever"
+ fi
+
+ # TODO: all fields should have this treatment
+ local spd="${pkgdesc//+([[:space:]])/ }"
+ spd=("${spd[@]#[[:space:]]}")
+ spd=("${spd[@]%[[:space:]]}")
+
+ printf "pkgdesc = %s\n" "$spd"
+ printf "url = %s\n" "$url"
+ printf "builddate = %s\n" "$builddate"
+ printf "packager = %s\n" "$packager"
+ printf "size = %s\n" "$size"
+ printf "arch = %s\n" "$pkgarch"
+
+ mapfile -t provides < <(find_libprovides)
+ mapfile -t depends < <(find_libdepends)
+
+ [[ $license ]] && printf "license = %s\n" "${license[@]}"
+ [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
+ [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
+ [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
+ [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
+ [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
+ [[ $depends ]] && printf "depend = %s\n" "${depends[@]}"
+ [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
+ [[ $makedepends ]] && printf "makedepend = %s\n" "${makedepends[@]}"
+ [[ $checkdepends ]] && printf "checkdepend = %s\n" "${checkdepends[@]}"
+}
+
+write_buildinfo() {
+ msg2 "$(gettext "Generating %s file...")" ".BUILDINFO"
+
+ printf "builddir = %s\n" "${BUILDDIR}"
+
+ local sum="$(openssl dgst -sha256 "${BUILDFILE}")"
+ sum=${sum##* }
+
+ printf "pkgbuild_sha256sum = %s\n" $sum
+
+ printf "buildenv = %s\n" "${BUILDENV[@]}"
+ printf "options = %s\n" "${OPTIONS[@]}"
+
+ local pkglist=($(run_pacman -Q | sed "s# #-#"))
+ printf "installed = %s\n" "${pkglist[@]}"
+}
+
+create_package() {
+ (( NOARCHIVE )) && return
+
+ if [[ ! -d $pkgdir ]]; then
+ error "$(gettext "Missing %s directory.")" "\$pkgdir/"
+ plain "$(gettext "Aborting...")"
+ exit 1 # $E_MISSING_PKGDIR
+ fi
+
+ cd_safe "$pkgdir"
+ msg "$(gettext "Creating package \"%s\"...")" "$pkgname"
+
+ pkgarch=$(get_pkg_arch)
+ write_pkginfo > .PKGINFO
+ write_buildinfo > .BUILDINFO
+
+ local comp_files=('.PKGINFO' '.BUILDINFO')
+
+ # check for changelog/install files
+ for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
+ IFS='/' read -r orig dest < <(printf '%s\n' "$i")
+
+ if [[ -n ${!orig} ]]; then
+ msg2 "$(gettext "Adding %s file...")" "$orig"
+ if ! cp "$startdir/${!orig}" "$dest"; then
+ error "$(gettext "Failed to add %s file to package.")" "$orig"
+ exit 1
+ fi
+ chmod 644 "$dest"
+ comp_files+=("$dest")
+ fi
+ done
+
+ # tar it up
+ local fullver=$(get_full_version)
+ local pkg_file="$PKGDEST/${pkgname}-${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
+
+ msg2 "$(gettext "Generating .MTREE file...")"
+ LANG=C bsdtar -czf .MTREE --format=mtree \
+ --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' \
+ "${comp_files[@]}" *
+ comp_files+=(".MTREE")
+
+ msg2 "$(gettext "Compressing package...")"
+ # TODO: Maybe this can be set globally for robustness
+ shopt -s -o pipefail
+ # bsdtar's gzip compression always saves the time stamp, making one
+ # archive created using the same command line distinct from another.
+ # Disable bsdtar compression and use gzip -n for now.
+ LANG=C bsdtar -cf - "${comp_files[@]}" * |
+ case "$PKGEXT" in
+ *tar.gz) ${COMPRESSGZ[@]:-gzip -c -f -n} ;;
+ *tar.bz2) ${COMPRESSBZ2[@]:-bzip2 -c -f} ;;
+ *tar.xz) ${COMPRESSXZ[@]:-xz -c -z -} ;;
+ *tar.lrz) ${COMPRESSLRZ[@]:-lrzip -q} ;;
+ *tar.lzo) ${COMPRESSLZO[@]:-lzop -q} ;;
+ *tar.Z) ${COMPRESSZ[@]:-compress -c -f} ;;
+ *tar) cat ;;
+ *) warning "$(gettext "'%s' is not a valid archive extension.")" \
+ "$PKGEXT"; cat ;;
+ esac > "${pkg_file}" || ret=$?
+
+ shopt -u nullglob
+ shopt -u -o pipefail
+
+ if (( ret )); then
+ error "$(gettext "Failed to create package file.")"
+ exit 1 # TODO: error code
+ fi
+
+ create_signature "$pkg_file"
+
+ if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
+ rm -f "${pkg_file/$PKGDEST/$startdir}"
+ ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
+ ret=$?
+ if [[ -f $pkg_file.sig ]]; then
+ rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
+ ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
+ fi
+ fi
+
+ if (( ret )); then
+ warning "$(gettext "Failed to create symlink to package file.")"
+ fi
+}
+
+create_debug_package() {
+ # check if a debug package was requested
+ if ! check_option "debug" "y" || ! check_option "strip" "y"; then
+ return
+ fi
+
+ pkgdir="${pkgdir}-debug"
+
+ # check if we have any debug symbols to package
+ if dir_is_empty "$pkgdir/usr/lib/debug"; then
+ return
+ fi
+
+ depends=("$pkgname=$(get_full_version)")
+ pkgdesc="Detached debugging symbols for $pkgname"
+ pkgname=$pkgname-debug
+
+ unset groups optdepends provides conflicts replaces backup install changelog
+
+ create_package
+}
+
+create_signature() {
+ if [[ $SIGNPKG != 'y' ]]; then
+ return
+ fi
+ local ret=0
+ local filename="$1"
+ msg "$(gettext "Signing package...")"
+
+ local SIGNWITHKEY=""
+ if [[ -n $GPGKEY ]]; then
+ SIGNWITHKEY="-u ${GPGKEY}"
+ fi
+
+ gpg --detach-sign --use-agent ${SIGNWITHKEY} --no-armor "$filename" &>/dev/null || ret=$?
+
+
+ if (( ! ret )); then
+ msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
+ else
+ warning "$(gettext "Failed to sign package file.")"
+ fi
+}
+
+create_srcpackage() {
+ local ret=0
+ msg "$(gettext "Creating source package...")"
+ local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
+ mkdir "${srclinks}"/${pkgbase}
+
+ msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
+ ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
+
+ msg2 "$(gettext "Generating %s file...")" .SRCINFO
+ write_srcinfo > "$srclinks/$pkgbase"/.SRCINFO
+
+ local file all_sources
+
+ get_all_sources 'all_sources'
+ for file in "${all_sources[@]}"; do
+ if [[ "$file" = "$(get_filename "$file")" ]] || (( SOURCEONLY == 2 )); then
+ local absfile
+ absfile=$(get_filepath "$file") || missing_source_file "$file"
+ msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
+ ln -s "$absfile" "$srclinks/$pkgbase"
+ fi
+ done
+
+ local i
+ for i in 'changelog' 'install'; do
+ local file files
+
+ [[ ${!i} ]] && files+=("${!i}")
+ for name in "${pkgname[@]}"; do
+ if extract_function_variable "package_$name" "$i" 0 file; then
+ files+=("$file")
+ fi
+ done
+
+ for file in "${files[@]}"; do
+ if [[ $file && ! -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" ;;
+ *tar.lrz) TAR_OPT="--lrzip" ;;
+ *tar.lzo) TAR_OPT="--lzop" ;;
+ *tar.Z) TAR_OPT="-Z" ;;
+ *tar) TAR_OPT="" ;;
+ *) warning "$(gettext "'%s' is not a valid archive extension.")" \
+ "$SRCEXT" ;;
+ esac
+
+ local fullver=$(get_full_version)
+ local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
+
+ # tar it up
+ msg2 "$(gettext "Compressing source package...")"
+ cd_safe "${srclinks}"
+ if ! LANG=C bsdtar -cL ${TAR_OPT} -f "$pkg_file" ${pkgbase}; then
+ error "$(gettext "Failed to create source package file.")"
+ exit 1 # TODO: error code
+ fi
+
+ create_signature "$pkg_file"
+
+ if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
+ rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
+ ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
+ ret=$?
+ if [[ -f $pkg_file.sig ]]; then
+ rm -f "${pkg_file/$SRCPKGDEST/$startdir}.sig"
+ ln -s "$pkg_file.sig" "${pkg_file/$SRCPKGDEST/$startdir}.sig"
+ fi
+ fi
+
+ if (( ret )); then
+ warning "$(gettext "Failed to create symlink to source package file.")"
+ fi
+
+ cd_safe "${startdir}"
+ rm -rf "${srclinks}"
+}
+
+# this function always returns 0 to make sure clean-up will still occur
+install_package() {
+ (( ! INSTALL )) && return
+
+ if (( ! SPLITPKG )); then
+ msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
+ else
+ msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
+ fi
+
+ local fullver pkgarch pkg pkglist
+ (( ASDEPS )) && pkglist+=('--asdeps')
+ (( NEEDED )) && pkglist+=('--needed')
+
+ for pkg in ${pkgname[@]}; do
+ fullver=$(get_full_version)
+ pkgarch=$(get_pkg_arch $pkg)
+ pkglist+=("$PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT}")
+
+ if [[ -f "$PKGDEST/${pkg}-debug-${fullver}-${pkgarch}${PKGEXT}" ]]; then
+ pkglist+=("$PKGDEST/${pkg}-debug-${fullver}-${pkgarch}${PKGEXT}")
+ fi
+ done
+
+ if ! run_pacman -U "${pkglist[@]}"; then
+ warning "$(gettext "Failed to install built package(s).")"
+ return 0
+ fi
+}
+
+get_vcsclient() {
+ local proto=${1%%+*}
+
+ local i
+ for i in "${VCSCLIENTS[@]}"; do
+ local handler="${i%%::*}"
+ if [[ $proto = "$handler" ]]; then
+ local client="${i##*::}"
+ break
+ fi
+ done
+
+ # if we didn't find an client, return an error
+ if [[ -z $client ]]; then
+ error "$(gettext "Unknown download protocol: %s")" "$proto"
+ plain "$(gettext "Aborting...")"
+ exit 1 # $E_CONFIG_ERROR
+ fi
+
+ printf "%s\n" "$client"
+}
+
+check_vcs_software() {
+ local all_sources all_deps deps ret=0
+
+ if (( SOURCEONLY == 1 )); then
+ # we will not download VCS sources
+ return $ret
+ fi
+
+ if [[ -z $PACMAN_PATH ]]; then
+ warning "$(gettext "Cannot find the %s binary needed to check VCS source requirements.")" "$PACMAN"
+ return $ret
+ fi
+
+ # we currently only use global depends/makedepends arrays for --syncdeps
+ for attr in depends makedepends; do
+ get_pkgbuild_attribute "$pkg" "$attr" 1 'deps'
+ all_deps+=("${deps[@]}")
+
+ get_pkgbuild_attribute "$pkg" "${attr}_$CARCH" 1 'deps'
+ all_deps+=("${deps[@]}")
+ done
+
+ get_all_sources_for_arch 'all_sources'
+ for netfile in ${all_sources[@]}; do
+ local proto=$(get_protocol "$netfile")
+
+ case $proto in
+ bzr*|git*|hg*|svn*)
+ if ! type -p ${proto%%+*} > /dev/null; then
+ local client
+ client=$(get_vcsclient "$proto") || exit $?
+ # ensure specified program is installed
+ local uninstalled
+ uninstalled="$(set +E; check_deps $client)" || exit 1
+ # if not installed, check presence in depends or makedepends
+ if [[ -n "$uninstalled" ]] && (( ! NODEPS || ( VERIFYSOURCE && !DEP_BIN ) )); then
+ if ! in_array "$client" ${all_deps[@]}; then
+ error "$(gettext "Cannot find the %s package needed to handle %s sources.")" \
+ "$client" "${proto%%+*}"
+ ret=1
+ fi
+ fi
+ fi
+ ;;
+ *)
+ # non VCS source
+ ;;
+ esac
+ done
+
+ return $ret
+}
+
+check_software() {
+ # check for needed software
+ local ret=0
+
+ # check for PACMAN if we need it
+ if (( ! NODEPS || DEP_BIN || RMDEPS || INSTALL )); then
+ if [[ -z $PACMAN_PATH ]]; then
+ error "$(gettext "Cannot find the %s binary required for dependency operations.")" "$PACMAN"
+ ret=1
+ fi
+ fi
+
+ # check for sudo if we will need it during makepkg execution
+ if (( DEP_BIN || RMDEPS || INSTALL )); then
+ if ! type -p sudo >/dev/null; then
+ warning "$(gettext "Cannot find the %s binary. Will use %s to acquire root privileges.")" "sudo" "su"
+ fi
+ fi
+
+ # fakeroot - correct package file permissions
+ if check_buildenv "fakeroot" "y" && (( EUID > 0 )); then
+ if ! type -p fakeroot >/dev/null; then
+ error "$(gettext "Cannot find the %s binary.")" "fakeroot"
+ ret=1
+ fi
+ fi
+
+ # gpg - package signing
+ if [[ $SIGNPKG == 'y' ]] || { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; }; then
+ if ! type -p gpg >/dev/null; then
+ error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
+ ret=1
+ fi
+ fi
+
+ # gpg - source verification
+ if (( ! SKIPPGPCHECK )) && source_has_signatures; then
+ if ! type -p gpg >/dev/null; then
+ error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
+ ret=1
+ fi
+ fi
+
+ # openssl - checksum operations
+ if (( ! SKIPCHECKSUMS )); then
+ if ! type -p openssl >/dev/null; then
+ error "$(gettext "Cannot find the %s binary required for validating source file checksums.")" "openssl"
+ ret=1
+ fi
+ fi
+
+ # distcc - compilation with distcc
+ if check_buildoption "distcc" "y"; 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_buildoption "ccache" "y"; 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
+
+ # tools to download vcs sources
+ if ! check_vcs_software; then
+ ret=1
+ fi
+
+ return $ret
+}
+
+check_build_status() {
+ if (( ! SPLITPKG )); then
+ fullver=$(get_full_version)
+ pkgarch=$(get_pkg_arch)
+ if [[ -f $PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT} ]] \
+ && ! (( FORCE || SOURCEONLY || NOBUILD || NOARCHIVE)); then
+ if (( INSTALL )); then
+ warning "$(gettext "A package has already been built, installing existing package...")"
+ install_package
+ exit 0
+ else
+ error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
+ exit 1
+ fi
+ fi
+ else
+ allpkgbuilt=1
+ somepkgbuilt=0
+ for pkg in ${pkgname[@]}; do
+ fullver=$(get_full_version)
+ pkgarch=$(get_pkg_arch $pkg)
+ if [[ -f $PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT} ]]; then
+ somepkgbuilt=1
+ else
+ allpkgbuilt=0
+ fi
+ done
+ if ! (( FORCE || SOURCEONLY || NOBUILD || NOARCHIVE)); then
+ if (( allpkgbuilt )); then
+ if (( INSTALL )); then
+ warning "$(gettext "The package group has already been built, installing existing packages...")"
+ install_package
+ exit 0
+ else
+ error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
+ exit 1
+ fi
+ fi
+ if (( somepkgbuilt && ! PKGVERFUNC )); then
+ error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
+ exit 1
+ fi
+ fi
+ unset allpkgbuilt somepkgbuilt
+ fi
+}
+
+backup_package_variables() {
+ local var
+ for var in ${splitpkg_overrides[@]}; do
+ local indirect="${var}_backup"
+ eval "${indirect}=(\"\${$var[@]}\")"
+ done
+}
+
+restore_package_variables() {
+ local var
+ for var in ${splitpkg_overrides[@]}; do
+ local indirect="${var}_backup"
+ if [[ -n ${!indirect} ]]; then
+ eval "${var}=(\"\${$indirect[@]}\")"
+ else
+ unset ${var}
+ fi
+ done
+}
+
+run_split_packaging() {
+ local pkgname_backup=("${pkgname[@]}")
+ for pkgname in ${pkgname_backup[@]}; do
+ pkgdir="$pkgdirbase/$pkgname"
+ mkdir "$pkgdir"
+ backup_package_variables
+ run_package $pkgname
+ tidy_install
+ lint_package
+ create_package
+ create_debug_package
+ restore_package_variables
+ done
+ pkgname=("${pkgname_backup[@]}")
+}
+
+# getopt-like parser
+parseopts() {
+ local opt= optarg= i= shortopts=$1
+ local -a longopts=() unused_argv=()
+
+ shift
+ while [[ $1 && $1 != '--' ]]; do
+ longopts+=("$1")
+ shift
+ done
+ shift
+
+ longoptmatch() {
+ local o longmatch=()
+ for o in "${longopts[@]}"; do
+ if [[ ${o%:} = "$1" ]]; then
+ longmatch=("$o")
+ break
+ fi
+ [[ ${o%:} = "$1"* ]] && longmatch+=("$o")
+ done
+
+ case ${#longmatch[*]} in
+ 1)
+ # success, override with opt and return arg req (0 == none, 1 == required)
+ opt=${longmatch%:}
+ if [[ $longmatch = *: ]]; then
+ return 1
+ else
+ return 0
+ fi ;;
+ 0)
+ # fail, no match found
+ return 255 ;;
+ *)
+ # fail, ambiguous match
+ printf "makepkg: $(gettext "option '%s' is ambiguous; possibilities:")" "--$1"
+ printf " '%s'" "${longmatch[@]%:}"
+ printf '\n'
+ return 254 ;;
+ esac >&2
+ }
+
+ while (( $# )); do
+ case $1 in
+ --) # explicit end of options
+ shift
+ break
+ ;;
+ -[!-]*) # short option
+ for (( i = 1; i < ${#1}; i++ )); do
+ opt=${1:i:1}
+
+ # option doesn't exist
+ if [[ $shortopts != *$opt* ]]; then
+ printf "makepkg: $(gettext "invalid option") -- '%s'\n" "$opt" >&2
+ OPTRET=(--)
+ return 1
+ fi
+
+ OPTRET+=("-$opt")
+ # option requires optarg
+ if [[ $shortopts = *$opt:* ]]; then
+ # if we're not at the end of the option chunk, the rest is the optarg
+ if (( i < ${#1} - 1 )); then
+ OPTRET+=("${1:i+1}")
+ break
+ # if we're at the end, grab the the next positional, if it exists
+ elif (( i == ${#1} - 1 )) && [[ $2 ]]; then
+ OPTRET+=("$2")
+ shift
+ break
+ # parse failure
+ else
+ printf "makepkg: $(gettext "option requires an argument") -- '%s'\n" "$opt" >&2
+ OPTRET=(--)
+ return 1
+ fi
+ fi
+ done
+ ;;
+ --?*=*|--?*) # long option
+ IFS='=' read -r opt optarg <<< "${1#--}"
+ longoptmatch "$opt"
+ case $? in
+ 0)
+ # parse failure
+ if [[ $optarg ]]; then
+ printf "makepkg: $(gettext "option '%s' does not allow an argument")\n" "--$opt" >&2
+ OPTRET=(--)
+ return 1
+ # --longopt
+ else
+ OPTRET+=("--$opt")
+ fi
+ ;;
+ 1)
+ # --longopt=optarg
+ if [[ $optarg ]]; then
+ OPTRET+=("--$opt" "$optarg")
+ # --longopt optarg
+ elif [[ $2 ]]; then
+ OPTRET+=("--$opt" "$2" )
+ shift
+ # parse failure
+ else
+ printf "makepkg: $(gettext "option '%s' requires an argument")\n" "--$opt" >&2
+ OPTRET=(--)
+ return 1
+ fi
+ ;;
+ 254)
+ # ambiguous option -- error was reported for us by longoptmatch()
+ OPTRET=(--)
+ return 1
+ ;;
+ 255)
+ # parse failure
+ printf "makepkg: $(gettext "invalid option") '--%s'\n" "$opt" >&2
+ OPTRET=(--)
+ return 1
+ ;;
+ esac
+ ;;
+ *) # non-option arg encountered, add it as a parameter
+ unused_argv+=("$1")
+ ;;
+ esac
+ shift
+ done
+
+ # add end-of-opt terminator and any leftover positional parameters
+ OPTRET+=('--' "${unused_argv[@]}" "$@")
+ unset longoptmatch
+
+ return 0
+}
+
+
+usage() {
+ printf "makepkg (pacman) %s\n" "$makepkg_version"
+ echo
+ printf -- "$(gettext "Make packages compatible for use with pacman")\n"
+ echo
+ printf -- "$(gettext "Usage: %s [options]")\n" "$0"
+ echo
+ printf -- "$(gettext "Options:")\n"
+ printf -- "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
+ printf -- "$(gettext " -c, --clean Clean up work files after build")\n"
+ printf -- "$(gettext " -C, --cleanbuild Remove %s dir before building the package")\n" "\$srcdir/"
+ printf -- "$(gettext " -d, --nodeps Skip all dependency checks")\n"
+ printf -- "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "\$srcdir/"
+ printf -- "$(gettext " -f, --force Overwrite existing package")\n"
+ printf -- "$(gettext " -g, --geninteg Generate integrity checks for source files")\n"
+ printf -- "$(gettext " -h, --help Show this help message and exit")\n"
+ printf -- "$(gettext " -i, --install Install package after successful build")\n"
+ printf -- "$(gettext " -L, --log Log package build process")\n"
+ printf -- "$(gettext " -m, --nocolor Disable colorized output messages")\n"
+ printf -- "$(gettext " -o, --nobuild Download and extract files only")\n"
+ printf -- "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
+ printf -- "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")\n"
+ printf -- "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")\n"
+ printf -- "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
+ printf -- "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")\n"
+ printf -- "$(gettext " -V, --version Show version information and exit")\n"
+ printf -- "$(gettext " --allsource Generate a source-only tarball including downloaded sources")\n"
+ 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 Do not update VCS sources")\n"
+ printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
+ printf -- "$(gettext " --noarchive Do not create package archive")\n"
+ printf -- "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
+ printf -- "$(gettext " --noprepare Do not run the %s function in the %s")\n" "prepare()" "$BUILDSCRIPT"
+ printf -- "$(gettext " --nosign Do not create a signature for the package")\n"
+ printf -- "$(gettext " --packagelist Only list packages that would be produced, without PKGEXT")\n"
+ printf -- "$(gettext " --printsrcinfo Print the generated SRCINFO and exit")\n"
+ printf -- "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
+ printf -- "$(gettext " --skipchecksums Do not verify checksums of the source files")\n"
+ printf -- "$(gettext " --skipinteg Do not perform any verification checks on source files")\n"
+ printf -- "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")\n"
+ printf -- "$(gettext " --verifysource Download source files (if needed) and perform integrity checks")\n"
+ echo
+ printf -- "$(gettext "These options can be passed to %s:")\n" "pacman"
+ echo
+ printf -- "$(gettext " --asdeps Install packages as non-explicitly installed")\n"
+ printf -- "$(gettext " --needed Do not reinstall the targets that are already up to date")\n"
+ printf -- "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")\n"
+ printf -- "$(gettext " --noprogressbar Do not show a progress bar when downloading files")\n"
+ echo
+ printf -- "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
+ echo
+}
+
+version() {
+ printf "makepkg (pacman) %s\n" "$makepkg_version"
+ printf -- "$(gettext "\
+Copyright (c) 2006-2016 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
+
+# ensure we have a sane umask set
+umask 0022
+
+# determine whether we have gettext; make it a no-op if we do not
+if ! type -p gettext >/dev/null; then
+ gettext() {
+ printf "%s\n" "$@"
+ }
+fi
+
+ARGLIST=("$@")
+
+# Parse Command Line Options.
+OPT_SHORT="AcCdefFghiLmop:rRsSV"
+OPT_LONG=('allsource' 'check' 'clean' 'cleanbuild' 'config:' 'force' 'geninteg'
+ 'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'noarchive' 'nobuild'
+ 'nocolor' 'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'packagelist'
+ 'printsrcinfo' 'repackage' 'rmdeps' 'sign' 'skipchecksums' 'skipinteg'
+ 'skippgpcheck' 'source' 'syncdeps' 'verifysource' 'version')
+
+# Pacman Options
+OPT_LONG+=('asdeps' 'noconfirm' 'needed' 'noprogressbar')
+
+if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
+ exit 1 # E_INVALID_OPTION;
+fi
+set -- "${OPTRET[@]}"
+unset OPT_SHORT OPT_LONG OPTRET
+
+while true; do
+ case "$1" in
+ # Pacman Options
+ --asdeps) ASDEPS=1;;
+ --needed) NEEDED=1;;
+ --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
+ --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
+
+ # Makepkg Options
+ --allsource) SOURCEONLY=2 ;;
+ -A|--ignorearch) IGNOREARCH=1 ;;
+ -c|--clean) CLEANUP=1 ;;
+ -C|--cleanbuild) CLEANBUILD=1 ;;
+ --check) RUN_CHECK='y' ;;
+ --config) shift; MAKEPKG_CONF=$1 ;;
+ -d|--nodeps) NODEPS=1 ;;
+ -e|--noextract) NOEXTRACT=1 ;;
+ -f|--force) FORCE=1 ;;
+ -F) INFAKEROOT=1 ;;
+ # generating integrity checks does not depend on architecture
+ -g|--geninteg) GENINTEG=1 IGNOREARCH=1;;
+ --holdver) HOLDVER=1 ;;
+ -i|--install) INSTALL=1 ;;
+ --key) shift; GPGKEY=$1 ;;
+ -L|--log) LOGGING=1 ;;
+ -m|--nocolor) USE_COLOR='n'; PACMAN_OPTS+=" --color never" ;;
+ --noarchive) NOARCHIVE=1 ;;
+ --nocheck) RUN_CHECK='n' ;;
+ --noprepare) RUN_PREPARE='n' ;;
+ --nosign) SIGNPKG='n' ;;
+ -o|--nobuild) NOBUILD=1 ;;
+ -p) shift; BUILDFILE=$1 ;;
+ --packagelist) PACKAGELIST=1 IGNOREARCH=1;;
+ --printsrcinfo) PRINTSRCINFO=1 ;;
+ -r|--rmdeps) RMDEPS=1 ;;
+ -R|--repackage) REPKG=1 ;;
+ --sign) SIGNPKG='y' ;;
+ --skipchecksums) SKIPCHECKSUMS=1 ;;
+ --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
+ --skippgpcheck) SKIPPGPCHECK=1;;
+ -s|--syncdeps) DEP_BIN=1 ;;
+ -S|--source) SOURCEONLY=1 ;;
+ --verifysource) VERIFYSOURCE=1 ;;
+
+ -h|--help) usage; exit 0 ;; # E_OK
+ -V|--version) version; exit 0 ;; # E_OK
+
+ --) OPT_IND=0; shift; break 2;;
+ esac
+ shift
+done
+
+# attempt to consume any extra argv as environment variables. this supports
+# overriding (e.g. CC=clang) as well as overriding (e.g. CFLAGS+=' -g').
+extra_environment=()
+while [[ $1 ]]; do
+ if [[ $1 = [_[:alpha:]]*([[:alnum:]_])?(+)=* ]]; then
+ extra_environment+=("$1")
+ fi
+ shift
+done
+
+# setup signal traps
+trap 'clean_up' 0
+for signal in TERM HUP QUIT; do
+ trap "trap_exit $signal \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal"
+done
+trap 'trap_exit INT "$(gettext "Aborted by user! Exiting...")"' INT
+trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' ERR
+
+# preserve environment variables and canonicalize path
+[[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
+[[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
+[[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
+[[ -n ${LOGDEST} ]] && _LOGDEST=$(canonicalize_path ${LOGDEST})
+[[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
+[[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
+[[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
+[[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
+[[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
+[[ -n ${CARCH} ]] && _CARCH=${CARCH}
+
+# 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_safe "$MAKEPKG_CONF"
+else
+ error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
+ plain "$(gettext "Aborting...")"
+ exit 1 # $E_CONFIG_ERROR
+fi
+
+# Source user-specific makepkg.conf overrides, but only if no override config
+# file was specified
+XDG_PACMAN_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/pacman"
+if [[ "$MAKEPKG_CONF" = "$confdir/makepkg.conf" ]]; then
+ if [[ -r "$XDG_PACMAN_DIR/makepkg.conf" ]]; then
+ source_safe "$XDG_PACMAN_DIR/makepkg.conf"
+ elif [[ -r "$HOME/.makepkg.conf" ]]; then
+ source_safe "$HOME/.makepkg.conf"
+ fi
+fi
+
+# set pacman command if not already defined
+PACMAN=${PACMAN:-pacman}
+# save full path to command as PATH may change when sourcing /etc/profile
+PACMAN_PATH=$(type -P $PACMAN)
+
+# check if messages are to be printed using color
+if [[ -t 2 && $USE_COLOR != "n" ]] && check_buildenv "color" "y"; then
+ colorize
+else
+ unset ALL_OFF BOLD BLUE GREEN RED YELLOW
+fi
+
+
+# override settings with an environment variable for batch processing
+BUILDDIR=${_BUILDDIR:-$BUILDDIR}
+BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
+if [[ ! -d $BUILDDIR ]]; then
+ if ! mkdir -p "$BUILDDIR"; then
+ error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
+ plain "$(gettext "Aborting...")"
+ exit 1
+ fi
+ chmod a-s "$BUILDDIR"
+fi
+if [[ ! -w $BUILDDIR ]]; then
+ error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
+ plain "$(gettext "Aborting...")"
+ exit 1
+fi
+
+# override settings from extra variables on commandline, if any
+if (( ${#extra_environment[*]} )); then
+ export "${extra_environment[@]}"
+fi
+
+PKGDEST=${_PKGDEST:-$PKGDEST}
+PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
+if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
+ error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
+ plain "$(gettext "Aborting...")"
+ exit 1
+fi
+
+SRCDEST=${_SRCDEST:-$SRCDEST}
+SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
+if [[ ! -w $SRCDEST ]] ; then
+ error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
+ plain "$(gettext "Aborting...")"
+ exit 1
+fi
+
+SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
+SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
+if (( SOURCEONLY )); then
+ if [[ ! -w $SRCPKGDEST ]]; then
+ error "$(gettext "You do not have write permission to store source tarballs in %s.")" "$SRCPKGDEST"
+ plain "$(gettext "Aborting...")"
+ exit 1
+ fi
+
+ # If we're only making a source tarball, then we need to ignore architecture-
+ # dependent behavior.
+ IGNOREARCH=1
+fi
+
+LOGDEST=${_LOGDEST:-$LOGDEST}
+LOGDEST=${LOGDEST:-$startdir} #default to $startdir if undefined
+if (( LOGGING )) && [[ ! -w $LOGDEST ]]; then
+ error "$(gettext "You do not have write permission to store logs in %s.")" "$LOGDEST"
+ plain "$(gettext "Aborting...")"
+ exit 1
+fi
+
+PKGEXT=${_PKGEXT:-$PKGEXT}
+SRCEXT=${_SRCEXT:-$SRCEXT}
+GPGKEY=${_GPGKEY:-$GPGKEY}
+PACKAGER=${_PACKAGER:-$PACKAGER}
+CARCH=${_CARCH:-$CARCH}
+
+if (( ! INFAKEROOT )); then
+ if (( EUID == 0 )); then
+ error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\
+catastrophic damage to your system.")" "makepkg"
+ exit 1 # $E_USER_ABORT
+ fi
+else
+ if [[ -z $FAKEROOTKEY ]]; then
+ error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
+ exit 1 # TODO: error code
+ fi
+fi
+
+unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
+unset md5sums replaces depends conflicts backup source install changelog build
+unset makedepends optdepends options noextract validpgpkeys
+
+BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
+if [[ ! -f $BUILDFILE ]]; then
+ error "$(gettext "%s does not exist.")" "$BUILDFILE"
+ exit 1
+else
+ if [[ $(<"$BUILDFILE") = *$'\r'* ]]; then
+ error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
+ exit 1
+ fi
+
+ if [[ ! $BUILDFILE -ef $PWD/${BUILDFILE##*/} ]]; then
+ error "$(gettext "%s must be in the current working directory.")" "$BUILDFILE"
+ exit 1
+ fi
+
+ if [[ ${BUILDFILE:0:1} != "/" ]]; then
+ BUILDFILE="$startdir/$BUILDFILE"
+ fi
+ source_buildfile "$BUILDFILE"
+fi
+
+pkgbase=${pkgbase:-${pkgname[0]}}
+
+# check the PKGBUILD for some basic requirements
+lint_pkgbuild || exit 1
+
+if (( !SOURCEONLY )); then
+ merge_arch_attrs
+fi
+
+basever=$(get_full_version)
+
+if [[ $BUILDDIR = "$startdir" ]]; then
+ srcdir="$BUILDDIR/src"
+ pkgdirbase="$BUILDDIR/pkg"
+else
+ srcdir="$BUILDDIR/$pkgbase/src"
+ pkgdirbase="$BUILDDIR/$pkgbase/pkg"
+
+fi
+
+# set pkgdir to something "sensible" for (not recommended) use during build()
+pkgdir="$pkgdirbase/$pkgbase"
+
+if (( GENINTEG )); then
+ mkdir -p "$srcdir"
+ chmod a-s "$srcdir"
+ cd_safe "$srcdir"
+ download_sources novcs allarch
+ generate_checksums
+ exit 0 # $E_OK
+fi
+
+if have_function pkgver; then
+ PKGVERFUNC=1
+fi
+
+# check we have the software required to process the PKGBUILD
+check_software || exit 1
+
+if (( ${#pkgname[@]} > 1 )); then
+ SPLITPKG=1
+fi
+
+# test for available PKGBUILD functions
+if have_function prepare; then
+ # "Hide" prepare() function if not going to be run
+ if [[ $RUN_PREPARE != "n" ]]; then
+ PREPAREFUNC=1
+ fi
+fi
+if have_function build; then
+ BUILDFUNC=1
+fi
+if have_function check; then
+ # "Hide" check() function if not going to be run
+ if [[ $RUN_CHECK = 'y' ]] || { ! check_buildenv "check" "n" && [[ $RUN_CHECK != "n" ]]; }; then
+ CHECKFUNC=1
+ fi
+fi
+if have_function package; then
+ PKGFUNC=1
+elif [[ $SPLITPKG -eq 0 ]] && have_function package_${pkgname}; then
+ SPLITPKG=1
+fi
+
+# check if gpg signature is to be created and if signing key is valid
+if { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; } || [[ $SIGNPKG == 'y' ]]; then
+ SIGNPKG='y'
+ 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 (( PACKAGELIST )); then
+ print_all_package_names
+ exit 0
+fi
+
+if (( PRINTSRCINFO )); then
+ write_srcinfo_content
+ exit 0
+fi
+
+if (( ! PKGVERFUNC )); then
+ check_build_status
+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
+
+ chmod 755 "$pkgdirbase"
+ if (( ! SPLITPKG )); then
+ pkgdir="$pkgdirbase/$pkgname"
+ mkdir "$pkgdir"
+ if (( PKGFUNC )); then
+ run_package
+ fi
+ tidy_install
+ lint_package
+ create_package
+ create_debug_package
+ else
+ run_split_packaging
+ fi
+
+ msg "$(gettext "Leaving %s environment.")" "fakeroot"
+ exit 0 # $E_OK
+fi
+
+msg "$(gettext "Making package: %s")" "$pkgbase $basever ($(date))"
+
+# if we are creating a source-only package, go no further
+if (( SOURCEONLY )); then
+ if [[ -f $SRCPKGDEST/${pkgbase}-${basever}${SRCEXT} ]] \
+ && (( ! FORCE )); then
+ error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
+ exit 1
+ fi
+
+ # Get back to our src directory so we can begin with sources.
+ mkdir -p "$srcdir"
+ chmod a-s "$srcdir"
+ cd_safe "$srcdir"
+ if (( SOURCEONLY == 2 )); then
+ download_sources allarch
+ elif ( (( ! SKIPCHECKSUMS )) || \
+ ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then
+ download_sources allarch novcs
+ fi
+ check_source_integrity all
+ cd_safe "$startdir"
+
+ enter_fakeroot
+
+ msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
+ exit 0
+fi
+
+if (( NODEPS || ( VERIFYSOURCE && !DEP_BIN ) )); then
+ if (( NODEPS )); then
+ warning "$(gettext "Skipping dependency checks.")"
+ fi
+else
+ if (( RMDEPS && ! INSTALL )); then
+ original_pkglist=($(run_pacman -Qq)) # required by remove_dep
+ fi
+ deperr=0
+
+ msg "$(gettext "Checking runtime dependencies...")"
+ resolve_deps ${depends[@]} || deperr=1
+
+ if (( RMDEPS && INSTALL )); then
+ original_pkglist=($(run_pacman -Qq)) # required by remove_dep
+ fi
+
+ msg "$(gettext "Checking buildtime dependencies...")"
+ if (( CHECKFUNC )); then
+ resolve_deps "${makedepends[@]}" "${checkdepends[@]}" || deperr=1
+ else
+ resolve_deps "${makedepends[@]}" || deperr=1
+ fi
+
+ if (( RMDEPS )); then
+ current_pkglist=($(run_pacman -Qq)) # required by remove_deps
+ fi
+
+ if (( deperr )); then
+ error "$(gettext "Could not resolve all dependencies.")"
+ exit 1
+ fi
+fi
+
+# get back to our src directory so we can begin with sources
+mkdir -p "$srcdir"
+chmod a-s "$srcdir"
+cd_safe "$srcdir"
+
+if (( !REPKG )); then
+ if (( NOEXTRACT && ! VERIFYSOURCE )); then
+ warning "$(gettext "Using existing %s tree")" "\$srcdir/"
+ else
+ download_sources
+ check_source_integrity
+ (( VERIFYSOURCE )) && exit 0 # $E_OK
+
+ if (( CLEANBUILD )); then
+ msg "$(gettext "Removing existing %s directory...")" "\$srcdir/"
+ rm -rf "$srcdir"/*
+ fi
+
+ extract_sources
+ if (( PREPAREFUNC )); then
+ run_prepare
+ fi
+ fi
+
+ if (( PKGVERFUNC )); then
+ update_pkgver
+ basever=$(get_full_version)
+ check_build_status
+ fi
+fi
+
+if (( NOBUILD )); then
+ msg "$(gettext "Sources are ready.")"
+ exit 0 #E_OK
+else
+ # clean existing pkg directory
+ if [[ -d $pkgdirbase ]]; then
+ msg "$(gettext "Removing existing %s directory...")" "\$pkgdir/"
+ rm -rf "$pkgdirbase"
+ fi
+ mkdir -p "$pkgdirbase"
+ chmod a-srw "$pkgdirbase"
+ cd_safe "$startdir"
+
+ if (( ! REPKG )); then
+ (( BUILDFUNC )) && run_build
+ (( CHECKFUNC )) && run_check
+ cd_safe "$startdir"
+ fi
+
+ enter_fakeroot
+fi
+
+# if inhibiting archive creation, go no further
+if (( NOARCHIVE )); then
+ msg "$(gettext "Package directory is ready.")"
+ exit 0
+fi
+
+msg "$(gettext "Finished making: %s")" "$pkgbase $basever ($(date))"
+
+install_package
+
+exit 0 #E_OK
+
+# vim: set noet:
diff --git a/makepkg.conf b/makepkg.conf
new file mode 100644
index 000000000000..3199ec66de5e
--- /dev/null
+++ b/makepkg.conf
@@ -0,0 +1,148 @@
+#
+# /etc/makepkg.conf
+#
+
+#########################################################################
+# SOURCE ACQUISITION
+#########################################################################
+#
+#-- The download utilities that makepkg should use to acquire sources
+# Format: 'protocol::agent'
+DLAGENTS=( #'ftp::/usr/bin/aria2c --conf-path=/etc/aria2/aria2.conf --ftp-pasv %u -o %o'
+ #'http::/usr/bin/aria2c --conf-path=/etc/aria2/aria2.conf %u -o %o'
+ #'https::/usr/bin/aria2c --conf-path=/etc/aria2/aria2.conf %u -o %o'
+ 'ftp::/usr/bin/curl -fC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
+ 'http::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
+ 'https::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
+ 'rsync::/usr/bin/rsync --no-motd -z %u %o'
+ 'scp::/usr/bin/scp -C %u %o')
+
+# Other common tools:
+# /usr/bin/snarf
+# /usr/bin/lftpget -c
+# /usr/bin/wget
+
+#-- The the package required by makepkg to download VCS sources
+# Format: 'protocol::package'
+VCSCLIENTS=('bzr::bzr'
+ 'git::git'
+ 'hg::mercurial'
+ 'svn::subversion')
+
+#########################################################################
+# ARCHITECTURE, COMPILE FLAGS
+#########################################################################
+#
+CARCH="x86_64"
+CHOST="x86_64-unknown-linux-gnu"
+
+#-- Compiler and Linker Flags
+# -march (or -mcpu) builds exclusively for an architecture
+# -mtune optimizes for an architecture, but builds for whole processor family
+CPPFLAGS="-D_FORTIFY_SOURCE=2"
+CFLAGS="-pipe -march=native -O2 -fstack-protector-strong --param=ssp-buffer-size=4 -Wno-error -w"
+CXXFLAGS="$CFLAGS"
+LDFLAGS="-Wl,-O4,--sort-common,--as-needed,-z,relro"
+#-- Make Flags: change this for DistCC/SMP systems
+MAKEFLAGS="-j$(getconf _NPROCESSORS_ONLN) --quiet"
+#-- Debugging flags
+DEBUG_CFLAGS="-g -fvar-tracking-assignments"
+DEBUG_CXXFLAGS="-g -fvar-tracking-assignments"
+
+#########################################################################
+# BUILD ENVIRONMENT
+#########################################################################
+#
+# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign)
+# A negated environment option will do the opposite of the comments below.
+#
+#-- distcc: Use the Distributed C/C++/ObjC compiler
+#-- color: Colorize output messages
+#-- ccache: Use ccache to cache compilation
+#-- check: Run the check() function if present in the PKGBUILD
+#-- sign: Generate PGP signature file
+#
+BUILDENV=(!distcc color !ccache !check !sign)
+#
+#-- If using DistCC, your MAKEFLAGS will also need modification. In addition,
+#-- specify a space-delimited list of hosts running in the DistCC cluster.
+#DISTCC_HOSTS=""
+#
+#-- Specify a directory for package building.
+#BUILDDIR=/tmp/makepkg
+
+#########################################################################
+# GLOBAL PACKAGE OPTIONS
+# These are default values for the options=() settings
+#########################################################################
+#
+# Default: OPTIONS=(strip !docs !libtool !staticlibs !emptydirs zipman purge upx !debug)
+# A negated option will do the opposite of the comments below.
+#
+#-- strip: Strip symbols from binaries/libraries
+#-- docs: Save doc directories specified by DOC_DIRS
+#-- libtool: Leave libtool (.la) files in packages
+#-- staticlibs: Leave static library (.a) files in packages
+#-- emptydirs: Leave empty directories in packages
+#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip
+#-- purge: Remove files specified by PURGE_TARGETS
+#-- debug: Add debugging flags as specified in DEBUG_* variables
+#
+OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !debug)
+
+#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
+INTEGRITY_CHECK=(sha512)
+#-- Options to be used when stripping binaries. See `man strip' for details.
+STRIP_BINARIES="--strip-all"
+#-- Options to be used when stripping shared libraries. See `man strip' for details.
+STRIP_SHARED="--strip-unneeded"
+#-- Options to be used when stripping static libraries. See `man strip' for details.
+STRIP_STATIC="--strip-debug"
+#-- Manual (man and info) directories to compress (if zipman is specified)
+MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info})
+#-- Doc directories to remove (if !docs is specified)
+DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc})
+#-- Files to be removed from all packages (if purge is specified)
+PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
+
+#########################################################################
+# PACKAGE OUTPUT
+#########################################################################
+#
+# Default: put built package and cached source in build directory
+#
+#-- Destination: specify a fixed directory where all packages will be placed
+#PKGDEST=/home/packages
+#-- Source cache: specify a fixed directory where source files will be cached
+#SRCDEST=/home/sources
+#-- Source packages: specify a fixed directory where all src packages will be placed
+#SRCPKGDEST=/home/srcpackages
+#-- Log files: specify a fixed directory where all log files will be placed
+#LOGDEST=/home/makepkglogs
+#-- Packager: name/email of the person or organization building packages
+#PACKAGER="Your Name <urnick@urhost.ext>"
+#-- Specify a key to use for package signing
+#GPGKEY=""
+
+#########################################################################
+# COMPRESSION DEFAULTS
+#########################################################################
+#
+COMPRESSGZ=(gzip -c -f -n --best)
+COMPRESSBZ2=(bzip2 -c -f --best)
+COMPRESSXZ=(xz -c -z -)
+COMPRESSLRZ=(lrzip -q)
+COMPRESSLZO=(lzop -q --best)
+COMPRESSZ=(compress -c -f)
+
+#########################################################################
+# EXTENSION DEFAULTS
+#########################################################################
+#
+# WARNING: Do NOT modify these variables unless you know what you are
+# doing.
+#
+PKGEXT='.pkg.tar.xz'
+SRCEXT='.src.tar.gz'
+
+# vim: set ft=sh ts=2 sw=2 et:
diff --git a/opticonf.patch b/opticonf.patch
new file mode 100644
index 000000000000..a768fa64d81f
--- /dev/null
+++ b/opticonf.patch
@@ -0,0 +1,43 @@
+--- makepkg-optimize
++++ makepkg-optimize
+@@ -1862,7 +1862,7 @@
+ printf -- "$(gettext " -V, --version Show version information and exit")\n"
+ printf -- "$(gettext " --allsource Generate a source-only tarball including downloaded sources")\n"
+ 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 " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg-optimize.conf"
+ printf -- "$(gettext " --holdver Do not update VCS sources")\n"
+ printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
+ printf -- "$(gettext " --noarchive Do not create package archive")\n"
+@@ -2010,8 +2010,8 @@
+ [[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
+ [[ -n ${CARCH} ]] && _CARCH=${CARCH}
+
+-# default config is makepkg.conf
+-MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
++# default config is makepkg-optimize.conf
++MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg-optimize.conf}
+
+ # Source the config file; fail if it is not found
+ if [[ -r $MAKEPKG_CONF ]]; then
+@@ -2022,14 +2022,14 @@
+ exit 1 # $E_CONFIG_ERROR
+ fi
+
+-# Source user-specific makepkg.conf overrides, but only if no override config
++# Source user-specific makepkg-optimize.conf overrides, but only if no override config
+ # file was specified
+ XDG_PACMAN_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/pacman"
+-if [[ "$MAKEPKG_CONF" = "$confdir/makepkg.conf" ]]; then
+- if [[ -r "$XDG_PACMAN_DIR/makepkg.conf" ]]; then
+- source_safe "$XDG_PACMAN_DIR/makepkg.conf"
+- elif [[ -r "$HOME/.makepkg.conf" ]]; then
+- source_safe "$HOME/.makepkg.conf"
++if [[ "$MAKEPKG_CONF" = "$confdir/makepkg-optimize.conf" ]]; then
++ if [[ -r "$XDG_PACMAN_DIR/makepkg-optimize.conf" ]]; then
++ source_safe "$XDG_PACMAN_DIR/makepkg-optimize.conf"
++ elif [[ -r "$HOME/.makepkg-optimize.conf" ]]; then
++ source_safe "$HOME/.makepkg-optimize.conf"
+ fi
+ fi
+
diff --git a/optipng.sh b/optipng.sh
new file mode 100755
index 000000000000..ea64ee7c7a90
--- /dev/null
+++ b/optipng.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/bash
+#
+# optipng.sh - Compress PNG files using optpng
+#
+# Copyright (c) 2015-2016 Pacman Development Team <pacman-dev@archlinux.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/>.
+#
+
+[[ -n "$LIBMAKEPKG_TIDY_OPTIPNG_SH" ]] && return
+LIBMAKEPKG_TIDY_OPTIPNG_SH=1
+
+LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
+
+source "$LIBRARY/util/message.sh"
+source "$LIBRARY/util/option.sh"
+
+
+packaging_options+=('optipng')
+tidy_modify+=('tidy_optipng')
+
+tidy_optipng() {
+ if check_option "optipng" "y"; then
+ msg2 "$(gettext "Optimizing PNG images...")"
+ local png
+ find . -type f -iname "*.png" 2>/dev/null | while read -r png ; do
+ if [[ $(file --brief --mime-type "$png") = 'image/png' ]]; then
+ optipng "${OPTIPNGFLAGS[@]}" "$png" &>/dev/null ||
+ warning "$(gettext "Could not optimize PNG image : %s")" "${png/$pkgdir\//}"
+ fi
+ done
+ fi
+}
diff --git a/upx.sh b/upx.sh
new file mode 100755
index 000000000000..9d39c78ee209
--- /dev/null
+++ b/upx.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/bash
+#
+# upx.sh - Compress package binaries with UPX
+#
+# Copyright (c) 2011-2016 Pacman Development Team <pacman-dev@archlinux.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/>.
+#
+
+[[ -n "$LIBMAKEPKG_TIDY_UPX_SH" ]] && return
+LIBMAKEPKG_TIDY_UPX_SH=1
+
+LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
+
+source "$LIBRARY/util/message.sh"
+source "$LIBRARY/util/option.sh"
+
+
+packaging_options+=('upx')
+tidy_modify+=('tidy_upx')
+
+tidy_upx() {
+ 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 -r binary ; do
+ case "$(file --brief --mime-type "$binary")" in
+ 'application/x-executable' | 'application/x-dosexec')
+ upx "${UPXFLAGS[@]}" "$binary" &>/dev/null ||
+ warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
+ ;;
+ esac
+ done
+ fi
+}