Update copyright on changed files since beginning of year
[pacman-ng.git] / scripts / makepkg.sh.in
blob169162ce661c9bc24310efdf1eb72b357626dd32
1 #!/bin/bash -e
3 # makepkg - make packages compatible for use with pacman
4 # @configure_input@
6 # Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
7 # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
8 # Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
9 # Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
10 # Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
11 # Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
12 # Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
28 # makepkg uses quite a few external programs during its execution. You
29 # need to have at least the following installed for makepkg to function:
30 # awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
31 # gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
33 # gettext initialization
34 export TEXTDOMAIN='pacman-scripts'
35 export TEXTDOMAINDIR='@localedir@'
37 # file -i does not work on Mac OSX unless legacy mode is set
38 export COMMAND_MODE='legacy'
40 myver='@PACKAGE_VERSION@'
41 confdir='@sysconfdir@'
42 BUILDSCRIPT='@BUILDSCRIPT@'
43 startdir="$PWD"
45 packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx')
46 other_options=('ccache' 'distcc' 'buildflags' 'makeflags')
47 splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'license' \
48 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \
49 'replaces' 'backup' 'options' 'install' 'changelog')
50 readonly -a packaging_options other_options splitpkg_overrides
52 # Options
53 ASROOT=0
54 CLEANUP=0
55 DEP_BIN=0
56 FORCE=0
57 INFAKEROOT=0
58 GENINTEG=0
59 SKIPCHECKSUMS=0
60 SKIPPGPCHECK=0
61 INSTALL=0
62 NOBUILD=0
63 NODEPS=0
64 NOEXTRACT=0
65 RMDEPS=0
66 REPKG=0
67 LOGGING=0
68 SOURCEONLY=0
69 IGNOREARCH=0
70 HOLDVER=0
71 BUILDFUNC=0
72 CHECKFUNC=0
73 PKGFUNC=0
74 SPLITPKG=0
75 PKGLIST=()
76 SIGNPKG=''
78 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
79 # when dealing with svn/cvs/etc PKGBUILDs.
80 FORCE_VER=""
82 PACMAN_OPTS=
84 shopt -s extglob
86 ### SUBROUTINES ###
88 plain() {
89 local mesg=$1; shift
90 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
93 msg() {
94 local mesg=$1; shift
95 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
98 msg2() {
99 local mesg=$1; shift
100 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
103 warning() {
104 local mesg=$1; shift
105 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
108 error() {
109 local mesg=$1; shift
110 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
115 # Special exit call for traps, Don't print any error messages when inside,
116 # the fakeroot call, the error message will be printed by the main call.
118 trap_exit() {
119 if (( ! INFAKEROOT )); then
120 echo
121 error "$@"
123 [[ -n $srclinks ]] && rm -rf "$srclinks"
124 exit 1
129 # Clean up function. Called automatically when the script exits.
131 clean_up() {
132 local EXIT_CODE=$?
134 if (( INFAKEROOT )); then
135 # Don't clean up when leaving fakeroot, we're not done yet.
136 return
139 if (( ! EXIT_CODE && CLEANUP )); then
140 local pkg file
142 # If it's a clean exit and -c/--clean has been passed...
143 msg "$(gettext "Cleaning up...")"
144 rm -rf "$pkgdir" "$srcdir"
145 if [[ -n $pkgbase ]]; then
146 local fullver=$(get_full_version)
147 # Can't do this unless the BUILDSCRIPT has been sourced.
148 if (( BUILDFUNC )); then
149 rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
151 if (( CHECKFUNC )); then
152 rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
154 if (( PKGFUNC )); then
155 rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
156 elif (( SPLITPKG )); then
157 for pkg in ${pkgname[@]}; do
158 rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
159 done
162 # clean up dangling symlinks to packages
163 for pkg in ${pkgname[@]}; do
164 for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do
165 if [[ -h $file && ! -e $file ]]; then
166 rm -f $file
168 done
169 done
173 remove_deps
177 enter_fakeroot() {
178 msg "$(gettext "Entering %s environment...")" "fakeroot"
180 if [[ -n $newpkgver ]]; then
181 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
182 else
183 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
188 # a source entry can have two forms :
189 # 1) "filename::http://path/to/file"
190 # 2) "http://path/to/file"
192 # Return the absolute filename of a source entry
194 # This function accepts a source entry or the already extracted filename of a
195 # source entry as input
196 get_filepath() {
197 local file="$(get_filename "$1")"
199 if [[ -f "$startdir/$file" ]]; then
200 file="$startdir/$file"
201 elif [[ -f "$SRCDEST/$file" ]]; then
202 file="$SRCDEST/$file"
203 else
204 return 1
207 echo "$file"
210 # Print 'source not found' error message and exit makepkg
211 missing_source_file() {
212 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
213 plain "$(gettext "Aborting...")"
214 exit 1 # $E_MISSING_FILE
217 # extract the filename from a source entry
218 get_filename() {
219 # if a filename is specified, use it
220 local filename="${1%%::*}"
221 # if it is just an URL, we only keep the last component
222 echo "${filename##*/}"
225 # extract the URL from a source entry
226 get_url() {
227 # strip an eventual filename
228 echo "${1#*::}"
232 # usage : get_full_version( [$pkgname] )
233 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
235 get_full_version() {
236 if [[ -z $1 ]]; then
237 if [[ $epoch ]] && (( ! $epoch )); then
238 echo $pkgver-$pkgrel
239 else
240 echo $epoch:$pkgver-$pkgrel
242 else
243 for i in pkgver pkgrel epoch; do
244 local indirect="${i}_override"
245 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
246 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
247 done
248 if (( ! $epoch_override )); then
249 echo $pkgver_override-$pkgrel_override
250 else
251 echo $epoch_override:$pkgver_override-$pkgrel_override
257 # Checks to see if options are present in makepkg.conf or PKGBUILD;
258 # PKGBUILD options always take precedence.
260 # usage : check_option( $option )
261 # return : y - enabled
262 # n - disabled
263 # ? - not found
265 check_option() {
266 local ret=$(in_opt_array "$1" ${options[@]})
267 if [[ $ret != '?' ]]; then
268 echo $ret
269 return
272 # fall back to makepkg.conf options
273 ret=$(in_opt_array "$1" ${OPTIONS[@]})
274 if [[ $ret != '?' ]]; then
275 echo $ret
276 return
279 echo '?' # Not Found
284 # Check if option is present in BUILDENV
286 # usage : check_buildenv( $option )
287 # return : y - enabled
288 # n - disabled
289 # ? - not found
291 check_buildenv() {
292 in_opt_array "$1" ${BUILDENV[@]}
297 # usage : in_opt_array( $needle, $haystack )
298 # return : y - enabled
299 # n - disabled
300 # ? - not found
302 in_opt_array() {
303 local needle=$1; shift
305 local opt
306 for opt in "$@"; do
307 if [[ $opt = $needle ]]; then
308 echo 'y' # Enabled
309 return
310 elif [[ $opt = "!$needle" ]]; then
311 echo 'n' # Disabled
312 return
314 done
316 echo '?' # Not Found
321 # usage : in_array( $needle, $haystack )
322 # return : 0 - found
323 # 1 - not found
325 in_array() {
326 local needle=$1; shift
327 local item
328 for item in "$@"; do
329 [[ $item = $needle ]] && return 0 # Found
330 done
331 return 1 # Not Found
334 source_has_signatures(){
335 local file
336 for file in "${source[@]}"; do
337 if [[ $file = *.@(sig?(n)|asc) ]]; then
338 return 0
340 done
341 return 1
344 get_downloadclient() {
345 # $1 = URL with valid protocol prefix
346 local url=$1
347 local proto="${url%%://*}"
349 # loop through DOWNLOAD_AGENTS variable looking for protocol
350 local i
351 for i in "${DLAGENTS[@]}"; do
352 local handler="${i%%::*}"
353 if [[ $proto = $handler ]]; then
354 local agent="${i##*::}"
355 break
357 done
359 # if we didn't find an agent, return an error
360 if [[ -z $agent ]]; then
361 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
362 plain "$(gettext "Aborting...")"
363 exit 1 # $E_CONFIG_ERROR
366 # ensure specified program is installed
367 local program="${agent%% *}"
368 if [[ ! -x $program ]]; then
369 local baseprog="${program##*/}"
370 error "$(gettext "The download program %s is not installed.")" "$baseprog"
371 plain "$(gettext "Aborting...")"
372 exit 1 # $E_MISSING_PROGRAM
375 echo "$agent"
378 download_file() {
379 # download command
380 local dlcmd=$1
381 # URL of the file
382 local url=$2
383 # destination file
384 local file=$3
385 # temporary download file, default to last component of the URL
386 local dlfile="${url##*/}"
388 # replace %o by the temporary dlfile if it exists
389 if [[ $dlcmd = *%o* ]]; then
390 dlcmd=${dlcmd//\%o/\"$file.part\"}
391 dlfile="$file.part"
393 # add the URL, either in place of %u or at the end
394 if [[ $dlcmd = *%u* ]]; then
395 dlcmd=${dlcmd//\%u/\"$url\"}
396 else
397 dlcmd="$dlcmd \"$url\""
400 local ret=0
401 eval "$dlcmd || ret=\$?"
402 if (( ret )); then
403 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
404 return $ret
407 # rename the temporary download file to the final destination
408 if [[ $dlfile != "$file" ]]; then
409 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
413 run_pacman() {
414 local cmd
415 printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
416 if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
417 if type -p sudo >/dev/null; then
418 cmd="sudo $cmd"
419 else
420 cmd="su root -c '$cmd'"
423 eval "$cmd"
426 check_deps() {
427 (( $# > 0 )) || return 0
429 # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility
430 # Also, a non-zero return value is not unexpected and we are manually dealing them
431 set +E
432 local ret=0
433 local pmout
434 pmout=$(run_pacman -T "$@") || ret=$?
435 set -E
437 if (( ret == 127 )); then #unresolved deps
438 echo "$pmout"
439 elif (( ret )); then
440 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
441 return "$ret"
445 handle_deps() {
446 local R_DEPS_SATISFIED=0
447 local R_DEPS_MISSING=1
449 (( $# == 0 )) && return $R_DEPS_SATISFIED
451 local deplist="$*"
453 if (( ! DEP_BIN )); then
454 return $R_DEPS_MISSING
457 if (( DEP_BIN )); then
458 # install missing deps from binary packages (using pacman -S)
459 msg "$(gettext "Installing missing dependencies...")"
461 if ! run_pacman -S --asdeps $deplist; then
462 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
463 exit 1 # TODO: error code
467 # we might need the new system environment
468 # avoid triggering the ERR trap and exiting
469 set +e
470 local restoretrap=$(trap -p ERR)
471 trap - ERR
472 source /etc/profile &>/dev/null
473 eval $restoretrap
474 set -e
476 return $R_DEPS_SATISFIED
479 resolve_deps() {
480 local R_DEPS_SATISFIED=0
481 local R_DEPS_MISSING=1
483 # deplist cannot be declared like this: local deplist=$(foo)
484 # Otherwise, the return value will depend on the assignment.
485 local deplist
486 deplist="$(set +E; check_deps $*)" || exit 1
487 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
489 if handle_deps $deplist; then
490 # check deps again to make sure they were resolved
491 deplist="$(set +E; check_deps $*)" || exit 1
492 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
495 msg "$(gettext "Missing Dependencies:")"
496 local dep
497 for dep in $deplist; do
498 msg2 "$dep"
499 done
501 return $R_DEPS_MISSING
504 remove_deps() {
505 (( ! RMDEPS )) && return
507 # check for packages removed during dependency install (e.g. due to conflicts)
508 # removing all installed packages is risky in this case
509 if [[ -n $(grep -xvFf <(printf '%s\n' "${current_packagelist[@]}") \
510 <(printf '%s\n' "${original_packagelist[@]}") ) ]]; then
511 warning "$(gettext "Failed to remove installed dependencies.")"
512 return 0
515 local deplist
516 if ! deplist=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
517 <(printf "%s\n" "${current_pkglist[@]}"))); then
518 return
521 msg "Removing installed dependencies..."
522 # exit cleanly on failure to remove deps as package has been built successfully
523 if ! run_pacman -Rn ${deplist[@]}; then
524 warning "$(gettext "Failed to remove installed dependencies.")"
525 return 0
529 download_sources() {
530 msg "$(gettext "Retrieving Sources...")"
532 pushd "$SRCDEST" &>/dev/null
534 local netfile
535 for netfile in "${source[@]}"; do
536 local file=$(get_filepath "$netfile" || true)
537 if [[ -n "$file" ]]; then
538 msg2 "$(gettext "Found %s")" "${file##*/}"
539 rm -f "$srcdir/${file##*/}"
540 ln -s "$file" "$srcdir/"
541 continue
544 file=$(get_filename "$netfile")
545 local url=$(get_url "$netfile")
547 # if we get here, check to make sure it was a URL, else fail
548 if [[ $file = $url ]]; then
549 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
550 exit 1 # $E_MISSING_FILE
553 # find the client we should use for this URL
554 local dlclient
555 dlclient=$(get_downloadclient "$url") || exit $?
557 msg2 "$(gettext "Downloading %s...")" "$file"
558 # fix flyspray bug #3289
559 local ret=0
560 download_file "$dlclient" "$url" "$file" || ret=$?
561 if (( ret )); then
562 error "$(gettext "Failure while downloading %s")" "$file"
563 plain "$(gettext "Aborting...")"
564 exit 1
566 rm -f "$srcdir/$file"
567 ln -s "$SRCDEST/$file" "$srcdir/"
568 done
570 popd &>/dev/null
573 get_integlist() {
574 local integ
575 local integlist=()
577 for integ in md5 sha1 sha256 sha384 sha512; do
578 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
579 if [[ -n "$integrity_sums" ]]; then
580 integlist=(${integlist[@]} $integ)
582 done
584 if (( ${#integlist[@]} > 0 )); then
585 echo ${integlist[@]}
586 else
587 echo ${INTEGRITY_CHECK[@]}
591 generate_checksums() {
592 msg "$(gettext "Generating checksums for source files...")"
593 plain ""
595 if ! type -p openssl >/dev/null; then
596 error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
597 exit 1 # $E_MISSING_PROGRAM
600 local integlist
601 if (( $# == 0 )); then
602 integlist=$(get_integlist)
603 else
604 integlist=$@
607 local integ
608 for integ in ${integlist[@]}; do
609 case "$integ" in
610 md5|sha1|sha256|sha384|sha512) : ;;
612 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
613 exit 1;; # $E_CONFIG_ERROR
614 esac
616 local ct=0
617 local numsrc=${#source[@]}
618 echo -n "${integ}sums=("
620 local i
621 local indent=''
622 for (( i = 0; i < ${#integ} + 6; i++ )); do
623 indent="$indent "
624 done
626 local netfile
627 for netfile in "${source[@]}"; do
628 local file
629 file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
630 local sum="$(openssl dgst -${integ} "$file")"
631 sum=${sum##* }
632 (( ct )) && echo -n "$indent"
633 echo -n "'$sum'"
634 ct=$(($ct+1))
635 (( $ct < $numsrc )) && echo
636 done
638 echo ")"
639 done
642 check_checksums() {
643 (( SKIPCHECKSUMS )) && return 0
644 (( ! ${#source[@]} )) && return 0
646 local correlation=0
647 local integ required
648 for integ in md5 sha1 sha256 sha384 sha512; do
649 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
650 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
651 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
652 correlation=1
653 local errors=0
654 local idx=0
655 local file
656 for file in "${source[@]}"; do
657 local found=1
658 file="$(get_filename "$file")"
659 echo -n " $file ... " >&2
661 if ! file="$(get_filepath "$file")"; then
662 echo "$(gettext "NOT FOUND")" >&2
663 errors=1
664 found=0
667 if (( $found )) ; then
668 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
669 local realsum="$(openssl dgst -${integ} "$file")"
670 realsum="${realsum##* }"
671 if [[ $expectedsum = $realsum ]]; then
672 echo "$(gettext "Passed")" >&2
673 else
674 echo "$(gettext "FAILED")" >&2
675 errors=1
679 idx=$((idx + 1))
680 done
682 if (( errors )); then
683 error "$(gettext "One or more files did not pass the validity check!")"
684 exit 1 # TODO: error code
686 elif (( ${#integrity_sums[@]} )); then
687 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
688 exit 1 # TODO: error code
690 done
692 if (( ! correlation )); then
693 error "$(gettext "Integrity checks are missing.")"
694 exit 1 # TODO: error code
698 check_pgpsigs() {
699 (( SKIPPGPCHECK )) && return 0
700 ! source_has_signatures && return 0
702 msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
704 local file pubkey
705 local warning=0
706 local errors=0
707 local statusfile=$(mktemp)
709 for file in "${source[@]}"; do
710 file="$(get_filename "$file")"
711 if [[ ! $file = *.@(sig?(n)|asc) ]]; then
712 continue
715 printf " %s ... " "${file%.*}" >&2
717 if ! file="$(get_filepath "$file")"; then
718 printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
719 errors=1
720 continue
723 if ! sourcefile="$(get_filepath "${file%.*}")"; then
724 printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
725 errors=1
726 continue
729 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
730 printf '%s' "$(gettext "FAILED")" >&2
731 if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
732 printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
733 warnings=1
734 else
735 errors=1
737 printf '\n' >&2
738 else
739 if grep -q "REVKEYSIG" "$statusfile"; then
740 printf '%s (%s)' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
741 errors=1
742 else
743 printf '%s' "$(gettext "Passed")" >&2
744 if grep -q "EXPSIG" "$statusfile"; then
745 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
746 warnings=1
747 elif grep -q "EXPKEYSIG" "$statusfile"; then
748 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
749 warnings=1
752 printf '\n' >&2
754 done
756 rm -f "$statusfile"
758 if (( errors )); then
759 error "$(gettext "One or more PGP signatures could not be verified!")"
760 exit 1
763 if (( warnings )); then
764 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
765 plain "$(gettext "Please make sure you really trust them.")"
769 check_source_integrity() {
770 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
771 warning "$(gettext "Skipping all source file integrity checks.")"
772 elif (( SKIPCHECKSUMS )); then
773 warning "$(gettext "Skipping verification of source file checksums.")"
774 check_pgpsigs
775 elif (( SKIPPGPCHECK )); then
776 warning "$(gettext "Skipping verification of source file PGP signatures.")"
777 check_checksums
778 else
779 check_checksums
780 check_pgpsigs
784 extract_sources() {
785 msg "$(gettext "Extracting Sources...")"
786 local netfile
787 for netfile in "${source[@]}"; do
788 local file=$(get_filename "$netfile")
789 if in_array "$file" "${noextract[@]}"; then
790 #skip source files in the noextract=() array
791 # these are marked explicitly to NOT be extracted
792 continue
796 # fix flyspray #6246
797 local file_type=$(file -bizL "$file")
798 local ext=${file##*.}
799 local cmd=''
800 case "$file_type" in
801 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
802 cmd="bsdtar" ;;
803 *application/x-gzip*)
804 case "$ext" in
805 gz|z|Z) cmd="gzip" ;;
806 *) continue;;
807 esac ;;
808 *application/x-bzip*)
809 case "$ext" in
810 bz2|bz) cmd="bzip2" ;;
811 *) continue;;
812 esac ;;
813 *application/x-xz*)
814 case "$ext" in
815 xz) cmd="xz" ;;
816 *) continue;;
817 esac ;;
819 # See if bsdtar can recognize the file
820 if bsdtar -tf "$file" -q '*' &>/dev/null; then
821 cmd="bsdtar"
822 else
823 continue
824 fi ;;
825 esac
827 local ret=0
828 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
829 if [[ $cmd = bsdtar ]]; then
830 $cmd -xf "$file" || ret=$?
831 else
832 rm -f "${file%.*}"
833 $cmd -dcf "$file" > "${file%.*}" || ret=$?
835 if (( ret )); then
836 error "$(gettext "Failed to extract %s")" "$file"
837 plain "$(gettext "Aborting...")"
838 exit 1
840 done
842 if (( EUID == 0 )); then
843 # change perms of all source files to root user & root group
844 chown -R 0:0 "$srcdir"
848 error_function() {
849 if [[ -p $logpipe ]]; then
850 rm "$logpipe"
852 # first exit all subshells, then print the error
853 if (( ! BASH_SUBSHELL )); then
854 error "$(gettext "A failure occurred in %s().")" "$1"
855 plain "$(gettext "Aborting...")"
856 remove_deps
858 exit 2 # $E_BUILD_FAILED
861 run_function() {
862 if [[ -z $1 ]]; then
863 return 1
865 local pkgfunc="$1"
867 # clear user-specified buildflags if requested
868 if [[ $(check_option buildflags) = "n" ]]; then
869 unset CFLAGS CXXFLAGS LDFLAGS
872 # clear user-specified makeflags if requested
873 if [[ $(check_option makeflags) = "n" ]]; then
874 unset MAKEFLAGS
877 msg "$(gettext "Starting %s()...")" "$pkgfunc"
878 cd "$srcdir"
880 # ensure all necessary build variables are exported
881 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
882 # save our shell options so pkgfunc() can't override what we need
883 local shellopts=$(shopt -p)
885 local ret=0
886 local restoretrap
887 if (( LOGGING )); then
888 local fullver=$(get_full_version)
889 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
890 if [[ -f $BUILDLOG ]]; then
891 local i=1
892 while true; do
893 if [[ -f $BUILDLOG.$i ]]; then
894 i=$(($i +1))
895 else
896 break
898 done
899 mv "$BUILDLOG" "$BUILDLOG.$i"
902 # ensure overridden package variables survive tee with split packages
903 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
904 mkfifo "$logpipe"
905 tee "$BUILDLOG" < "$logpipe" &
906 local teepid=$!
908 restoretrap=$(trap -p ERR)
909 trap 'error_function $pkgfunc' ERR
910 $pkgfunc &>"$logpipe"
911 eval $restoretrap
913 wait $teepid
914 rm "$logpipe"
915 else
916 restoretrap=$(trap -p ERR)
917 trap 'error_function $pkgfunc' ERR
918 $pkgfunc 2>&1
919 eval $restoretrap
921 # reset our shell options
922 eval "$shellopts"
925 run_build() {
926 # use distcc if it is requested (check buildenv and PKGBUILD opts)
927 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
928 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
929 export DISTCC_HOSTS
932 # use ccache if it is requested (check buildenv and PKGBUILD opts)
933 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
934 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
937 run_function "build"
940 run_check() {
941 run_function "check"
944 run_package() {
945 local pkgfunc
946 if [[ -z $1 ]]; then
947 pkgfunc="package"
948 else
949 pkgfunc="package_$1"
952 run_function "$pkgfunc"
955 tidy_install() {
956 cd "$pkgdir"
957 msg "$(gettext "Tidying install...")"
959 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
960 msg2 "$(gettext "Removing doc files...")"
961 rm -rf ${DOC_DIRS[@]}
964 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
965 msg2 "$(gettext "Purging unwanted files...")"
966 local pt
967 for pt in "${PURGE_TARGETS[@]}"; do
968 if [[ ${pt} = ${pt//\/} ]]; then
969 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
970 else
971 rm -f ${pt}
973 done
976 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
977 msg2 "$(gettext "Compressing man and info pages...")"
978 local manpage ext file link hardlinks hl
979 find ${MAN_DIRS[@]} -type f 2>/dev/null |
980 while read manpage ; do
981 ext="${manpage##*.}"
982 file="${manpage##*/}"
983 if [[ $ext != gz && $ext != bz2 ]]; then
984 # update symlinks to this manpage
985 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
986 while read link ; do
987 rm -f "$link" "${link}.gz"
988 ln -s "${file}.gz" "${link}.gz"
989 done
991 # check file still exists (potentially already compressed due to hardlink)
992 if [[ -f ${manpage} ]]; then
993 # find hard links and remove them
994 # the '|| true' part keeps the script from bailing on the EOF returned
995 # by read at the end of the find output
996 IFS=$'\n' read -rd '' -a hardlinks < \
997 <(find "${MAN_DIRS[@]}" \! -name "$file" -samefile "$manpage" 2>/dev/null) || true
998 rm -f "${hardlinks[@]}"
999 # compress the original
1000 gzip -9 "$manpage"
1001 # recreate hard links removed earlier
1002 for hl in "${hardlinks[@]}"; do
1003 ln "${manpage}.gz" "${hl}.gz"
1004 chmod 644 ${hl}.gz
1005 done
1008 done
1011 if [[ $(check_option strip) = y ]]; then
1012 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1013 # make sure library stripping variables are defined to prevent excess stripping
1014 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1015 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1016 local binary
1017 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1018 case "$(file -bi "$binary")" in
1019 *application/x-sharedlib*) # Libraries (.so)
1020 strip $STRIP_SHARED "$binary";;
1021 *application/x-archive*) # Libraries (.a)
1022 strip $STRIP_STATIC "$binary";;
1023 *application/x-executable*) # Binaries
1024 strip $STRIP_BINARIES "$binary";;
1025 esac
1026 done
1029 if [[ $(check_option libtool) = "n" ]]; then
1030 msg2 "$(gettext "Removing "%s" files...")" "libtool"
1031 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
1034 if [[ $(check_option emptydirs) = "n" ]]; then
1035 msg2 "$(gettext "Removing empty directories...")"
1036 find . -depth -type d -empty -delete
1039 if [[ $(check_option upx) = "y" ]]; then
1040 msg2 "$(gettext "Compressing binaries with %s...")" "UPX"
1041 local binary
1042 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1043 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1044 upx $UPXFLAGS "$binary" &>/dev/null ||
1045 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1047 done
1051 find_libdepends() {
1052 local libdepends
1053 find "$pkgdir" -type f -perm -u+x | while read filename
1055 # get architecture of the file; if soarch is empty it's not an ELF binary
1056 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1057 [ -n "$soarch" ] || continue
1058 # process all libraries needed by the binary
1059 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1061 # extract the library name: libfoo.so
1062 soname="${sofile%%\.so\.*}.so"
1063 # extract the major version: 1
1064 soversion="${sofile##*\.so\.}"
1065 if in_array "${soname}" ${depends[@]}; then
1066 if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then
1067 # libfoo.so=1-64
1068 echo "${soname}=${soversion}-${soarch}"
1069 libdepends=(${libdepends[@]} "${soname}=${soversion}-${soarch}")
1072 done
1073 done
1076 find_libprovides() {
1077 local libprovides
1078 find "$pkgdir" -type f -name \*.so\* | while read filename
1080 # check if we really have a shared object
1081 if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1082 # 64
1083 soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1084 # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1
1085 sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1086 [ -z "$sofile" ] && sofile="${filename##*/}"
1088 # extract the library name: libfoo.so
1089 soname="${sofile%%\.so\.*}.so"
1090 # extract the major version: 1
1091 soversion="${sofile##*\.so\.}"
1092 if in_array "${soname}" ${provides[@]}; then
1093 if ! in_array "${soname}=${soversion}-${soarch}" ${libprovides[@]}; then
1094 # libfoo.so=1-64
1095 echo "${soname}=${soversion}-${soarch}"
1096 libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
1100 done
1103 write_pkginfo() {
1104 local builddate=$(date -u "+%s")
1105 if [[ -n $PACKAGER ]]; then
1106 local packager="$PACKAGER"
1107 else
1108 local packager="Unknown Packager"
1110 local size="$(@DUPATH@ -sk)"
1111 size="$(( ${size%%[^0-9]*} * 1024 ))"
1113 msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
1114 echo "# Generated by makepkg $myver"
1115 if (( INFAKEROOT )); then
1116 echo "# using $(fakeroot -v)"
1118 echo "# $(LC_ALL=C date -u)"
1119 echo "pkgname = $1"
1120 (( SPLITPKG )) && echo pkgbase = $pkgbase
1121 echo "pkgver = $(get_full_version)"
1122 echo "pkgdesc = $pkgdesc"
1123 echo "url = $url"
1124 echo "builddate = $builddate"
1125 echo "packager = $packager"
1126 echo "size = $size"
1127 echo "arch = $PKGARCH"
1129 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1130 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1131 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1132 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
1133 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1134 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1136 local it
1138 libprovides=$(find_libprovides)
1139 libdepends=$(find_libdepends)
1140 provides=("${provides[@]}" ${libprovides})
1141 depends=("${depends[@]}" ${libdepends})
1143 for it in "${depends[@]}"; do
1144 if [[ $it = *.so ]]; then
1145 # check if the entry has been found by find_libdepends
1146 # if not, it's unneeded; tell the user so he can remove it
1147 if [[ ! $libdepends =~ (^|\s)${it}=.* ]]; then
1148 error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it"
1149 return 1
1151 else
1152 echo "depend = $it"
1154 done
1156 for it in "${provides[@]}"; do
1157 # ignore versionless entires (those come from the PKGBUILD)
1158 if [[ $it = *.so ]]; then
1159 # check if the entry has been found by find_libprovides
1160 # if not, it's unneeded; tell the user so he can remove it
1161 if [[ ! $libprovides =~ (^|\s)${it}=.* ]]; then
1162 error "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$it"
1163 return 1
1165 else
1166 echo "provides = $it"
1168 done
1170 for it in "${packaging_options[@]}"; do
1171 local ret="$(check_option $it)"
1172 if [[ $ret != "?" ]]; then
1173 if [[ $ret = y ]]; then
1174 echo "makepkgopt = $it"
1175 else
1176 echo "makepkgopt = !$it"
1179 done
1181 # TODO maybe remove this at some point
1182 # warn if license array is not present or empty
1183 if [[ -z $license ]]; then
1184 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1185 plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
1189 check_package() {
1190 cd "$pkgdir"
1192 # check existence of backup files
1193 local file
1194 for file in "${backup[@]}"; do
1195 if [[ ! -f $file ]]; then
1196 warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
1198 done
1200 # check for references to the build and package directory
1201 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1202 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
1204 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
1205 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
1210 create_package() {
1211 if [[ ! -d $pkgdir ]]; then
1212 error "$(gettext "Missing %s directory.")" "pkg/"
1213 plain "$(gettext "Aborting...")"
1214 exit 1 # $E_MISSING_PKGDIR
1217 check_package
1219 cd "$pkgdir"
1220 msg "$(gettext "Creating package...")"
1222 local nameofpkg
1223 if [[ -z $1 ]]; then
1224 nameofpkg="$pkgname"
1225 else
1226 nameofpkg="$1"
1229 if [[ $arch = "any" ]]; then
1230 PKGARCH="any"
1231 else
1232 PKGARCH=$CARCH
1235 write_pkginfo $nameofpkg > .PKGINFO
1237 local comp_files=".PKGINFO"
1239 # check for changelog/install files
1240 for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1241 IFS='/' read -r orig dest < <(printf '%s\n' "$i")
1243 if [[ -n ${!orig} ]]; then
1244 msg2 "$(gettext "Adding %s file...")" "$orig"
1245 cp "$startdir/${!orig}" "$dest"
1246 chmod 644 "$dest"
1247 comp_files+=" $dest"
1249 done
1251 # tar it up
1252 msg2 "$(gettext "Compressing package...")"
1254 local fullver=$(get_full_version)
1255 local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}"
1256 local ret=0
1258 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1259 [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
1261 # when fileglobbing, we want * in an empty directory to expand to
1262 # the null string rather than itself
1263 shopt -s nullglob
1264 # TODO: Maybe this can be set globally for robustness
1265 shopt -s -o pipefail
1266 # bsdtar's gzip compression always saves the time stamp, making one
1267 # archive created using the same command line distinct from another.
1268 # Disable bsdtar compression and use gzip -n for now.
1269 bsdtar -cf - $comp_files * |
1270 case "$PKGEXT" in
1271 *tar.gz) gzip -c -f -n ;;
1272 *tar.bz2) bzip2 -c -f ;;
1273 *tar.xz) xz -c -z - ;;
1274 *tar.Z) compress -c -f ;;
1275 *tar) cat ;;
1276 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1277 "$PKGEXT"; cat ;;
1278 esac > "${pkg_file}" || ret=$?
1280 shopt -u nullglob
1281 shopt -u -o pipefail
1283 if (( ret )); then
1284 error "$(gettext "Failed to create package file.")"
1285 exit 1 # TODO: error code
1288 create_signature "$pkg_file"
1290 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1291 rm -f "${pkg_file/$PKGDEST/$startdir}"
1292 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1293 ret=$?
1294 if [[ -f $pkg_file.sig ]]; then
1295 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1296 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1300 if (( ret )); then
1301 warning "$(gettext "Failed to create symlink to package file.")"
1305 create_signature() {
1306 if [[ $SIGNPKG != 'y' ]]; then
1307 return
1309 local ret=0
1310 local filename="$1"
1311 msg "$(gettext "Signing package...")"
1313 local SIGNWITHKEY=""
1314 if [[ -n $GPGKEY ]]; then
1315 SIGNWITHKEY="-u ${GPGKEY}"
1317 # The signature will be generated directly in ascii-friendly format
1318 gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
1321 if (( ! ret )); then
1322 msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
1323 else
1324 warning "$(gettext "Failed to sign package file.")"
1328 create_srcpackage() {
1329 local ret=0
1330 msg "$(gettext "Creating source package...")"
1331 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1332 mkdir "${srclinks}"/${pkgbase}
1334 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1335 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1337 local file
1338 for file in "${source[@]}"; do
1339 if [[ "$file" == $(get_filename "$file") ]] || (( SOURCEONLY == 2 )); then
1340 local absfile
1341 absfile=$(get_filepath "$file") || missing_source_file "$file"
1342 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1343 ln -s "$absfile" "$srclinks/$pkgbase"
1345 done
1347 local i
1348 for i in 'changelog' 'install'; do
1349 local file
1350 while read -r file; do
1351 # evaluate any bash variables used
1352 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1353 if [[ $file && ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1354 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1355 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1357 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1358 done
1360 local TAR_OPT
1361 case "$SRCEXT" in
1362 *tar.gz) TAR_OPT="z" ;;
1363 *tar.bz2) TAR_OPT="j" ;;
1364 *tar.xz) TAR_OPT="J" ;;
1365 *tar.Z) TAR_OPT="Z" ;;
1366 *tar) TAR_OPT="" ;;
1367 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1368 "$SRCEXT" ;;
1369 esac
1371 local fullver=$(get_full_version)
1372 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1374 # tar it up
1375 msg2 "$(gettext "Compressing source package...")"
1376 cd "${srclinks}"
1377 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1378 error "$(gettext "Failed to create source package file.")"
1379 exit 1 # TODO: error code
1382 if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1383 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1384 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1385 ret=$?
1388 if (( ret )); then
1389 warning "$(gettext "Failed to create symlink to source package file.")"
1392 cd "${startdir}"
1393 rm -rf "${srclinks}"
1396 install_package() {
1397 (( ! INSTALL )) && return
1399 if (( ! SPLITPKG )); then
1400 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1401 else
1402 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1405 local fullver pkg pkglist
1406 for pkg in ${pkgname[@]}; do
1407 fullver=$(get_full_version $pkg)
1408 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then
1409 pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}"
1410 else
1411 pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}"
1413 done
1415 if ! run_pacman -U $pkglist; then
1416 warning "$(gettext "Failed to install built package(s).")"
1417 return 0
1421 check_sanity() {
1422 # check for no-no's in the build script
1423 local i
1424 local ret=0
1425 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1426 if [[ -z ${!i} ]]; then
1427 error "$(gettext "%s is not allowed to be empty.")" "$i"
1428 ret=1
1430 done
1432 for i in "${pkgname[@]}"; do
1433 if [[ ${i:0:1} = "-" ]]; then
1434 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1435 ret=1
1437 done
1439 if [[ ${pkgbase:0:1} = "-" ]]; then
1440 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1441 ret=1
1444 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1445 while IFS='=' read -r _ i; do
1446 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1447 if [[ $i = *[[:space:]:-]* ]]; then
1448 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1449 return 1
1451 done || ret=1
1453 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1454 while IFS='=' read -r _ i; do
1455 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1456 if [[ $i = *[[:space:]-]* ]]; then
1457 error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel"
1458 return 1
1460 done || ret=1
1462 awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
1463 while IFS='=' read -r _ i; do
1464 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1465 if [[ $i != *([[:digit:]]) ]]; then
1466 error "$(gettext "%s must be an integer.")" "epoch"
1467 return 1
1469 done || ret=1
1471 if [[ $arch != 'any' ]]; then
1472 if ! in_array $CARCH ${arch[@]}; then
1473 if (( ! IGNOREARCH )); then
1474 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1475 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1476 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1477 ret=1
1482 if (( ${#pkgname[@]} > 1 )); then
1483 for i in ${pkgname[@]}; do
1484 local arch_list=""
1485 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1486 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1487 if ! in_array $CARCH ${arch_list[@]}; then
1488 if (( ! IGNOREARCH )); then
1489 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1490 ret=1
1494 done
1497 local provides_list=()
1498 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1499 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1500 for i in ${provides_list[@]}; do
1501 if [[ $i == *['<>']* ]]; then
1502 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1503 ret=1
1505 done
1507 local backup_list=()
1508 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1509 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1510 for i in "${backup_list[@]}"; do
1511 if [[ ${i:0:1} = "/" ]]; then
1512 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1513 ret=1
1515 done
1517 local optdepends_list=()
1518 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1519 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1520 for i in "${optdepends_list[@]}"; do
1521 local pkg=${i%%:[[:space:]]*}
1522 # the '-' character _must_ be first or last in the character range
1523 if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then
1524 error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
1525 ret=1
1527 done
1529 for i in 'changelog' 'install'; do
1530 local file
1531 while read -r file; do
1532 # evaluate any bash variables used
1533 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1534 if [[ $file && ! -f $file ]]; then
1535 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1536 ret=1
1538 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1539 done
1541 local valid_options=1
1542 local known kopt options_list
1543 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
1544 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
1545 for i in ${options_list[@]}; do
1546 known=0
1547 # check if option matches a known option or its inverse
1548 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1549 if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then
1550 known=1
1552 done
1553 if (( ! known )); then
1554 error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
1555 valid_options=0
1557 done
1558 if (( ! valid_options )); then
1559 ret=1
1562 if (( ${#pkgname[@]} > 1 )); then
1563 for i in ${pkgname[@]}; do
1564 if ! declare -f package_${i} >/dev/null; then
1565 error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
1566 ret=1
1568 done
1571 for i in ${PKGLIST[@]}; do
1572 if ! in_array $i ${pkgname[@]}; then
1573 error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1574 ret=1
1576 done
1578 return $ret
1581 check_software() {
1582 # check for needed software
1583 local ret=0
1585 # check for sudo if we will need it during makepkg execution
1586 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1587 if ! type -p sudo >/dev/null; then
1588 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1592 # fakeroot - building as non-root user
1593 if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1594 if ! type -p fakeroot >/dev/null; then
1595 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
1596 ret=1
1600 # gpg - package signing
1601 if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then
1602 if ! type -p gpg >/dev/null; then
1603 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
1604 ret=1
1608 # gpg - source verification
1609 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
1610 if ! type -p gpg >/dev/null; then
1611 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
1612 ret=1
1616 # openssl - checksum operations
1617 if (( ! SKIPCHECKSUMS )); then
1618 if ! type -p openssl >/dev/null; then
1619 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
1620 ret=1
1624 # upx - binary compression
1625 if [[ $(check_option upx) == 'y' ]]; then
1626 if ! type -p upx >/dev/null; then
1627 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
1628 ret=1
1632 # distcc - compilation with distcc
1633 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
1634 if ! type -p distcc >/dev/null; then
1635 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
1636 ret=1
1640 # ccache - compilation with ccache
1641 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
1642 if ! type -p ccache >/dev/null; then
1643 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
1644 ret=1
1648 # strip - strip symbols from binaries/libraries
1649 if [[ $(check_option strip) = "y" ]]; then
1650 if ! type -p strip >/dev/null; then
1651 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
1652 ret=1
1656 # gzip - compressig man and info pages
1657 if [[ $(check_option zipman) = "y" ]]; then
1658 if ! type -p gzip >/dev/null; then
1659 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
1660 ret=1
1664 return $ret
1667 devel_check() {
1668 newpkgver=""
1670 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1671 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1672 if (( HOLDVER || SOURCEONLY || REPKG )) ||
1673 [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = /dev/stdin ]]; then
1674 return
1677 if [[ -z $FORCE_VER ]]; then
1678 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1679 # This will only be used on the first call to makepkg; subsequent
1680 # calls to makepkg via fakeroot will explicitly pass the version
1681 # number to avoid having to determine the version number twice.
1682 # Also do a check to make sure we have the VCS tool available.
1683 oldpkgver=$pkgver
1684 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1685 if ! type -p darcs >/dev/null; then
1686 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "darcs" "darcs"
1687 return 0
1689 msg "$(gettext "Determining latest %s revision...")" 'darcs'
1690 newpkgver=$(date +%Y%m%d)
1691 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1692 if ! type -p cvs >/dev/null; then
1693 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "cvs" "cvs"
1694 return 0
1696 msg "$(gettext "Determining latest %s revision...")" 'cvs'
1697 newpkgver=$(date +%Y%m%d)
1698 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1699 if ! type -p git >/dev/null; then
1700 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "git" "git"
1701 return 0
1703 msg "$(gettext "Determining latest %s revision...")" 'git'
1704 newpkgver=$(date +%Y%m%d)
1705 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1706 if ! type -p svn >/dev/null; then
1707 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "svn" "svn"
1708 return 0
1710 msg "$(gettext "Determining latest %s revision...")" 'svn'
1711 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1712 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1713 if ! type -p bzr >/dev/null; then
1714 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "bzr" "bzr"
1715 return 0
1717 msg "$(gettext "Determining latest %s revision...")" 'bzr'
1718 newpkgver=$(bzr revno ${_bzrtrunk})
1719 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1720 if ! type -p hg >/dev/null; then
1721 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "hg" "hg"
1722 return 0
1724 msg "$(gettext "Determining latest %s revision...")" 'hg'
1725 if [[ -d ./src/$_hgrepo ]] ; then
1726 cd ./src/$_hgrepo
1727 hg pull
1728 hg update
1729 else
1730 [[ ! -d ./src/ ]] && mkdir ./src/
1731 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1732 cd ./src/$_hgrepo
1734 newpkgver=$(hg tip --template "{rev}")
1735 cd ../../
1738 if [[ -n $newpkgver ]]; then
1739 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1742 else
1743 # Version number retrieved from fakeroot->makepkg argument
1744 newpkgver=$FORCE_VER
1748 devel_update() {
1749 # This is lame, but if we're wanting to use an updated pkgver for
1750 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1751 # the new pkgver and then re-source it. This is the most robust
1752 # method for dealing with PKGBUILDs that use, e.g.:
1754 # pkgver=23
1755 # ...
1756 # _foo=pkgver
1758 if [[ -n $newpkgver ]]; then
1759 if [[ $newpkgver != "$pkgver" ]]; then
1760 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1761 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1762 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1763 source "$BUILDFILE"
1769 backup_package_variables() {
1770 local var
1771 for var in ${splitpkg_overrides[@]}; do
1772 local indirect="${var}_backup"
1773 eval "${indirect}=(\"\${$var[@]}\")"
1774 done
1777 restore_package_variables() {
1778 local var
1779 for var in ${splitpkg_overrides[@]}; do
1780 local indirect="${var}_backup"
1781 if [[ -n ${!indirect} ]]; then
1782 eval "${var}=(\"\${$indirect[@]}\")"
1783 else
1784 unset ${var}
1786 done
1789 run_split_packaging() {
1790 local pkgname_backup=${pkgname[@]}
1791 for pkgname in ${pkgname_backup[@]}; do
1792 pkgdir="$pkgdir/$pkgname"
1793 mkdir -p "$pkgdir"
1794 chmod a-s "$pkgdir"
1795 backup_package_variables
1796 run_package $pkgname
1797 tidy_install
1798 create_package $pkgname
1799 restore_package_variables
1800 pkgdir="${pkgdir%/*}"
1801 done
1802 pkgname=${pkgname_backup[@]}
1805 # Canonicalize a directory path if it exists
1806 canonicalize_path() {
1807 local path="$1";
1809 if [[ -d $path ]]; then
1811 cd "$path"
1812 pwd -P
1814 else
1815 echo "$path"
1819 m4_include(library/parse_options.sh)
1821 usage() {
1822 printf "makepkg (pacman) %s\n" "$myver"
1823 echo
1824 printf "$(gettext "Usage: %s [options]")\n" "$0"
1825 echo
1826 echo "$(gettext "Options:")"
1827 printf "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
1828 echo "$(gettext " -c, --clean Clean up work files after build")"
1829 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1830 printf "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
1831 echo "$(gettext " -f, --force Overwrite existing package")"
1832 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1833 echo "$(gettext " -h, --help Show this help message and exit")"
1834 echo "$(gettext " -i, --install Install package after successful build")"
1835 echo "$(gettext " -L, --log Log package build process")"
1836 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1837 echo "$(gettext " -o, --nobuild Download and extract files only")"
1838 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1839 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1840 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1841 printf "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
1842 echo "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")"
1843 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1844 printf "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
1845 printf "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1846 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1847 printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1848 printf "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
1849 printf "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1850 echo "$(gettext " --nosign Do not create a signature for the package")"
1851 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1852 printf "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
1853 echo "$(gettext " --skipchecksums Do not verify checksums of the source files")"
1854 echo "$(gettext " --skipinteg Do not perform any verification checks on source files")"
1855 echo "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")"
1856 echo
1857 printf "$(gettext "These options can be passed to %s:")\n" "pacman"
1858 echo
1859 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1860 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1861 echo
1862 printf "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
1863 echo
1866 version() {
1867 printf "makepkg (pacman) %s\n" "$myver"
1868 printf "$(gettext "\
1869 Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1870 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1871 This is free software; see the source for copying conditions.\n\
1872 There is NO WARRANTY, to the extent permitted by law.\n")"
1875 # PROGRAM START
1877 # determine whether we have gettext; make it a no-op if we do not
1878 if ! type -p gettext >/dev/null; then
1879 gettext() {
1880 echo "$@"
1884 ARGLIST=("$@")
1886 # Parse Command Line Options.
1887 OPT_SHORT="AcdefFghiLmop:rRsSV"
1888 OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
1889 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck"
1890 OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
1891 OPT_LONG+=",repackage,skipchecksums,skipinteg,skippgpcheck,sign,source,syncdeps"
1892 OPT_LONG+=",version,config:"
1894 # Pacman Options
1895 OPT_LONG+=",noconfirm,noprogressbar"
1896 if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
1897 echo; usage; exit 1 # E_INVALID_OPTION;
1899 eval set -- "$OPT_TEMP"
1900 unset OPT_SHORT OPT_LONG OPT_TEMP
1902 while true; do
1903 case "$1" in
1904 # Pacman Options
1905 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1906 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1908 # Makepkg Options
1909 --allsource) SOURCEONLY=2 ;;
1910 --asroot) ASROOT=1 ;;
1911 -A|--ignorearch) IGNOREARCH=1 ;;
1912 -c|--clean) CLEANUP=1 ;;
1913 --check) RUN_CHECK='y' ;;
1914 --config) shift; MAKEPKG_CONF=$1 ;;
1915 -d|--nodeps) NODEPS=1 ;;
1916 -e|--noextract) NOEXTRACT=1 ;;
1917 -f|--force) FORCE=1 ;;
1918 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1919 --forcever) shift; FORCE_VER=$1;;
1920 -F) INFAKEROOT=1 ;;
1921 -g|--geninteg) GENINTEG=1 ;;
1922 --holdver) HOLDVER=1 ;;
1923 -i|--install) INSTALL=1 ;;
1924 --key) shift; GPGKEY=$1 ;;
1925 -L|--log) LOGGING=1 ;;
1926 -m|--nocolor) USE_COLOR='n' ;;
1927 --nocheck) RUN_CHECK='n' ;;
1928 --nosign) SIGNPKG='n' ;;
1929 -o|--nobuild) NOBUILD=1 ;;
1930 -p) shift; BUILDFILE=$1 ;;
1931 --pkg) shift; PKGLIST=($1) ;;
1932 -r|--rmdeps) RMDEPS=1 ;;
1933 -R|--repackage) REPKG=1 ;;
1934 --skipchecksums) SKIPCHECKSUMS=1 ;;
1935 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
1936 --skippgpcheck) SKIPPGPCHECK=1;;
1937 --sign) SIGNPKG='y' ;;
1938 -s|--syncdeps) DEP_BIN=1 ;;
1939 -S|--source) SOURCEONLY=1 ;;
1941 -h|--help) usage; exit 0 ;; # E_OK
1942 -V|--version) version; exit 0 ;; # E_OK
1944 --) OPT_IND=0; shift; break;;
1945 *) usage; exit 1 ;; # E_INVALID_OPTION
1946 esac
1947 shift
1948 done
1950 # setup signal traps
1951 trap 'clean_up' 0
1952 for signal in TERM HUP QUIT; do
1953 trap "trap_exit \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal"
1954 done
1955 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
1956 trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
1957 set -E
1959 # preserve environment variables and canonicalize path
1960 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
1961 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
1962 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
1963 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
1964 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
1965 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
1966 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
1968 # default config is makepkg.conf
1969 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1971 # Source the config file; fail if it is not found
1972 if [[ -r $MAKEPKG_CONF ]]; then
1973 source "$MAKEPKG_CONF"
1974 else
1975 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1976 plain "$(gettext "Aborting...")"
1977 exit 1 # $E_CONFIG_ERROR
1980 # Source user-specific makepkg.conf overrides, but only if no override config
1981 # file was specified
1982 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
1983 source ~/.makepkg.conf
1986 # set pacman command if not already defined
1987 PACMAN=${PACMAN:-pacman}
1989 # check if messages are to be printed using color
1990 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1991 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1992 # prefer terminal safe colored and bold text when tput is supported
1993 if tput setaf 0 &>/dev/null; then
1994 ALL_OFF="$(tput sgr0)"
1995 BOLD="$(tput bold)"
1996 BLUE="${BOLD}$(tput setaf 4)"
1997 GREEN="${BOLD}$(tput setaf 2)"
1998 RED="${BOLD}$(tput setaf 1)"
1999 YELLOW="${BOLD}$(tput setaf 3)"
2000 else
2001 ALL_OFF="\e[1;0m"
2002 BOLD="\e[1;1m"
2003 BLUE="${BOLD}\e[1;34m"
2004 GREEN="${BOLD}\e[1;32m"
2005 RED="${BOLD}\e[1;31m"
2006 YELLOW="${BOLD}\e[1;33m"
2009 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2011 # override settings with an environment variable for batch processing
2012 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2013 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2014 if [[ ! -d $BUILDDIR ]]; then
2015 mkdir -p "$BUILDDIR" ||
2016 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2017 chmod a-s "$BUILDDIR"
2019 if [[ ! -w $BUILDDIR ]]; then
2020 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2021 plain "$(gettext "Aborting...")"
2022 exit 1
2024 srcdir="$BUILDDIR/src"
2025 pkgdir="$BUILDDIR/pkg"
2027 PKGDEST=${_PKGDEST:-$PKGDEST}
2028 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2029 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2030 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2031 plain "$(gettext "Aborting...")"
2032 exit 1
2035 SRCDEST=${_SRCDEST:-$SRCDEST}
2036 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2037 if [[ ! -w $SRCDEST ]] ; then
2038 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2039 plain "$(gettext "Aborting...")"
2040 exit 1
2043 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2044 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2046 PKGEXT=${_PKGEXT:-$PKGEXT}
2047 SRCEXT=${_SRCEXT:-$SRCEXT}
2048 GPGKEY=${_GPGKEY:-$GPGKEY}
2050 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
2051 # The '\\0' is here to prevent gettext from thinking --holdver is an option
2052 error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
2053 exit 1
2056 if (( ! INFAKEROOT )); then
2057 if (( EUID == 0 && ! ASROOT )); then
2058 # Warn those who like to live dangerously.
2059 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2060 catastrophic damage to your system. If you wish to run as root, please\n\
2061 use the %s option.")" "makepkg" "--asroot"
2062 exit 1 # $E_USER_ABORT
2063 elif (( EUID > 0 && ASROOT )); then
2064 # Warn those who try to use the --asroot option when they are not root
2065 error "$(gettext "The %s option is meant for the root user only. Please\n\
2066 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2067 exit 1 # $E_USER_ABORT
2068 elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
2069 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2070 ownership of the packaged files. Try using the %s environment by\n\
2071 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF"
2072 sleep 1
2074 else
2075 if [[ -z $FAKEROOTKEY ]]; then
2076 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2077 exit 1 # TODO: error code
2081 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2082 unset md5sums replaces depends conflicts backup source install changelog build
2083 unset makedepends optdepends options noextract
2085 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2086 if [[ ! -f $BUILDFILE ]]; then
2087 if [[ -t 0 ]]; then
2088 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2089 exit 1
2090 else
2091 # PKGBUILD passed through a pipe
2092 BUILDFILE=/dev/stdin
2093 source "$BUILDFILE"
2095 else
2096 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2097 if [[ -n $crlftest ]]; then
2098 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2099 exit 1
2102 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2103 BUILDFILE="$startdir/$BUILDFILE"
2105 source "$BUILDFILE"
2108 # set defaults if they weren't specified in buildfile
2109 pkgbase=${pkgbase:-${pkgname[0]}}
2110 epoch=${epoch:-0}
2112 if (( GENINTEG )); then
2113 mkdir -p "$srcdir"
2114 chmod a-s "$srcdir"
2115 cd "$srcdir"
2116 download_sources
2117 generate_checksums
2118 exit 0 # $E_OK
2121 # check the PKGBUILD for some basic requirements
2122 check_sanity || exit 1
2124 # check we have the software required to process the PKGBUILD
2125 check_software || exit 1
2127 # We need to run devel_update regardless of whether we are in the fakeroot
2128 # build process so that if the user runs makepkg --forcever manually, we
2129 # 1) output the correct pkgver, and 2) use the correct filename when
2130 # checking if the package file already exists - fixes FS #9194
2131 devel_check
2132 devel_update
2134 if (( ${#pkgname[@]} > 1 )); then
2135 SPLITPKG=1
2138 # test for available PKGBUILD functions
2139 if declare -f build >/dev/null; then
2140 BUILDFUNC=1
2142 if declare -f check >/dev/null; then
2143 # "Hide" check() function if not going to be run
2144 if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then
2145 CHECKFUNC=1
2148 if declare -f package >/dev/null; then
2149 PKGFUNC=1
2150 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
2151 SPLITPKG=1
2154 if [[ -n "${PKGLIST[@]}" ]]; then
2155 unset pkgname
2156 pkgname=("${PKGLIST[@]}")
2159 # check if gpg signature is to be created and if signing key is valid
2160 [[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign)
2161 if [[ $SIGNPKG == 'y' ]]; then
2162 if ! gpg --list-key ${GPGKEY} &>/dev/null; then
2163 if [[ ! -z $GPGKEY ]]; then
2164 error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2165 else
2166 error "$(gettext "There is no key in your keyring.")"
2168 exit 1
2173 if (( ! SPLITPKG )); then
2174 fullver=$(get_full_version)
2175 if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \
2176 || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \
2177 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2178 if (( INSTALL )); then
2179 warning "$(gettext "A package has already been built, installing existing package...")"
2180 install_package
2181 exit $?
2182 else
2183 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2184 exit 1
2187 else
2188 allpkgbuilt=1
2189 somepkgbuilt=0
2190 for pkg in ${pkgname[@]}; do
2191 fullver=$(get_full_version $pkg)
2192 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \
2193 || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then
2194 somepkgbuilt=1
2195 else
2196 allpkgbuilt=0
2198 done
2199 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2200 if (( allpkgbuilt )); then
2201 if (( INSTALL )); then
2202 warning "$(gettext "The package group has already been built, installing existing packages...")"
2203 install_package
2204 exit $?
2205 else
2206 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2207 exit 1
2210 if (( somepkgbuilt )); then
2211 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2212 exit 1
2215 unset allpkgbuilt somepkgbuilt
2218 # Run the bare minimum in fakeroot
2219 if (( INFAKEROOT )); then
2220 if (( SOURCEONLY )); then
2221 create_srcpackage
2222 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2223 exit 0 # $E_OK
2226 if (( ! SPLITPKG )); then
2227 if (( ! PKGFUNC )); then
2228 if (( ! REPKG )); then
2229 if (( BUILDFUNC )); then
2230 run_build
2231 (( CHECKFUNC )) && run_check
2232 tidy_install
2234 else
2235 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2236 plain "$(gettext "File permissions may not be preserved.")"
2238 else
2239 run_package
2240 tidy_install
2242 create_package
2243 else
2244 run_split_packaging
2247 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2248 exit 0 # $E_OK
2251 fullver=$(get_full_version)
2252 msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2254 # if we are creating a source-only package, go no further
2255 if (( SOURCEONLY )); then
2256 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2257 && (( ! FORCE )); then
2258 error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2259 exit 1
2262 # Get back to our src directory so we can begin with sources.
2263 mkdir -p "$srcdir"
2264 chmod a-s "$srcdir"
2265 cd "$srcdir"
2266 if ( (( ! SKIPCHECKSUMS )) || \
2267 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \
2268 (( SOURCEONLY == 2 )); then
2269 download_sources
2271 check_source_integrity
2272 cd "$startdir"
2274 # if we are root or if fakeroot is not enabled, then we don't use it
2275 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2276 create_srcpackage
2277 else
2278 enter_fakeroot
2281 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2282 exit 0
2285 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
2286 # no warning message needed for nobuild, repkg
2287 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
2288 warning "$(gettext "Skipping dependency checks.")"
2290 elif type -p "${PACMAN%% *}" >/dev/null; then
2291 if (( RMDEPS )); then
2292 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2294 deperr=0
2296 msg "$(gettext "Checking runtime dependencies...")"
2297 resolve_deps ${depends[@]} || deperr=1
2299 msg "$(gettext "Checking buildtime dependencies...")"
2300 resolve_deps ${makedepends[@]} || deperr=1
2302 if (( CHECKFUNC )); then
2303 resolve_deps ${checkdepends[@]} || deperr=1
2306 if (( RMDEPS )); then
2307 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2310 if (( deperr )); then
2311 error "$(gettext "Could not resolve all dependencies.")"
2312 exit 1
2314 else
2315 warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
2318 # ensure we have a sane umask set
2319 umask 0022
2321 # get back to our src directory so we can begin with sources
2322 mkdir -p "$srcdir"
2323 chmod a-s "$srcdir"
2324 cd "$srcdir"
2326 if (( NOEXTRACT )); then
2327 warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
2328 warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
2329 warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
2331 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
2332 error "$(gettext "The source directory is empty, there is nothing to build!")"
2333 plain "$(gettext "Aborting...")"
2334 exit 1
2336 elif (( REPKG )); then
2337 if (( ! PKGFUNC && ! SPLITPKG )) \
2338 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
2339 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2340 plain "$(gettext "Aborting...")"
2341 exit 1
2343 else
2344 download_sources
2345 check_source_integrity
2346 extract_sources
2349 if (( NOBUILD )); then
2350 msg "$(gettext "Sources are ready.")"
2351 exit 0 #E_OK
2352 else
2353 # check for existing pkg directory; don't remove if we are repackaging
2354 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2355 msg "$(gettext "Removing existing %s directory...")" "pkg/"
2356 rm -rf "$pkgdir"
2358 mkdir -p "$pkgdir"
2359 chmod a-s "$pkgdir"
2360 cd "$startdir"
2362 # if we are root or if fakeroot is not enabled, then we don't use it
2363 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2364 if (( ! REPKG )); then
2365 devel_update
2366 (( BUILDFUNC )) && run_build
2367 (( CHECKFUNC )) && run_check
2369 if (( ! SPLITPKG )); then
2370 if (( PKGFUNC )); then
2371 run_package
2372 tidy_install
2373 else
2374 if (( ! REPKG )); then
2375 tidy_install
2376 else
2377 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2378 plain "$(gettext "File permissions may not be preserved.")"
2381 create_package
2382 else
2383 run_split_packaging
2385 else
2386 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2387 devel_update
2388 (( BUILDFUNC )) && run_build
2389 (( CHECKFUNC )) && run_check
2390 cd "$startdir"
2393 enter_fakeroot
2397 fullver=$(get_full_version)
2398 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
2400 install_package
2402 exit 0 #E_OK
2404 # vim: set ts=2 sw=2 noet: