makepkg: Be more consistent with missing program message
[pacman-ng.git] / scripts / makepkg.sh.in
blob10a0654dd853ad580c681d1db6873bf7d4963d38
1 #!/bin/bash
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'
39 # Ensure CDPATH doesn't screw with our cd calls
40 unset CDPATH
42 declare -r myver='@PACKAGE_VERSION@'
43 declare -r confdir='@sysconfdir@'
44 declare -r BUILDSCRIPT='@BUILDSCRIPT@'
45 declare -r startdir="$PWD"
47 packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx')
48 other_options=('ccache' 'distcc' 'buildflags' 'makeflags')
49 splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'license' \
50 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \
51 'replaces' 'backup' 'options' 'install' 'changelog')
52 readonly -a packaging_options other_options splitpkg_overrides
54 # Options
55 ASROOT=0
56 CLEANUP=0
57 DEP_BIN=0
58 FORCE=0
59 INFAKEROOT=0
60 GENINTEG=0
61 SKIPCHECKSUMS=0
62 SKIPPGPCHECK=0
63 INSTALL=0
64 NOBUILD=0
65 NODEPS=0
66 NOEXTRACT=0
67 RMDEPS=0
68 REPKG=0
69 LOGGING=0
70 SOURCEONLY=0
71 IGNOREARCH=0
72 HOLDVER=0
73 BUILDFUNC=0
74 CHECKFUNC=0
75 PKGFUNC=0
76 SPLITPKG=0
77 PKGLIST=()
78 SIGNPKG=''
80 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
81 # when dealing with svn/cvs/etc PKGBUILDs.
82 FORCE_VER=""
84 PACMAN_OPTS=
86 shopt -s extglob
88 ### SUBROUTINES ###
90 plain() {
91 local mesg=$1; shift
92 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
95 msg() {
96 local mesg=$1; shift
97 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
100 msg2() {
101 local mesg=$1; shift
102 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
105 warning() {
106 local mesg=$1; shift
107 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
110 error() {
111 local mesg=$1; shift
112 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
117 # Special exit call for traps, Don't print any error messages when inside,
118 # the fakeroot call, the error message will be printed by the main call.
120 trap_exit() {
121 local signal=$1; shift
123 if (( ! INFAKEROOT )); then
124 echo
125 error "$@"
127 [[ -n $srclinks ]] && rm -rf "$srclinks"
129 # unset the trap for this signal, and then call the default handler
130 trap -- "$signal"
131 kill "-$signal" "$$"
136 # Clean up function. Called automatically when the script exits.
138 clean_up() {
139 local EXIT_CODE=$?
141 if (( INFAKEROOT )); then
142 # Don't clean up when leaving fakeroot, we're not done yet.
143 return
146 if (( ! EXIT_CODE && CLEANUP )); then
147 local pkg file
149 # If it's a clean exit and -c/--clean has been passed...
150 msg "$(gettext "Cleaning up...")"
151 rm -rf "$pkgdir" "$srcdir"
152 if [[ -n $pkgbase ]]; then
153 local fullver=$(get_full_version)
154 # Can't do this unless the BUILDSCRIPT has been sourced.
155 if (( BUILDFUNC )); then
156 rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
158 if (( CHECKFUNC )); then
159 rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
161 if (( PKGFUNC )); then
162 rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
163 elif (( SPLITPKG )); then
164 for pkg in ${pkgname[@]}; do
165 rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
166 done
169 # clean up dangling symlinks to packages
170 for pkg in ${pkgname[@]}; do
171 for file in ${pkg}-*-*-*{${PKGEXT},${SRCEXT}}; do
172 if [[ -h $file && ! -e $file ]]; then
173 rm -f "$file"
175 done
176 done
180 remove_deps
184 enter_fakeroot() {
185 msg "$(gettext "Entering %s environment...")" "fakeroot"
187 if [[ -n $newpkgver ]]; then
188 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
189 else
190 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
195 # a source entry can have two forms :
196 # 1) "filename::http://path/to/file"
197 # 2) "http://path/to/file"
199 # Return the absolute filename of a source entry
201 # This function accepts a source entry or the already extracted filename of a
202 # source entry as input
203 get_filepath() {
204 local file="$(get_filename "$1")"
206 if [[ -f "$startdir/$file" ]]; then
207 file="$startdir/$file"
208 elif [[ -f "$SRCDEST/$file" ]]; then
209 file="$SRCDEST/$file"
210 else
211 return 1
214 printf "%s\n" "$file"
217 # Print 'source not found' error message and exit makepkg
218 missing_source_file() {
219 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
220 plain "$(gettext "Aborting...")"
221 exit 1 # $E_MISSING_FILE
224 # extract the filename from a source entry
225 get_filename() {
226 # if a filename is specified, use it
227 local filename="${1%%::*}"
228 # if it is just an URL, we only keep the last component
229 printf "%s\n" "${filename##*/}"
232 # extract the URL from a source entry
233 get_url() {
234 # strip an eventual filename
235 printf "%s\n" "${1#*::}"
239 # usage : get_full_version( [$pkgname] )
240 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
242 get_full_version() {
243 if [[ -z $1 ]]; then
244 if [[ $epoch ]] && (( ! $epoch )); then
245 printf "%s\n" "$pkgver-$pkgrel"
246 else
247 printf "%s\n" "$epoch:$pkgver-$pkgrel"
249 else
250 for i in pkgver pkgrel epoch; do
251 local indirect="${i}_override"
252 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
253 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
254 done
255 if (( ! $epoch_override )); then
256 printf "%s\n" "$pkgver_override-$pkgrel_override"
257 else
258 printf "%s\n" "$epoch_override:$pkgver_override-$pkgrel_override"
264 # usage : get_pkg_arch( [$pkgname] )
265 # return : architecture of the package
267 get_pkg_arch() {
268 if [[ -z $1 ]]; then
269 if [[ $arch = "any" ]]; then
270 printf "%s\n" "any"
271 else
272 printf "%s\n" "$CARCH"
274 else
275 local arch_override
276 eval $(declare -f package_$1 | sed -n 's/\(^[[:space:]]*arch=\)/arch_override=/p')
277 if [[ $arch_override = "any" ]]; then
278 printf "%s\n" "any"
279 else
280 printf "%s\n" "$CARCH"
286 # Checks to see if options are present in makepkg.conf or PKGBUILD;
287 # PKGBUILD options always take precedence.
289 # usage : check_option( $option )
290 # return : y - enabled
291 # n - disabled
292 # ? - not found
294 check_option() {
295 local ret=$(in_opt_array "$1" ${options[@]})
296 if [[ $ret != '?' ]]; then
297 printf "%s\n" "$ret"
298 return
301 # fall back to makepkg.conf options
302 ret=$(in_opt_array "$1" ${OPTIONS[@]})
303 if [[ $ret != '?' ]]; then
304 printf "%s\n" "$ret"
305 return
308 echo '?' # Not Found
313 # Check if option is present in BUILDENV
315 # usage : check_buildenv( $option )
316 # return : y - enabled
317 # n - disabled
318 # ? - not found
320 check_buildenv() {
321 in_opt_array "$1" ${BUILDENV[@]}
326 # usage : in_opt_array( $needle, $haystack )
327 # return : y - enabled
328 # n - disabled
329 # ? - not found
331 in_opt_array() {
332 local needle=$1; shift
334 local opt
335 for opt in "$@"; do
336 if [[ $opt = "$needle" ]]; then
337 echo 'y' # Enabled
338 return
339 elif [[ $opt = "!$needle" ]]; then
340 echo 'n' # Disabled
341 return
343 done
345 echo '?' # Not Found
350 # usage : in_array( $needle, $haystack )
351 # return : 0 - found
352 # 1 - not found
354 in_array() {
355 local needle=$1; shift
356 local item
357 for item in "$@"; do
358 [[ $item = "$needle" ]] && return 0 # Found
359 done
360 return 1 # Not Found
363 source_has_signatures() {
364 local file
365 for file in "${source[@]}"; do
366 if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then
367 return 0
369 done
370 return 1
373 get_downloadclient() {
374 # $1 = URL with valid protocol prefix
375 local url=$1
376 local proto="${url%%://*}"
378 # loop through DOWNLOAD_AGENTS variable looking for protocol
379 local i
380 for i in "${DLAGENTS[@]}"; do
381 local handler="${i%%::*}"
382 if [[ $proto = "$handler" ]]; then
383 local agent="${i##*::}"
384 break
386 done
388 # if we didn't find an agent, return an error
389 if [[ -z $agent ]]; then
390 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
391 plain "$(gettext "Aborting...")"
392 exit 1 # $E_CONFIG_ERROR
395 # ensure specified program is installed
396 local program="${agent%% *}"
397 if [[ ! -x $program ]]; then
398 local baseprog="${program##*/}"
399 error "$(gettext "The download program %s is not installed.")" "$baseprog"
400 plain "$(gettext "Aborting...")"
401 exit 1 # $E_MISSING_PROGRAM
404 printf "%s\n" "$agent"
407 download_file() {
408 # download command
409 local dlcmd=$1
410 # URL of the file
411 local url=$2
412 # destination file
413 local file=$3
414 # temporary download file, default to last component of the URL
415 local dlfile="${url##*/}"
417 # replace %o by the temporary dlfile if it exists
418 if [[ $dlcmd = *%o* ]]; then
419 dlcmd=${dlcmd//\%o/\"$file.part\"}
420 dlfile="$file.part"
422 # add the URL, either in place of %u or at the end
423 if [[ $dlcmd = *%u* ]]; then
424 dlcmd=${dlcmd//\%u/\"$url\"}
425 else
426 dlcmd="$dlcmd \"$url\""
429 local ret=0
430 eval "$dlcmd || ret=\$?"
431 if (( ret )); then
432 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
433 return $ret
436 # rename the temporary download file to the final destination
437 if [[ $dlfile != "$file" ]]; then
438 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
442 run_pacman() {
443 local cmd
444 if [[ ! $1 = -@(T|Qq) ]]; then
445 cmd=("$PACMAN" $PACMAN_OPTS "$@")
446 else
447 cmd=("$PACMAN" "$@")
449 if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
450 if type -p sudo >/dev/null; then
451 cmd=(sudo "${cmd[@]}")
452 else
453 cmd=(su root -c "$(printf '%q ' "${cmd[@]}")")
456 "${cmd[@]}"
459 check_deps() {
460 (( $# > 0 )) || return 0
462 local ret=0
463 local pmout
464 pmout=$(run_pacman -T "$@")
465 ret=$?
467 if (( ret == 127 )); then #unresolved deps
468 printf "%s\n" "$pmout"
469 elif (( ret )); then
470 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
471 return "$ret"
475 handle_deps() {
476 local R_DEPS_SATISFIED=0
477 local R_DEPS_MISSING=1
479 (( $# == 0 )) && return $R_DEPS_SATISFIED
481 local deplist="$*"
483 if (( ! DEP_BIN )); then
484 return $R_DEPS_MISSING
487 if (( DEP_BIN )); then
488 # install missing deps from binary packages (using pacman -S)
489 msg "$(gettext "Installing missing dependencies...")"
491 if ! run_pacman -S --asdeps $deplist; then
492 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
493 exit 1 # TODO: error code
497 # we might need the new system environment
498 # save our shell options and turn off extglob
499 local shellopts=$(shopt -p)
500 shopt -u extglob
501 source /etc/profile &>/dev/null
502 eval "$shellopts"
504 return $R_DEPS_SATISFIED
507 resolve_deps() {
508 local R_DEPS_SATISFIED=0
509 local R_DEPS_MISSING=1
511 # deplist cannot be declared like this: local deplist=$(foo)
512 # Otherwise, the return value will depend on the assignment.
513 local deplist
514 deplist="$(set +E; check_deps $*)" || exit 1
515 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
517 if handle_deps $deplist; then
518 # check deps again to make sure they were resolved
519 deplist="$(set +E; check_deps $*)" || exit 1
520 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
523 msg "$(gettext "Missing Dependencies:")"
524 local dep
525 for dep in $deplist; do
526 msg2 "$dep"
527 done
529 return $R_DEPS_MISSING
532 remove_deps() {
533 (( ! RMDEPS )) && return
535 # check for packages removed during dependency install (e.g. due to conflicts)
536 # removing all installed packages is risky in this case
537 if [[ -n $(grep -xvFf <(printf '%s\n' "${current_packagelist[@]}") \
538 <(printf '%s\n' "${original_packagelist[@]}") || true) ]]; then
539 warning "$(gettext "Failed to remove installed dependencies.")"
540 return 0
543 local deplist
544 deplist=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
545 <(printf "%s\n" "${current_pkglist[@]}") || true))
546 if [[ -z $deplist ]]; then
547 return
550 msg "Removing installed dependencies..."
551 # exit cleanly on failure to remove deps as package has been built successfully
552 if ! run_pacman -Rn ${deplist[@]}; then
553 warning "$(gettext "Failed to remove installed dependencies.")"
554 return 0
558 download_sources() {
559 msg "$(gettext "Retrieving Sources...")"
561 pushd "$SRCDEST" &>/dev/null
563 local netfile
564 for netfile in "${source[@]}"; do
565 local file=$(get_filepath "$netfile" || true)
566 if [[ -n "$file" ]]; then
567 msg2 "$(gettext "Found %s")" "${file##*/}"
568 rm -f "$srcdir/${file##*/}"
569 ln -s "$file" "$srcdir/"
570 continue
573 file=$(get_filename "$netfile")
574 local url=$(get_url "$netfile")
576 # if we get here, check to make sure it was a URL, else fail
577 if [[ $file = "$url" ]]; then
578 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
579 exit 1 # $E_MISSING_FILE
582 # find the client we should use for this URL
583 local dlclient
584 dlclient=$(get_downloadclient "$url") || exit $?
586 msg2 "$(gettext "Downloading %s...")" "$file"
587 # fix flyspray bug #3289
588 local ret=0
589 download_file "$dlclient" "$url" "$file" || ret=$?
590 if (( ret )); then
591 error "$(gettext "Failure while downloading %s")" "$file"
592 plain "$(gettext "Aborting...")"
593 exit 1
595 rm -f "$srcdir/$file"
596 ln -s "$SRCDEST/$file" "$srcdir/"
597 done
599 popd &>/dev/null
602 get_integlist() {
603 local integ
604 local integlist=()
606 for integ in md5 sha1 sha256 sha384 sha512; do
607 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
608 if [[ -n "$integrity_sums" ]]; then
609 integlist=(${integlist[@]} $integ)
611 done
613 if (( ${#integlist[@]} > 0 )); then
614 printf "%s\n" "${integlist[@]}"
615 else
616 printf "%s\n" "${INTEGRITY_CHECK[@]}"
620 generate_checksums() {
621 msg "$(gettext "Generating checksums for source files...")"
622 plain ""
624 if ! type -p openssl >/dev/null; then
625 error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
626 exit 1 # $E_MISSING_PROGRAM
629 local integlist
630 if (( $# == 0 )); then
631 integlist=$(get_integlist)
632 else
633 integlist=$@
636 local integ
637 for integ in ${integlist[@]}; do
638 case "$integ" in
639 md5|sha1|sha256|sha384|sha512) : ;;
641 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
642 exit 1;; # $E_CONFIG_ERROR
643 esac
645 local ct=0
646 local numsrc=${#source[@]}
647 printf "%s" "${integ}sums=("
649 local i
650 local indent=''
651 for (( i = 0; i < ${#integ} + 6; i++ )); do
652 indent="$indent "
653 done
655 local netfile
656 for netfile in "${source[@]}"; do
657 local file
658 file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
659 local sum="$(openssl dgst -${integ} "$file")"
660 sum=${sum##* }
661 (( ct )) && printf "%s" "$indent"
662 printf "%s" "'$sum'"
663 ct=$(($ct+1))
664 (( $ct < $numsrc )) && echo
665 done
667 echo ")"
668 done
671 check_checksums() {
672 (( SKIPCHECKSUMS )) && return 0
673 (( ! ${#source[@]} )) && return 0
675 local correlation=0
676 local integ required
677 for integ in md5 sha1 sha256 sha384 sha512; do
678 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
679 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
680 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
681 correlation=1
682 local errors=0
683 local idx=0
684 local file
685 for file in "${source[@]}"; do
686 local found=1
687 file="$(get_filename "$file")"
688 printf "%s" " $file ... " >&2
690 if ! file="$(get_filepath "$file")"; then
691 printf -- "$(gettext "NOT FOUND")\n" >&2
692 errors=1
693 found=0
696 if (( $found )) ; then
697 if [[ ${integrity_sums[$idx]} = 'SKIP' ]]; then
698 echo "$(gettext "Skipped")" >&2
699 else
700 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
701 local realsum="$(openssl dgst -${integ} "$file")"
702 realsum="${realsum##* }"
703 if [[ $expectedsum = "$realsum" ]]; then
704 printf -- "$(gettext "Passed")\n" >&2
705 else
706 printf -- "$(gettext "FAILED")\n" >&2
707 errors=1
712 idx=$((idx + 1))
713 done
715 if (( errors )); then
716 error "$(gettext "One or more files did not pass the validity check!")"
717 exit 1 # TODO: error code
719 elif (( ${#integrity_sums[@]} )); then
720 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
721 exit 1 # TODO: error code
723 done
725 if (( ! correlation )); then
726 error "$(gettext "Integrity checks are missing.")"
727 exit 1 # TODO: error code
731 check_pgpsigs() {
732 (( SKIPPGPCHECK )) && return 0
733 ! source_has_signatures && return 0
735 msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
737 local file pubkey
738 local warning=0
739 local errors=0
740 local statusfile=$(mktemp)
742 for file in "${source[@]}"; do
743 file="$(get_filename "$file")"
744 if [[ ! $file = *.@(sig?(n)|asc) ]]; then
745 continue
748 printf " %s ... " "${file%.*}" >&2
750 if ! file="$(get_filepath "$file")"; then
751 printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
752 errors=1
753 continue
756 if ! sourcefile="$(get_filepath "${file%.*}")"; then
757 printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
758 errors=1
759 continue
762 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
763 printf '%s' "$(gettext "FAILED")" >&2
764 if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
765 printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
766 warnings=1
767 else
768 errors=1
770 printf '\n' >&2
771 else
772 if grep -q "REVKEYSIG" "$statusfile"; then
773 printf '%s (%s)' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
774 errors=1
775 else
776 printf '%s' "$(gettext "Passed")" >&2
777 if grep -q "EXPSIG" "$statusfile"; then
778 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
779 warnings=1
780 elif grep -q "EXPKEYSIG" "$statusfile"; then
781 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
782 warnings=1
785 printf '\n' >&2
787 done
789 rm -f "$statusfile"
791 if (( errors )); then
792 error "$(gettext "One or more PGP signatures could not be verified!")"
793 exit 1
796 if (( warnings )); then
797 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
798 plain "$(gettext "Please make sure you really trust them.")"
802 check_source_integrity() {
803 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
804 warning "$(gettext "Skipping all source file integrity checks.")"
805 elif (( SKIPCHECKSUMS )); then
806 warning "$(gettext "Skipping verification of source file checksums.")"
807 check_pgpsigs
808 elif (( SKIPPGPCHECK )); then
809 warning "$(gettext "Skipping verification of source file PGP signatures.")"
810 check_checksums
811 else
812 check_checksums
813 check_pgpsigs
817 extract_sources() {
818 msg "$(gettext "Extracting Sources...")"
819 local netfile
820 for netfile in "${source[@]}"; do
821 local file=$(get_filename "$netfile")
822 if in_array "$file" "${noextract[@]}"; then
823 #skip source files in the noextract=() array
824 # these are marked explicitly to NOT be extracted
825 continue
829 # fix flyspray #6246
830 local file_type=$(file -bizL "$file")
831 local ext=${file##*.}
832 local cmd=''
833 case "$file_type" in
834 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
835 cmd="bsdtar" ;;
836 *application/x-gzip*)
837 case "$ext" in
838 gz|z|Z) cmd="gzip" ;;
839 *) continue;;
840 esac ;;
841 *application/x-bzip*)
842 case "$ext" in
843 bz2|bz) cmd="bzip2" ;;
844 *) continue;;
845 esac ;;
846 *application/x-xz*)
847 case "$ext" in
848 xz) cmd="xz" ;;
849 *) continue;;
850 esac ;;
852 # See if bsdtar can recognize the file
853 if bsdtar -tf "$file" -q '*' &>/dev/null; then
854 cmd="bsdtar"
855 else
856 continue
857 fi ;;
858 esac
860 local ret=0
861 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
862 if [[ $cmd = "bsdtar" ]]; then
863 $cmd -xf "$file" || ret=$?
864 else
865 rm -f -- "${file%.*}"
866 $cmd -dcf "$file" > "${file%.*}" || ret=$?
868 if (( ret )); then
869 error "$(gettext "Failed to extract %s")" "$file"
870 plain "$(gettext "Aborting...")"
871 exit 1
873 done
875 if (( EUID == 0 )); then
876 # change perms of all source files to root user & root group
877 chown -R 0:0 "$srcdir"
881 error_function() {
882 if [[ -p $logpipe ]]; then
883 rm "$logpipe"
885 # first exit all subshells, then print the error
886 if (( ! BASH_SUBSHELL )); then
887 error "$(gettext "A failure occurred in %s().")" "$1"
888 plain "$(gettext "Aborting...")"
889 remove_deps
891 exit 2 # $E_BUILD_FAILED
894 cd_safe() {
895 if ! cd "$1"; then
896 error "$(gettext "Failed to change to directory %s")" "$1"
897 plain "$(gettext "Aborting...")"
898 exit 1
902 source_safe() {
903 shopt -u extglob
904 if ! source "$@"; then
905 error "$(gettext "Failed to source %s")" "$1"
906 exit 1
908 shopt -s extglob
911 run_function_safe() {
912 local restoretrap
914 set -e
915 set -E
917 restoretrap=$(trap -p ERR)
918 trap 'error_function $pkgfunc' ERR
920 run_function "$1"
922 eval $restoretrap
924 set +E
925 set +e
928 run_function() {
929 if [[ -z $1 ]]; then
930 return 1
932 local pkgfunc="$1"
934 # clear user-specified buildflags if requested
935 if [[ $(check_option buildflags) = "n" ]]; then
936 unset CFLAGS CXXFLAGS LDFLAGS
939 # clear user-specified makeflags if requested
940 if [[ $(check_option makeflags) = "n" ]]; then
941 unset MAKEFLAGS
944 msg "$(gettext "Starting %s()...")" "$pkgfunc"
945 cd_safe "$srcdir"
947 # ensure all necessary build variables are exported
948 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
949 # save our shell options so pkgfunc() can't override what we need
950 local shellopts=$(shopt -p)
952 local ret=0
953 if (( LOGGING )); then
954 local fullver=$(get_full_version)
955 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
956 if [[ -f $BUILDLOG ]]; then
957 local i=1
958 while true; do
959 if [[ -f $BUILDLOG.$i ]]; then
960 i=$(($i +1))
961 else
962 break
964 done
965 mv "$BUILDLOG" "$BUILDLOG.$i"
968 # ensure overridden package variables survive tee with split packages
969 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
970 mkfifo "$logpipe"
971 tee "$BUILDLOG" < "$logpipe" &
972 local teepid=$!
974 $pkgfunc &>"$logpipe"
976 wait $teepid
977 rm "$logpipe"
978 else
979 $pkgfunc 2>&1
981 # reset our shell options
982 eval "$shellopts"
985 run_build() {
986 # use distcc if it is requested (check buildenv and PKGBUILD opts)
987 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
988 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
989 export DISTCC_HOSTS
992 # use ccache if it is requested (check buildenv and PKGBUILD opts)
993 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
994 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
997 run_function_safe "build"
1000 run_check() {
1001 run_function_safe "check"
1004 run_package() {
1005 local pkgfunc
1006 if [[ -z $1 ]]; then
1007 pkgfunc="package"
1008 else
1009 pkgfunc="package_$1"
1012 run_function_safe "$pkgfunc"
1015 tidy_install() {
1016 cd_safe "$pkgdir"
1017 msg "$(gettext "Tidying install...")"
1019 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
1020 msg2 "$(gettext "Removing doc files...")"
1021 rm -rf -- ${DOC_DIRS[@]}
1024 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
1025 msg2 "$(gettext "Purging unwanted files...")"
1026 local pt
1027 for pt in "${PURGE_TARGETS[@]}"; do
1028 if [[ ${pt} = "${pt//\/}" ]]; then
1029 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
1030 else
1031 rm -f ${pt}
1033 done
1036 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
1037 msg2 "$(gettext "Compressing man and info pages...")"
1038 local manpage ext file link hardlinks hl
1039 find ${MAN_DIRS[@]} -type f 2>/dev/null |
1040 while read manpage ; do
1041 ext="${manpage##*.}"
1042 file="${manpage##*/}"
1043 if [[ $ext != gz && $ext != bz2 ]]; then
1044 # update symlinks to this manpage
1045 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
1046 while read link ; do
1047 rm -f "$link" "${link}.gz"
1048 ln -s -- "${file}.gz" "${link}.gz"
1049 done
1051 # check file still exists (potentially already compressed due to hardlink)
1052 if [[ -f ${manpage} ]]; then
1053 # find hard links and remove them
1054 # the '|| true' part keeps the script from bailing on the EOF returned
1055 # by read at the end of the find output
1056 IFS=$'\n' read -rd '' -a hardlinks < \
1057 <(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" \
1058 2>/dev/null || true) || true
1059 rm -f "${hardlinks[@]}"
1060 # compress the original
1061 gzip -9 "$manpage"
1062 # recreate hard links removed earlier
1063 for hl in "${hardlinks[@]}"; do
1064 ln "${manpage}.gz" "${hl}.gz"
1065 chmod 644 ${hl}.gz
1066 done
1069 done
1072 if [[ $(check_option strip) = "y" ]]; then
1073 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1074 # make sure library stripping variables are defined to prevent excess stripping
1075 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1076 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1077 local binary
1078 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1079 case "$(file -bi "$binary")" in
1080 *application/x-sharedlib*) # Libraries (.so)
1081 strip $STRIP_SHARED "$binary";;
1082 *application/x-archive*) # Libraries (.a)
1083 strip $STRIP_STATIC "$binary";;
1084 *application/x-executable*) # Binaries
1085 strip $STRIP_BINARIES "$binary";;
1086 esac
1087 done
1090 if [[ $(check_option libtool) = "n" ]]; then
1091 msg2 "$(gettext "Removing "%s" files...")" "libtool"
1092 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
1095 if [[ $(check_option emptydirs) = "n" ]]; then
1096 msg2 "$(gettext "Removing empty directories...")"
1097 find . -depth -type d -empty -delete
1100 if [[ $(check_option upx) = "y" ]]; then
1101 msg2 "$(gettext "Compressing binaries with %s...")" "UPX"
1102 local binary
1103 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1104 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1105 upx $UPXFLAGS "$binary" &>/dev/null ||
1106 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1108 done
1112 find_libdepends() {
1113 local libdepends
1114 find "$pkgdir" -type f -perm -u+x | while read filename
1116 # get architecture of the file; if soarch is empty it's not an ELF binary
1117 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1118 [ -n "$soarch" ] || continue
1119 # process all libraries needed by the binary
1120 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1122 # extract the library name: libfoo.so
1123 soname="${sofile%.so?(+(.+([0-9])))}".so
1124 # extract the major version: 1
1125 soversion="${sofile##*\.so\.}"
1126 if in_array "${soname}" ${depends[@]}; then
1127 if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then
1128 # libfoo.so=1-64
1129 printf "%s" "${soname}=${soversion}-${soarch}"
1130 libdepends+=("${soname}=${soversion}-${soarch}")
1133 done
1134 done
1137 find_libprovides() {
1138 local libprovides missing
1139 for p in "${provides[@]}"; do
1140 missing=0
1141 case "$p" in
1142 *.so)
1143 IFS=$'\n' read -rd '' -a filename < <(find "$pkgdir" -type f -name $p\*)
1144 if [[ $filename ]]; then
1145 # packages may provide multiple versions of the same library
1146 for fn in "${filename[@]}"; do
1147 # check if we really have a shared object
1148 if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1149 # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
1150 local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1151 if [[ -z "$sofile" ]]; then
1152 warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
1153 libprovides+=("$p")
1154 continue
1157 # get the library architecture (32 or 64 bit)
1158 local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1160 # extract the library major version
1161 local soversion="${sofile##*\.so\.}"
1163 libprovides+=("${p}=${soversion}-${soarch}")
1164 else
1165 warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
1166 libprovides+=("$p")
1168 done
1169 else
1170 libprovides+=("$p")
1171 missing=1
1175 libprovides+=("$p")
1177 esac
1179 if (( missing )); then
1180 warning "$(gettext "Can not find library listed in %s: %s")" "'provides'" "$p"
1182 done
1184 printf '%s\n' "${libprovides[@]}"
1187 check_license() {
1188 # TODO maybe remove this at some point
1189 # warn if license array is not present or empty
1190 if [[ -z $license ]]; then
1191 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1192 plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
1196 write_pkginfo() {
1197 local builddate=$(date -u "+%s")
1198 if [[ -n $PACKAGER ]]; then
1199 local packager="$PACKAGER"
1200 else
1201 local packager="Unknown Packager"
1204 # btrfs's delayed allocation causes the stat buffers from the kernel to "lie"
1205 # to us momentarily and report 0 blocks allocated (which is how du calculates
1206 # size). Sleeping for a second here is about the dirtiest thing possible,
1207 # but avoids reporting entirely bogus install sizes.
1208 sleep 1
1209 local size="$(@DUPATH@ -sk)"
1210 size="$(( ${size%%[^0-9]*} * 1024 ))"
1212 msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
1213 echo "# Generated by makepkg $myver"
1214 if (( INFAKEROOT )); then
1215 echo "# using $(fakeroot -v)"
1217 echo "# $(LC_ALL=C date -u)"
1218 printf "pkgname = %s\n" "$1"
1219 (( SPLITPKG )) && echo pkgbase = $pkgbase
1220 echo "pkgver = $(get_full_version)"
1221 printf "pkgdesc = %s\n" "$pkgdesc"
1222 printf "url = %s\n" "$url"
1223 printf "builddate = %s\n" "$builddate"
1224 printf "packager = %s\n" "$packager"
1225 printf "size = %s\n" "$size"
1226 printf "arch = %s\n" "$pkgarch"
1228 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1229 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1230 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1231 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
1232 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1234 IFS=$'\n' read -rd '' -a provides < <(find_libprovides)
1235 [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
1237 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1240 local it
1241 IFS=$'\n' read -rd '' -a libdepends < <(find_libdepends)
1242 depends+=("${libdepends[@]}")
1244 for it in "${depends[@]}"; do
1245 if [[ $it = *.so ]]; then
1246 # check if the entry has been found by find_libdepends
1247 # if not, it's unneeded; tell the user so he can remove it
1248 printf -v re '(^|\s)%s=.*' "$it"
1249 if [[ ! $libdepends =~ $re ]]; then
1250 error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it"
1251 return 1
1253 else
1254 printf "depend = %s\n" "$it"
1256 done
1258 for it in "${packaging_options[@]}"; do
1259 local ret="$(check_option $it)"
1260 if [[ $ret != "?" ]]; then
1261 if [[ $ret = "y" ]]; then
1262 printf "makepkgopt = %s\n" "$it"
1263 else
1264 printf "makepkgopt = %s\n" "!$it"
1267 done
1269 check_license
1272 check_package() {
1273 cd_safe "$pkgdir"
1275 # check existence of backup files
1276 local file
1277 for file in "${backup[@]}"; do
1278 if [[ ! -f $file ]]; then
1279 warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
1281 done
1283 # check for references to the build and package directory
1284 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1285 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
1287 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
1288 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
1293 create_package() {
1294 if [[ ! -d $pkgdir ]]; then
1295 error "$(gettext "Missing %s directory.")" "pkg/"
1296 plain "$(gettext "Aborting...")"
1297 exit 1 # $E_MISSING_PKGDIR
1300 check_package
1302 cd_safe "$pkgdir"
1303 msg "$(gettext "Creating package...")"
1305 local nameofpkg
1306 if [[ -z $1 ]]; then
1307 nameofpkg="$pkgname"
1308 else
1309 nameofpkg="$1"
1312 pkgarch=$(get_pkg_arch)
1314 write_pkginfo $nameofpkg > .PKGINFO
1316 local comp_files=('.PKGINFO')
1318 # check for changelog/install files
1319 for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1320 IFS='/' read -r orig dest < <(printf '%s\n' "$i")
1322 if [[ -n ${!orig} ]]; then
1323 msg2 "$(gettext "Adding %s file...")" "$orig"
1324 cp "$startdir/${!orig}" "$dest"
1325 chmod 644 "$dest"
1326 comp_files+=("$dest")
1328 done
1330 # tar it up
1331 msg2 "$(gettext "Compressing package...")"
1333 local fullver=$(get_full_version)
1334 local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${pkgarch}${PKGEXT}"
1335 local ret=0
1337 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1338 [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
1340 # when fileglobbing, we want * in an empty directory to expand to
1341 # the null string rather than itself
1342 shopt -s nullglob
1343 # TODO: Maybe this can be set globally for robustness
1344 shopt -s -o pipefail
1345 # bsdtar's gzip compression always saves the time stamp, making one
1346 # archive created using the same command line distinct from another.
1347 # Disable bsdtar compression and use gzip -n for now.
1348 bsdtar -cf - "${comp_files[@]}" * |
1349 case "$PKGEXT" in
1350 *tar.gz) ${COMPRESSGZ[@]:-gzip -c -f -n} ;;
1351 *tar.bz2) ${COMPRESSBZ2[@]:-bzip2 -c -f} ;;
1352 *tar.xz) ${COMPRESSXZ[@]:-xz -c -z -} ;;
1353 *tar.Z) ${COMPRESSZ[@]:-compress -c -f} ;;
1354 *tar) cat ;;
1355 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1356 "$PKGEXT"; cat ;;
1357 esac > "${pkg_file}" || ret=$?
1359 shopt -u nullglob
1360 shopt -u -o pipefail
1362 if (( ret )); then
1363 error "$(gettext "Failed to create package file.")"
1364 exit 1 # TODO: error code
1367 create_signature "$pkg_file"
1369 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1370 rm -f "${pkg_file/$PKGDEST/$startdir}"
1371 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1372 ret=$?
1373 if [[ -f $pkg_file.sig ]]; then
1374 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1375 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1379 if (( ret )); then
1380 warning "$(gettext "Failed to create symlink to package file.")"
1384 create_signature() {
1385 if [[ $SIGNPKG != 'y' ]]; then
1386 return
1388 local ret=0
1389 local filename="$1"
1390 msg "$(gettext "Signing package...")"
1392 local SIGNWITHKEY=""
1393 if [[ -n $GPGKEY ]]; then
1394 SIGNWITHKEY="-u ${GPGKEY}"
1396 # The signature will be generated directly in ascii-friendly format
1397 gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
1400 if (( ! ret )); then
1401 msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
1402 else
1403 warning "$(gettext "Failed to sign package file.")"
1407 create_srcpackage() {
1408 local ret=0
1409 msg "$(gettext "Creating source package...")"
1410 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1411 mkdir "${srclinks}"/${pkgbase}
1413 check_license
1415 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1416 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1418 local file
1419 for file in "${source[@]}"; do
1420 if [[ "$file" = "$(get_filename "$file")" ]] || (( SOURCEONLY == 2 )); then
1421 local absfile
1422 absfile=$(get_filepath "$file") || missing_source_file "$file"
1423 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1424 ln -s "$absfile" "$srclinks/$pkgbase"
1426 done
1428 local i
1429 for i in 'changelog' 'install'; do
1430 local file
1431 while read -r file; do
1432 # evaluate any bash variables used
1433 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1434 if [[ $file && ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1435 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1436 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1438 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1439 done
1441 local TAR_OPT
1442 case "$SRCEXT" in
1443 *tar.gz) TAR_OPT="z" ;;
1444 *tar.bz2) TAR_OPT="j" ;;
1445 *tar.xz) TAR_OPT="J" ;;
1446 *tar.Z) TAR_OPT="Z" ;;
1447 *tar) TAR_OPT="" ;;
1448 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1449 "$SRCEXT" ;;
1450 esac
1452 local fullver=$(get_full_version)
1453 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1455 # tar it up
1456 msg2 "$(gettext "Compressing source package...")"
1457 cd_safe "${srclinks}"
1458 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1459 error "$(gettext "Failed to create source package file.")"
1460 exit 1 # TODO: error code
1463 if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1464 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1465 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1466 ret=$?
1469 if (( ret )); then
1470 warning "$(gettext "Failed to create symlink to source package file.")"
1473 cd_safe "${startdir}"
1474 rm -rf "${srclinks}"
1477 install_package() {
1478 (( ! INSTALL )) && return
1480 if (( ! SPLITPKG )); then
1481 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1482 else
1483 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1486 local fullver pkgarch pkg pkglist
1487 for pkg in ${pkgname[@]}; do
1488 fullver=$(get_full_version $pkg)
1489 pkgarch=$(get_pkg_arch $pkg)
1490 pkglist+=("$PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT}")
1491 done
1493 if ! run_pacman -U ${pkglist[@]}; then
1494 warning "$(gettext "Failed to install built package(s).")"
1495 return 0
1499 check_sanity() {
1500 # check for no-no's in the build script
1501 local i
1502 local ret=0
1503 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1504 if [[ -z ${!i} ]]; then
1505 error "$(gettext "%s is not allowed to be empty.")" "$i"
1506 ret=1
1508 done
1510 for i in "${pkgname[@]}"; do
1511 if [[ ${i:0:1} = "-" ]]; then
1512 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1513 ret=1
1515 if [[ $i = *[^[:alnum:]+_.@-]* ]]; then
1516 error "$(gettext "%s contains invalid characters: '%s'")" \
1517 'pkgname' "${pkgname//[[:alnum:]+_.@-]}"
1518 ret=1
1520 done
1522 if [[ ${pkgbase:0:1} = "-" ]]; then
1523 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1524 ret=1
1527 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1528 while IFS='=' read -r _ i; do
1529 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1530 if [[ $i = *[[:space:]:-]* ]]; then
1531 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1532 return 1
1534 done || ret=1
1536 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1537 while IFS='=' read -r _ i; do
1538 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1539 if [[ $i != +([0-9])?(.+([0-9])) ]]; then
1540 error "$(gettext "%s must be a decimal.")" "pkgrel"
1541 return 1
1543 done || ret=1
1545 awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
1546 while IFS='=' read -r _ i; do
1547 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1548 if [[ $i != *([[:digit:]]) ]]; then
1549 error "$(gettext "%s must be an integer.")" "epoch"
1550 return 1
1552 done || ret=1
1554 if [[ $arch != 'any' ]]; then
1555 if ! in_array $CARCH ${arch[@]}; then
1556 if (( ! IGNOREARCH )); then
1557 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1558 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1559 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1560 ret=1
1565 if (( ${#pkgname[@]} > 1 )); then
1566 for i in ${pkgname[@]}; do
1567 local arch_list=""
1568 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1569 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1570 if ! in_array $CARCH ${arch_list[@]}; then
1571 if (( ! IGNOREARCH )); then
1572 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1573 ret=1
1577 done
1580 local provides_list=()
1581 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1582 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1583 for i in ${provides_list[@]}; do
1584 if [[ $i == *['<>']* ]]; then
1585 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1586 ret=1
1588 done
1590 local backup_list=()
1591 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1592 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1593 for i in "${backup_list[@]}"; do
1594 if [[ ${i:0:1} = "/" ]]; then
1595 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1596 ret=1
1598 done
1600 local optdepends_list=()
1601 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1602 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1603 for i in "${optdepends_list[@]}"; do
1604 local pkg=${i%%:[[:space:]]*}
1605 # the '-' character _must_ be first or last in the character range
1606 if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then
1607 error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
1608 ret=1
1610 done
1612 for i in 'changelog' 'install'; do
1613 local file
1614 while read -r file; do
1615 # evaluate any bash variables used
1616 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1617 if [[ $file && ! -f $file ]]; then
1618 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1619 ret=1
1621 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1622 done
1624 local valid_options=1
1625 local known kopt options_list
1626 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
1627 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
1628 for i in ${options_list[@]}; do
1629 known=0
1630 # check if option matches a known option or its inverse
1631 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1632 if [[ ${i} = "${kopt}" || ${i} = "!${kopt}" ]]; then
1633 known=1
1635 done
1636 if (( ! known )); then
1637 error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
1638 valid_options=0
1640 done
1641 if (( ! valid_options )); then
1642 ret=1
1645 if (( ${#pkgname[@]} > 1 )); then
1646 for i in ${pkgname[@]}; do
1647 if ! declare -f package_${i} >/dev/null; then
1648 error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
1649 ret=1
1651 done
1654 for i in ${PKGLIST[@]}; do
1655 if ! in_array $i ${pkgname[@]}; then
1656 error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1657 ret=1
1659 done
1661 return $ret
1664 check_software() {
1665 # check for needed software
1666 local ret=0
1668 # check for sudo if we will need it during makepkg execution
1669 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1670 if ! type -p sudo >/dev/null; then
1671 warning "$(gettext "Cannot find the %s binary. Will use %s to acquire root privileges.")" "sudo" "su"
1675 # fakeroot - building as non-root user
1676 if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1677 if ! type -p fakeroot >/dev/null; then
1678 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
1679 ret=1
1683 # gpg - package signing
1684 if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then
1685 if ! type -p gpg >/dev/null; then
1686 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
1687 ret=1
1691 # gpg - source verification
1692 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
1693 if ! type -p gpg >/dev/null; then
1694 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
1695 ret=1
1699 # openssl - checksum operations
1700 if (( ! SKIPCHECKSUMS )); then
1701 if ! type -p openssl >/dev/null; then
1702 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
1703 ret=1
1707 # upx - binary compression
1708 if [[ $(check_option upx) == 'y' ]]; then
1709 if ! type -p upx >/dev/null; then
1710 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
1711 ret=1
1715 # distcc - compilation with distcc
1716 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
1717 if ! type -p distcc >/dev/null; then
1718 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
1719 ret=1
1723 # ccache - compilation with ccache
1724 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
1725 if ! type -p ccache >/dev/null; then
1726 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
1727 ret=1
1731 # strip - strip symbols from binaries/libraries
1732 if [[ $(check_option strip) = "y" ]]; then
1733 if ! type -p strip >/dev/null; then
1734 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
1735 ret=1
1739 # gzip - compressig man and info pages
1740 if [[ $(check_option zipman) = "y" ]]; then
1741 if ! type -p gzip >/dev/null; then
1742 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
1743 ret=1
1747 return $ret
1750 devel_check() {
1751 newpkgver=""
1753 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1754 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1755 if (( HOLDVER || SOURCEONLY || REPKG )) ||
1756 [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = "/dev/stdin" ]]; then
1757 return
1760 if [[ -z $FORCE_VER ]]; then
1761 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1762 # This will only be used on the first call to makepkg; subsequent
1763 # calls to makepkg via fakeroot will explicitly pass the version
1764 # number to avoid having to determine the version number twice.
1765 # Also do a check to make sure we have the VCS tool available.
1766 local vcs=()
1768 [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] && vcs+=("darcs")
1769 [[ -n ${_cvsroot} && -n ${_cvsmod} ]] && vcs+=("cvs")
1770 [[ -n ${_gitroot} && -n ${_gitname} ]] && vcs+=("git")
1771 [[ -n ${_svntrunk} && -n ${_svnmod} ]] && vcs+=("svn")
1772 [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] && vcs+=("bzr")
1773 [[ -n ${_hgroot} && -n ${_hgrepo} ]] && vcs+=("hg")
1775 if (( ${#vcs[@]} == 0 )); then
1776 return
1777 elif (( ${#vcs[@]} > 1 )); then
1778 warning "$(gettext "Ambiguous VCS package. Cannot pick from: %s.")" "${vcs[*]}"
1779 return 0
1782 if ! type -p "$vcs" >/dev/null; then
1783 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "$vcs" "$vcs"
1784 return 0
1787 msg "$(gettext "Determining latest %s revision...")" "$vcs"
1789 case "$vcs" in
1790 darcs)
1791 newpkgver=$(date +%Y%m%d)
1793 cvs)
1794 newpkgver=$(date +%Y%m%d)
1796 git)
1797 newpkgver=$(date +%Y%m%d)
1799 svn)
1800 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1802 bzr)
1803 newpkgver=$(bzr revno ${_bzrtrunk})
1806 if pushd "./src/$_hgrepo" > /dev/null; then
1807 local ret=0
1808 hg pull || ret=$?
1809 if (( ! ret )); then
1810 hg update
1811 elif (( ret != 1 )); then
1812 return 1
1814 else
1815 [[ ! -d ./src/ ]] && mkdir ./src/
1816 hg clone "$_hgroot/$_hgrepo" "./src/$_hgrepo"
1817 if ! pushd "./src/$_hgrepo" > /dev/null; then
1818 warning "$(gettext "An error occured while determining the hg version number.")"
1819 return 0
1822 newpkgver=$(hg tip --template "{rev}")
1823 popd > /dev/null
1825 esac
1827 if [[ -n $newpkgver ]]; then
1828 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1831 else
1832 # Version number retrieved from fakeroot->makepkg argument
1833 newpkgver=$FORCE_VER
1837 devel_update() {
1838 # This is lame, but if we're wanting to use an updated pkgver for
1839 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1840 # the new pkgver and then re-source it. This is the most robust
1841 # method for dealing with PKGBUILDs that use, e.g.:
1843 # pkgver=23
1844 # ...
1845 # _foo=pkgver
1847 if [[ -n $newpkgver && $newpkgver != "$pkgver" ]]; then
1848 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1849 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1850 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1851 source "$BUILDFILE"
1852 else
1853 warning "$(gettext "%s is not writeable -- pkgver will not be updated")" "$BUILDFILE"
1858 backup_package_variables() {
1859 local var
1860 for var in ${splitpkg_overrides[@]}; do
1861 local indirect="${var}_backup"
1862 eval "${indirect}=(\"\${$var[@]}\")"
1863 done
1866 restore_package_variables() {
1867 local var
1868 for var in ${splitpkg_overrides[@]}; do
1869 local indirect="${var}_backup"
1870 if [[ -n ${!indirect} ]]; then
1871 eval "${var}=(\"\${$indirect[@]}\")"
1872 else
1873 unset ${var}
1875 done
1878 run_split_packaging() {
1879 local pkgname_backup=${pkgname[@]}
1880 for pkgname in ${pkgname_backup[@]}; do
1881 pkgdir="$pkgdir/$pkgname"
1882 mkdir -p "$pkgdir"
1883 chmod a-s "$pkgdir"
1884 backup_package_variables
1885 run_package $pkgname
1886 tidy_install
1887 create_package $pkgname
1888 restore_package_variables
1889 pkgdir="${pkgdir%/*}"
1890 done
1891 pkgname=${pkgname_backup[@]}
1894 # Canonicalize a directory path if it exists
1895 canonicalize_path() {
1896 local path="$1";
1898 if [[ -d $path ]]; then
1900 cd_safe "$path"
1901 pwd -P
1903 else
1904 printf "%s\n" "$path"
1908 m4_include(library/parseopts.sh)
1910 usage() {
1911 printf "makepkg (pacman) %s\n" "$myver"
1912 echo
1913 printf -- "$(gettext "Usage: %s [options]")\n" "$0"
1914 echo
1915 printf -- "$(gettext "Options:")\n"
1916 printf -- "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
1917 printf -- "$(gettext " -c, --clean Clean up work files after build")\n"
1918 printf -- "$(gettext " -d, --nodeps Skip all dependency checks")\n"
1919 printf -- "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
1920 printf -- "$(gettext " -f, --force Overwrite existing package")\n"
1921 printf -- "$(gettext " -g, --geninteg Generate integrity checks for source files")\n"
1922 printf -- "$(gettext " -h, --help Show this help message and exit")\n"
1923 printf -- "$(gettext " -i, --install Install package after successful build")\n"
1924 printf -- "$(gettext " -L, --log Log package build process")\n"
1925 printf -- "$(gettext " -m, --nocolor Disable colorized output messages")\n"
1926 printf -- "$(gettext " -o, --nobuild Download and extract files only")\n"
1927 printf -- "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1928 printf -- "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")\n"
1929 printf -- "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")\n"
1930 printf -- "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
1931 printf -- "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")\n"
1932 printf -- "$(gettext " --allsource Generate a source-only tarball including downloaded sources")\n"
1933 printf -- "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
1934 printf -- "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1935 printf -- "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1936 printf -- "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1937 printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
1938 printf -- "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1939 printf -- "$(gettext " --nosign Do not create a signature for the package")\n"
1940 printf -- "$(gettext " --pkg <list> Only build listed packages from a split package")\n"
1941 printf -- "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
1942 printf -- "$(gettext " --skipchecksums Do not verify checksums of the source files")\n"
1943 printf -- "$(gettext " --skipinteg Do not perform any verification checks on source files")\n"
1944 printf -- "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")\n"
1945 echo
1946 printf -- "$(gettext "These options can be passed to %s:")\n" "pacman"
1947 echo
1948 printf -- "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")\n"
1949 printf -- "$(gettext " --noprogressbar Do not show a progress bar when downloading files")\n"
1950 echo
1951 printf -- "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
1952 echo
1955 version() {
1956 printf "makepkg (pacman) %s\n" "$myver"
1957 printf -- "$(gettext "\
1958 Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1959 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1960 This is free software; see the source for copying conditions.\n\
1961 There is NO WARRANTY, to the extent permitted by law.\n")"
1964 # PROGRAM START
1966 # determine whether we have gettext; make it a no-op if we do not
1967 if ! type -p gettext >/dev/null; then
1968 gettext() {
1969 printf "%s\n" "$@"
1973 ARGLIST=("$@")
1975 # Parse Command Line Options.
1976 OPT_SHORT="AcdefFghiLmop:rRsSV"
1977 OPT_LONG=('allsource' 'asroot' 'ignorearch' 'check' 'clean' 'nodeps'
1978 'noextract' 'force' 'forcever:' 'geninteg' 'help' 'holdver' 'skippgpcheck'
1979 'install' 'key:' 'log' 'nocolor' 'nobuild' 'nocheck' 'nosign' 'pkg:' 'rmdeps'
1980 'repackage' 'skipchecksums' 'skipinteg' 'skippgpcheck' 'sign' 'source' 'syncdeps'
1981 'version' 'config:')
1983 # Pacman Options
1984 OPT_LONG+=('noconfirm' 'noprogressbar')
1986 if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
1987 exit 1 # E_INVALID_OPTION;
1989 set -- "${OPTRET[@]}"
1990 unset OPT_SHORT OPT_LONG OPTRET
1992 while true; do
1993 case "$1" in
1994 # Pacman Options
1995 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1996 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1998 # Makepkg Options
1999 --allsource) SOURCEONLY=2 ;;
2000 --asroot) ASROOT=1 ;;
2001 -A|--ignorearch) IGNOREARCH=1 ;;
2002 -c|--clean) CLEANUP=1 ;;
2003 --check) RUN_CHECK='y' ;;
2004 --config) shift; MAKEPKG_CONF=$1 ;;
2005 -d|--nodeps) NODEPS=1 ;;
2006 -e|--noextract) NOEXTRACT=1 ;;
2007 -f|--force) FORCE=1 ;;
2008 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
2009 --forcever) shift; FORCE_VER=$1;;
2010 -F) INFAKEROOT=1 ;;
2011 -g|--geninteg) GENINTEG=1 ;;
2012 --holdver) HOLDVER=1 ;;
2013 -i|--install) INSTALL=1 ;;
2014 --key) shift; GPGKEY=$1 ;;
2015 -L|--log) LOGGING=1 ;;
2016 -m|--nocolor) USE_COLOR='n' ;;
2017 --nocheck) RUN_CHECK='n' ;;
2018 --nosign) SIGNPKG='n' ;;
2019 -o|--nobuild) NOBUILD=1 ;;
2020 -p) shift; BUILDFILE=$1 ;;
2021 --pkg) shift; IFS=, read -ra p <<<"$1"; PKGLIST+=("${p[@]}"); unset p ;;
2022 -r|--rmdeps) RMDEPS=1 ;;
2023 -R|--repackage) REPKG=1 ;;
2024 --skipchecksums) SKIPCHECKSUMS=1 ;;
2025 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
2026 --skippgpcheck) SKIPPGPCHECK=1;;
2027 --sign) SIGNPKG='y' ;;
2028 -s|--syncdeps) DEP_BIN=1 ;;
2029 -S|--source) SOURCEONLY=1 ;;
2031 -h|--help) usage; exit 0 ;; # E_OK
2032 -V|--version) version; exit 0 ;; # E_OK
2034 --) OPT_IND=0; shift; break 2;;
2035 esac
2036 shift
2037 done
2039 # setup signal traps
2040 trap 'clean_up' 0
2041 for signal in TERM HUP QUIT; do
2042 trap "trap_exit $signal \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal"
2043 done
2044 trap 'trap_exit INT "$(gettext "Aborted by user! Exiting...")"' INT
2045 trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' ERR
2047 # preserve environment variables and canonicalize path
2048 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
2049 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
2050 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
2051 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
2052 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
2053 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
2054 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
2055 [[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
2057 # default config is makepkg.conf
2058 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
2060 # Source the config file; fail if it is not found
2061 if [[ -r $MAKEPKG_CONF ]]; then
2062 source_safe "$MAKEPKG_CONF"
2063 else
2064 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
2065 plain "$(gettext "Aborting...")"
2066 exit 1 # $E_CONFIG_ERROR
2069 # Source user-specific makepkg.conf overrides, but only if no override config
2070 # file was specified
2071 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
2072 source_safe ~/.makepkg.conf
2075 # set pacman command if not already defined
2076 PACMAN=${PACMAN:-pacman}
2078 # check if messages are to be printed using color
2079 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
2080 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
2081 # prefer terminal safe colored and bold text when tput is supported
2082 if tput setaf 0 &>/dev/null; then
2083 ALL_OFF="$(tput sgr0)"
2084 BOLD="$(tput bold)"
2085 BLUE="${BOLD}$(tput setaf 4)"
2086 GREEN="${BOLD}$(tput setaf 2)"
2087 RED="${BOLD}$(tput setaf 1)"
2088 YELLOW="${BOLD}$(tput setaf 3)"
2089 else
2090 ALL_OFF="\e[1;0m"
2091 BOLD="\e[1;1m"
2092 BLUE="${BOLD}\e[1;34m"
2093 GREEN="${BOLD}\e[1;32m"
2094 RED="${BOLD}\e[1;31m"
2095 YELLOW="${BOLD}\e[1;33m"
2098 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2100 # override settings with an environment variable for batch processing
2101 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2102 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2103 if [[ ! -d $BUILDDIR ]]; then
2104 if ! mkdir -p "$BUILDDIR"; then
2105 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2106 plain "$(gettext "Aborting...")"
2107 exit 1
2109 chmod a-s "$BUILDDIR"
2111 if [[ ! -w $BUILDDIR ]]; then
2112 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2113 plain "$(gettext "Aborting...")"
2114 exit 1
2117 PKGDEST=${_PKGDEST:-$PKGDEST}
2118 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2119 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2120 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2121 plain "$(gettext "Aborting...")"
2122 exit 1
2125 SRCDEST=${_SRCDEST:-$SRCDEST}
2126 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2127 if [[ ! -w $SRCDEST ]] ; then
2128 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2129 plain "$(gettext "Aborting...")"
2130 exit 1
2133 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2134 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2135 if (( SOURCEONLY )) && [[ ! -w $SRCPKGDEST ]]; then
2136 error "$(gettext "You do not have write permission to store source tarballs in %s.")" "$SRCPKGDEST"
2137 plain "$(gettext "Aborting...")"
2138 exit 1
2141 PKGEXT=${_PKGEXT:-$PKGEXT}
2142 SRCEXT=${_SRCEXT:-$SRCEXT}
2143 GPGKEY=${_GPGKEY:-$GPGKEY}
2144 PACKAGER=${_PACKAGER:-$PACKAGER}
2146 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
2147 # The '\\0' is here to prevent gettext from thinking --holdver is an option
2148 error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
2149 exit 1
2152 if (( ! INFAKEROOT )); then
2153 if (( EUID == 0 && ! ASROOT )); then
2154 # Warn those who like to live dangerously.
2155 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2156 catastrophic damage to your system. If you wish to run as root, please\n\
2157 use the %s option.")" "makepkg" "--asroot"
2158 exit 1 # $E_USER_ABORT
2159 elif (( EUID > 0 && ASROOT )); then
2160 # Warn those who try to use the --asroot option when they are not root
2161 error "$(gettext "The %s option is meant for the root user only. Please\n\
2162 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2163 exit 1 # $E_USER_ABORT
2164 elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
2165 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2166 ownership of the packaged files. Try using the %s environment by\n\
2167 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF"
2168 sleep 1
2170 else
2171 if [[ -z $FAKEROOTKEY ]]; then
2172 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2173 exit 1 # TODO: error code
2177 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2178 unset md5sums replaces depends conflicts backup source install changelog build
2179 unset makedepends optdepends options noextract
2181 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2182 if [[ ! -f $BUILDFILE ]]; then
2183 if [[ -t 0 ]]; then
2184 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2185 exit 1
2186 else
2187 # PKGBUILD passed through a pipe
2188 BUILDFILE=/dev/stdin
2189 source_safe "$BUILDFILE"
2191 else
2192 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2193 if [[ -n $crlftest ]]; then
2194 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2195 exit 1
2198 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2199 BUILDFILE="$startdir/$BUILDFILE"
2201 source_safe "$BUILDFILE"
2204 # set defaults if they weren't specified in buildfile
2205 pkgbase=${pkgbase:-${pkgname[0]}}
2206 epoch=${epoch:-0}
2208 if [[ $BUILDDIR = "$startdir" ]]; then
2209 srcdir="$BUILDDIR/src"
2210 pkgdir="$BUILDDIR/pkg"
2211 else
2212 srcdir="$BUILDDIR/$pkgbase/src"
2213 pkgdir="$BUILDDIR/$pkgbase/pkg"
2216 if (( GENINTEG )); then
2217 mkdir -p "$srcdir"
2218 chmod a-s "$srcdir"
2219 cd_safe "$srcdir"
2220 download_sources
2221 generate_checksums
2222 exit 0 # $E_OK
2225 # check the PKGBUILD for some basic requirements
2226 check_sanity || exit 1
2228 # check we have the software required to process the PKGBUILD
2229 check_software || exit 1
2231 # We need to run devel_update regardless of whether we are in the fakeroot
2232 # build process so that if the user runs makepkg --forcever manually, we
2233 # 1) output the correct pkgver, and 2) use the correct filename when
2234 # checking if the package file already exists - fixes FS #9194
2235 devel_check
2236 devel_update
2238 if (( ${#pkgname[@]} > 1 )); then
2239 SPLITPKG=1
2242 # test for available PKGBUILD functions
2243 if declare -f build >/dev/null; then
2244 BUILDFUNC=1
2246 if declare -f check >/dev/null; then
2247 # "Hide" check() function if not going to be run
2248 if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then
2249 CHECKFUNC=1
2252 if declare -f package >/dev/null; then
2253 PKGFUNC=1
2254 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
2255 SPLITPKG=1
2258 if [[ -n "${PKGLIST[@]}" ]]; then
2259 unset pkgname
2260 pkgname=("${PKGLIST[@]}")
2263 # check if gpg signature is to be created and if signing key is valid
2264 [[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign)
2265 if [[ $SIGNPKG == 'y' ]]; then
2266 if ! gpg --list-key ${GPGKEY} &>/dev/null; then
2267 if [[ ! -z $GPGKEY ]]; then
2268 error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2269 else
2270 error "$(gettext "There is no key in your keyring.")"
2272 exit 1
2277 if (( ! SPLITPKG )); then
2278 fullver=$(get_full_version)
2279 pkgarch=$(get_pkg_arch)
2280 if [[ -f $PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT} ]] \
2281 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2282 if (( INSTALL )); then
2283 warning "$(gettext "A package has already been built, installing existing package...")"
2284 install_package
2285 exit $?
2286 else
2287 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2288 exit 1
2291 else
2292 allpkgbuilt=1
2293 somepkgbuilt=0
2294 for pkg in ${pkgname[@]}; do
2295 fullver=$(get_full_version $pkg)
2296 pkgarch=$(get_pkg_arch $pkg)
2297 if [[ -f $PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT} ]]; then
2298 somepkgbuilt=1
2299 else
2300 allpkgbuilt=0
2302 done
2303 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2304 if (( allpkgbuilt )); then
2305 if (( INSTALL )); then
2306 warning "$(gettext "The package group has already been built, installing existing packages...")"
2307 install_package
2308 exit $?
2309 else
2310 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2311 exit 1
2314 if (( somepkgbuilt )); then
2315 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2316 exit 1
2319 unset allpkgbuilt somepkgbuilt
2322 # Run the bare minimum in fakeroot
2323 if (( INFAKEROOT )); then
2324 if (( SOURCEONLY )); then
2325 create_srcpackage
2326 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2327 exit 0 # $E_OK
2330 if (( ! SPLITPKG )); then
2331 if (( ! PKGFUNC )); then
2332 if (( ! REPKG )); then
2333 if (( BUILDFUNC )); then
2334 run_build
2335 (( CHECKFUNC )) && run_check
2336 tidy_install
2338 else
2339 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2340 plain "$(gettext "File permissions may not be preserved.")"
2342 else
2343 run_package
2344 tidy_install
2346 create_package
2347 else
2348 run_split_packaging
2351 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2352 exit 0 # $E_OK
2355 fullver=$(get_full_version)
2356 msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2358 # if we are creating a source-only package, go no further
2359 if (( SOURCEONLY )); then
2360 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2361 && (( ! FORCE )); then
2362 error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2363 exit 1
2366 # Get back to our src directory so we can begin with sources.
2367 mkdir -p "$srcdir"
2368 chmod a-s "$srcdir"
2369 cd_safe "$srcdir"
2370 if ( (( ! SKIPCHECKSUMS )) || \
2371 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \
2372 (( SOURCEONLY == 2 )); then
2373 download_sources
2375 check_source_integrity
2376 cd_safe "$startdir"
2378 # if we are root or if fakeroot is not enabled, then we don't use it
2379 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2380 create_srcpackage
2381 else
2382 enter_fakeroot
2385 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2386 exit 0
2389 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
2390 # no warning message needed for nobuild, repkg
2391 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
2392 warning "$(gettext "Skipping dependency checks.")"
2394 elif type -p "${PACMAN%% *}" >/dev/null; then
2395 if (( RMDEPS && ! INSTALL )); then
2396 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2398 deperr=0
2400 msg "$(gettext "Checking runtime dependencies...")"
2401 resolve_deps ${depends[@]} || deperr=1
2403 if (( RMDEPS && INSTALL )); then
2404 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2407 msg "$(gettext "Checking buildtime dependencies...")"
2408 resolve_deps ${makedepends[@]} || deperr=1
2410 if (( CHECKFUNC )); then
2411 resolve_deps ${checkdepends[@]} || deperr=1
2414 if (( RMDEPS )); then
2415 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2418 if (( deperr )); then
2419 error "$(gettext "Could not resolve all dependencies.")"
2420 exit 1
2422 else
2423 warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
2426 # ensure we have a sane umask set
2427 umask 0022
2429 # get back to our src directory so we can begin with sources
2430 mkdir -p "$srcdir"
2431 chmod a-s "$srcdir"
2432 cd_safe "$srcdir"
2434 if (( NOEXTRACT )); then
2435 warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
2436 warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
2437 warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
2439 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
2440 error "$(gettext "The source directory is empty, there is nothing to build!")"
2441 plain "$(gettext "Aborting...")"
2442 exit 1
2444 elif (( REPKG )); then
2445 if (( ! PKGFUNC && ! SPLITPKG )) \
2446 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
2447 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2448 plain "$(gettext "Aborting...")"
2449 exit 1
2451 else
2452 download_sources
2453 check_source_integrity
2454 extract_sources
2457 if (( NOBUILD )); then
2458 msg "$(gettext "Sources are ready.")"
2459 exit 0 #E_OK
2460 else
2461 # check for existing pkg directory; don't remove if we are repackaging
2462 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2463 msg "$(gettext "Removing existing %s directory...")" "pkg/"
2464 rm -rf "$pkgdir"
2466 mkdir -p "$pkgdir"
2467 chmod a-s "$pkgdir"
2468 cd_safe "$startdir"
2470 # if we are root or if fakeroot is not enabled, then we don't use it
2471 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2472 if (( ! REPKG )); then
2473 devel_update
2474 (( BUILDFUNC )) && run_build
2475 (( CHECKFUNC )) && run_check
2477 if (( ! SPLITPKG )); then
2478 if (( PKGFUNC )); then
2479 run_package
2480 tidy_install
2481 else
2482 if (( ! REPKG )); then
2483 tidy_install
2484 else
2485 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2486 plain "$(gettext "File permissions may not be preserved.")"
2489 create_package
2490 else
2491 run_split_packaging
2493 else
2494 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2495 devel_update
2496 (( BUILDFUNC )) && run_build
2497 (( CHECKFUNC )) && run_check
2498 cd_safe "$startdir"
2501 enter_fakeroot
2505 fullver=$(get_full_version)
2506 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
2508 install_package
2510 exit 0 #E_OK
2512 # vim: set ts=2 sw=2 noet: