Document verifying source file signatures in makepkg
[pacman-ng.git] / scripts / makepkg.sh.in
blob50cf2725f35f2bee08075ce4c700c05eb3a39dd8
1 #!/bin/bash -e
3 # makepkg - make packages compatible for use with pacman
4 # @configure_input@
6 # Copyright (c) 2006-2011 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
178 # Signal Traps
180 set -E
181 trap 'clean_up' 0
182 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
183 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
184 trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
186 enter_fakeroot() {
187 msg "$(gettext "Entering %s environment...")" "fakeroot"
189 if [[ -n $newpkgver ]]; then
190 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
191 else
192 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
197 # a source entry can have two forms :
198 # 1) "filename::http://path/to/file"
199 # 2) "http://path/to/file"
201 # Return the absolute filename of a source entry
203 # This function accepts a source entry or the already extracted filename of a
204 # source entry as input
205 get_filepath() {
206 local file="$(get_filename "$1")"
208 if [[ -f "$startdir/$file" ]]; then
209 file="$startdir/$file"
210 elif [[ -f "$SRCDEST/$file" ]]; then
211 file="$SRCDEST/$file"
212 else
213 return 1
216 echo "$file"
219 # Print 'source not found' error message and exit makepkg
220 missing_source_file() {
221 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
222 plain "$(gettext "Aborting...")"
223 exit 1 # $E_MISSING_FILE
226 # extract the filename from a source entry
227 get_filename() {
228 # if a filename is specified, use it
229 local filename="${1%%::*}"
230 # if it is just an URL, we only keep the last component
231 echo "${filename##*/}"
234 # extract the URL from a source entry
235 get_url() {
236 # strip an eventual filename
237 echo "${1#*::}"
241 # usage : get_full_version( [$pkgname] )
242 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
244 get_full_version() {
245 if [[ -z $1 ]]; then
246 if [[ $epoch ]] && (( ! $epoch )); then
247 echo $pkgver-$pkgrel
248 else
249 echo $epoch:$pkgver-$pkgrel
251 else
252 for i in pkgver pkgrel epoch; do
253 local indirect="${i}_override"
254 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
255 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
256 done
257 if (( ! $epoch_override )); then
258 echo $pkgver_override-$pkgrel_override
259 else
260 echo $epoch_override:$pkgver_override-$pkgrel_override
266 # Checks to see if options are present in makepkg.conf or PKGBUILD;
267 # PKGBUILD options always take precedence.
269 # usage : check_option( $option )
270 # return : y - enabled
271 # n - disabled
272 # ? - not found
274 check_option() {
275 local ret=$(in_opt_array "$1" ${options[@]})
276 if [[ $ret != '?' ]]; then
277 echo $ret
278 return
281 # fall back to makepkg.conf options
282 ret=$(in_opt_array "$1" ${OPTIONS[@]})
283 if [[ $ret != '?' ]]; then
284 echo $ret
285 return
288 echo '?' # Not Found
293 # Check if option is present in BUILDENV
295 # usage : check_buildenv( $option )
296 # return : y - enabled
297 # n - disabled
298 # ? - not found
300 check_buildenv() {
301 in_opt_array "$1" ${BUILDENV[@]}
306 # usage : in_opt_array( $needle, $haystack )
307 # return : y - enabled
308 # n - disabled
309 # ? - not found
311 in_opt_array() {
312 local needle=$1; shift
314 local opt
315 for opt in "$@"; do
316 if [[ $opt = $needle ]]; then
317 echo 'y' # Enabled
318 return
319 elif [[ $opt = "!$needle" ]]; then
320 echo 'n' # Disabled
321 return
323 done
325 echo '?' # Not Found
330 # usage : in_array( $needle, $haystack )
331 # return : 0 - found
332 # 1 - not found
334 in_array() {
335 local needle=$1; shift
336 local item
337 for item in "$@"; do
338 [[ $item = $needle ]] && return 0 # Found
339 done
340 return 1 # Not Found
343 source_has_signatures(){
344 local file
345 for file in "${source[@]}"; do
346 if [[ $file = *.@(sig|asc) ]]; then
347 return 0
349 done
350 return 1
353 get_downloadclient() {
354 # $1 = URL with valid protocol prefix
355 local url=$1
356 local proto="${url%%://*}"
358 # loop through DOWNLOAD_AGENTS variable looking for protocol
359 local i
360 for i in "${DLAGENTS[@]}"; do
361 local handler="${i%%::*}"
362 if [[ $proto = $handler ]]; then
363 local agent="${i##*::}"
364 break
366 done
368 # if we didn't find an agent, return an error
369 if [[ -z $agent ]]; then
370 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
371 plain "$(gettext "Aborting...")"
372 exit 1 # $E_CONFIG_ERROR
375 # ensure specified program is installed
376 local program="${agent%% *}"
377 if [[ ! -x $program ]]; then
378 local baseprog="${program##*/}"
379 error "$(gettext "The download program %s is not installed.")" "$baseprog"
380 plain "$(gettext "Aborting...")"
381 exit 1 # $E_MISSING_PROGRAM
384 echo "$agent"
387 download_file() {
388 # download command
389 local dlcmd=$1
390 # URL of the file
391 local url=$2
392 # destination file
393 local file=$3
394 # temporary download file, default to last component of the URL
395 local dlfile="${url##*/}"
397 # replace %o by the temporary dlfile if it exists
398 if [[ $dlcmd = *%o* ]]; then
399 dlcmd=${dlcmd//\%o/\"$file.part\"}
400 dlfile="$file.part"
402 # add the URL, either in place of %u or at the end
403 if [[ $dlcmd = *%u* ]]; then
404 dlcmd=${dlcmd//\%u/\"$url\"}
405 else
406 dlcmd="$dlcmd \"$url\""
409 local ret=0
410 eval "$dlcmd || ret=\$?"
411 if (( ret )); then
412 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
413 return $ret
416 # rename the temporary download file to the final destination
417 if [[ $dlfile != "$file" ]]; then
418 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
422 run_pacman() {
423 local cmd
424 printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
425 if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
426 if type -p sudo >/dev/null; then
427 cmd="sudo $cmd"
428 else
429 cmd="su root -c '$cmd'"
432 eval "$cmd"
435 check_deps() {
436 (( $# > 0 )) || return 0
438 # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility
439 # Also, a non-zero return value is not unexpected and we are manually dealing them
440 set +E
441 local ret=0
442 local pmout
443 pmout=$(run_pacman -T "$@") || ret=$?
444 set -E
446 if (( ret == 127 )); then #unresolved deps
447 echo "$pmout"
448 elif (( ret )); then
449 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
450 return "$ret"
454 handle_deps() {
455 local R_DEPS_SATISFIED=0
456 local R_DEPS_MISSING=1
458 (( $# == 0 )) && return $R_DEPS_SATISFIED
460 local deplist="$*"
462 if (( ! DEP_BIN )); then
463 return $R_DEPS_MISSING
466 if (( DEP_BIN )); then
467 # install missing deps from binary packages (using pacman -S)
468 msg "$(gettext "Installing missing dependencies...")"
470 if ! run_pacman -S --asdeps $deplist; then
471 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
472 exit 1 # TODO: error code
476 # we might need the new system environment
477 # avoid triggering the ERR trap and exiting
478 set +e
479 local restoretrap=$(trap -p ERR)
480 trap - ERR
481 source /etc/profile &>/dev/null
482 eval $restoretrap
483 set -e
485 return $R_DEPS_SATISFIED
488 resolve_deps() {
489 local R_DEPS_SATISFIED=0
490 local R_DEPS_MISSING=1
492 # deplist cannot be declared like this: local deplist=$(foo)
493 # Otherwise, the return value will depend on the assignment.
494 local deplist
495 deplist="$(set +E; check_deps $*)" || exit 1
496 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
498 if handle_deps $deplist; then
499 # check deps again to make sure they were resolved
500 deplist="$(set +E; check_deps $*)" || exit 1
501 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
504 msg "$(gettext "Missing Dependencies:")"
505 local dep
506 for dep in $deplist; do
507 msg2 "$dep"
508 done
510 return $R_DEPS_MISSING
513 remove_deps() {
514 (( ! RMDEPS )) && return
516 # check for packages removed during dependency install (e.g. due to conflicts)
517 # removing all installed packages is risky in this case
518 if [[ -n $(comm -23 <(printf "%s\n" "${original_pkglist[@]}") \
519 <(printf "%s\n" "${current_pkglist[@]}")) ]]; then
520 warning "$(gettext "Failed to remove installed dependencies.")"
521 return 0
524 local deplist=($(comm -13 <(printf "%s\n" "${original_pkglist[@]}") \
525 <(printf "%s\n" "${current_pkglist[@]}")))
526 (( ${#deplist[@]} == 0 )) && return
528 msg "Removing installed dependencies..."
529 # exit cleanly on failure to remove deps as package has been built successfully
530 if ! run_pacman -Rn ${deplist[@]}; then
531 warning "$(gettext "Failed to remove installed dependencies.")"
532 return 0
536 download_sources() {
537 msg "$(gettext "Retrieving Sources...")"
539 pushd "$SRCDEST" &>/dev/null
541 local netfile
542 for netfile in "${source[@]}"; do
543 local file=$(get_filepath "$netfile" || true)
544 if [[ -n "$file" ]]; then
545 msg2 "$(gettext "Found %s")" "${file##*/}"
546 rm -f "$srcdir/${file##*/}"
547 ln -s "$file" "$srcdir/"
548 continue
551 file=$(get_filename "$netfile")
552 local url=$(get_url "$netfile")
554 # if we get here, check to make sure it was a URL, else fail
555 if [[ $file = $url ]]; then
556 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
557 exit 1 # $E_MISSING_FILE
560 # find the client we should use for this URL
561 local dlclient=$(get_downloadclient "$url") || exit $?
563 msg2 "$(gettext "Downloading %s...")" "$file"
564 # fix flyspray bug #3289
565 local ret=0
566 download_file "$dlclient" "$url" "$file" || ret=$?
567 if (( ret )); then
568 error "$(gettext "Failure while downloading %s")" "$file"
569 plain "$(gettext "Aborting...")"
570 exit 1
572 rm -f "$srcdir/$file"
573 ln -s "$SRCDEST/$file" "$srcdir/"
574 done
576 popd &>/dev/null
579 get_integlist() {
580 local integ
581 local integlist=()
583 for integ in md5 sha1 sha256 sha384 sha512; do
584 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
585 if [[ -n "$integrity_sums" ]]; then
586 integlist=(${integlist[@]} $integ)
588 done
590 if (( ${#integlist[@]} > 0 )); then
591 echo ${integlist[@]}
592 else
593 echo ${INTEGRITY_CHECK[@]}
597 generate_checksums() {
598 msg "$(gettext "Generating checksums for source files...")"
599 plain ""
601 if ! type -p openssl >/dev/null; then
602 error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
603 exit 1 # $E_MISSING_PROGRAM
606 local integlist
607 if (( $# == 0 )); then
608 integlist=$(get_integlist)
609 else
610 integlist=$@
613 local integ
614 for integ in ${integlist[@]}; do
615 case "$integ" in
616 md5|sha1|sha256|sha384|sha512) : ;;
618 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
619 exit 1;; # $E_CONFIG_ERROR
620 esac
622 local ct=0
623 local numsrc=${#source[@]}
624 echo -n "${integ}sums=("
626 local i
627 local indent=''
628 for (( i = 0; i < ${#integ} + 6; i++ )); do
629 indent="$indent "
630 done
632 local netfile
633 for netfile in "${source[@]}"; do
634 local file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
635 local sum="$(openssl dgst -${integ} "$file")"
636 sum=${sum##* }
637 (( ct )) && echo -n "$indent"
638 echo -n "'$sum'"
639 ct=$(($ct+1))
640 (( $ct < $numsrc )) && echo
641 done
643 echo ")"
644 done
647 check_checksums() {
648 (( SKIPCHECKSUMS )) && return 0
649 (( ! ${#source[@]} )) && return 0
651 local correlation=0
652 local integ required
653 for integ in md5 sha1 sha256 sha384 sha512; do
654 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
655 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
656 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
657 correlation=1
658 local errors=0
659 local idx=0
660 local file
661 for file in "${source[@]}"; do
662 local found=1
663 file="$(get_filename "$file")"
664 echo -n " $file ... " >&2
666 if ! file="$(get_filepath "$file")"; then
667 echo "$(gettext "NOT FOUND")" >&2
668 errors=1
669 found=0
672 if (( $found )) ; then
673 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
674 local realsum="$(openssl dgst -${integ} "$file")"
675 realsum="${realsum##* }"
676 if [[ $expectedsum = $realsum ]]; then
677 echo "$(gettext "Passed")" >&2
678 else
679 echo "$(gettext "FAILED")" >&2
680 errors=1
684 idx=$((idx + 1))
685 done
687 if (( errors )); then
688 error "$(gettext "One or more files did not pass the validity check!")"
689 exit 1 # TODO: error code
691 elif (( ${#integrity_sums[@]} )); then
692 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
693 exit 1 # TODO: error code
695 done
697 if (( ! correlation )); then
698 error "$(gettext "Integrity checks are missing.")"
699 exit 1 # TODO: error code
703 check_pgpsigs() {
704 (( SKIPPGPCHECK )) && return 0
705 ! source_has_signatures && return 0
707 msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
709 local file pubkey
710 local warning=0
711 local errors=0
712 local statusfile=$(mktemp)
714 for file in "${source[@]}"; do
715 file="$(get_filename "$file")"
716 if [[ ! $file = *.@(sig|asc) ]]; then
717 continue
720 printf " %s ... " "${file%.*}" >&2
722 if ! file="$(get_filepath "$file")"; then
723 printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
724 errors=1
725 continue
728 if ! sourcefile="$(get_filepath "${file%.*}")"; then
729 printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
730 errors=1
731 continue
734 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
735 printf '%s' "$(gettext "FAILED")" >&2
736 if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
737 printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
738 warnings=1
739 else
740 errors=1
742 printf '\n' >&2
743 else
744 if grep -q "REVKEYSIG" "$statusfile"; then
745 printf '%s (%s)' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
746 errors=1
747 else
748 printf '%s' "$(gettext "Passed")" >&2
749 if grep -q "EXPSIG" "$statusfile"; then
750 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
751 warnings=1
752 elif grep -q "EXPKEYSIG" "$statusfile"; then
753 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
754 warnings=1
757 printf '\n' >&2
759 done
761 rm -f "$statusfile"
763 if (( errors )); then
764 error "$(gettext "One or more PGP signatures could not be verified!")"
765 exit 1
768 if (( warnings )); then
769 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
770 plain "$(gettext "Please make sure you really trust them.")"
774 check_source_integrity() {
775 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
776 warning "$(gettext "Skipping all source file integrity checks.")"
777 elif (( SKIPCHECKSUMS )); then
778 warning "$(gettext "Skipping verification of source file checksums.")"
779 check_pgpsigs
780 elif (( SKIPPGPCHECK )); then
781 warning "$(gettext "Skipping verification of source file PGP signatures.")"
782 check_checksums
783 else
784 check_checksums
785 check_pgpsigs
789 extract_sources() {
790 msg "$(gettext "Extracting Sources...")"
791 local netfile
792 for netfile in "${source[@]}"; do
793 local file=$(get_filename "$netfile")
794 if in_array "$file" "${noextract[@]}"; then
795 #skip source files in the noextract=() array
796 # these are marked explicitly to NOT be extracted
797 continue
801 # fix flyspray #6246
802 local file_type=$(file -bizL "$file")
803 local ext=${file##*.}
804 local cmd=''
805 case "$file_type" in
806 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
807 cmd="bsdtar" ;;
808 *application/x-gzip*)
809 case "$ext" in
810 gz|z|Z) cmd="gzip" ;;
811 *) continue;;
812 esac ;;
813 *application/x-bzip*)
814 case "$ext" in
815 bz2|bz) cmd="bzip2" ;;
816 *) continue;;
817 esac ;;
818 *application/x-xz*)
819 case "$ext" in
820 xz) cmd="xz" ;;
821 *) continue;;
822 esac ;;
824 # See if bsdtar can recognize the file
825 if bsdtar -tf "$file" -q '*' &>/dev/null; then
826 cmd="bsdtar"
827 else
828 continue
829 fi ;;
830 esac
832 local ret=0
833 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
834 if [[ $cmd = bsdtar ]]; then
835 $cmd -xf "$file" || ret=$?
836 else
837 rm -f "${file%.*}"
838 $cmd -dcf "$file" > "${file%.*}" || ret=$?
840 if (( ret )); then
841 error "$(gettext "Failed to extract %s")" "$file"
842 plain "$(gettext "Aborting...")"
843 exit 1
845 done
847 if (( EUID == 0 )); then
848 # change perms of all source files to root user & root group
849 chown -R 0:0 "$srcdir"
853 error_function() {
854 if [[ -p $logpipe ]]; then
855 rm "$logpipe"
857 # first exit all subshells, then print the error
858 if (( ! BASH_SUBSHELL )); then
859 error "$(gettext "A failure occurred in %s().")" "$1"
860 plain "$(gettext "Aborting...")"
861 remove_deps
863 exit 2 # $E_BUILD_FAILED
866 run_function() {
867 if [[ -z $1 ]]; then
868 return 1
870 local pkgfunc="$1"
872 # clear user-specified buildflags if requested
873 if [[ $(check_option buildflags) = "n" ]]; then
874 unset CFLAGS CXXFLAGS LDFLAGS
877 # clear user-specified makeflags if requested
878 if [[ $(check_option makeflags) = "n" ]]; then
879 unset MAKEFLAGS
882 msg "$(gettext "Starting %s()...")" "$pkgfunc"
883 cd "$srcdir"
885 # ensure all necessary build variables are exported
886 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
887 # save our shell options so pkgfunc() can't override what we need
888 local shellopts=$(shopt -p)
890 local ret=0
891 local restoretrap
892 if (( LOGGING )); then
893 local fullver=$(get_full_version)
894 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
895 if [[ -f $BUILDLOG ]]; then
896 local i=1
897 while true; do
898 if [[ -f $BUILDLOG.$i ]]; then
899 i=$(($i +1))
900 else
901 break
903 done
904 mv "$BUILDLOG" "$BUILDLOG.$i"
907 # ensure overridden package variables survive tee with split packages
908 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
909 mkfifo "$logpipe"
910 tee "$BUILDLOG" < "$logpipe" &
911 local teepid=$!
913 restoretrap=$(trap -p ERR)
914 trap 'error_function $pkgfunc' ERR
915 $pkgfunc &>"$logpipe"
916 eval $restoretrap
918 wait $teepid
919 rm "$logpipe"
920 else
921 restoretrap=$(trap -p ERR)
922 trap 'error_function $pkgfunc' ERR
923 $pkgfunc 2>&1
924 eval $restoretrap
926 # reset our shell options
927 eval "$shellopts"
930 run_build() {
931 # use distcc if it is requested (check buildenv and PKGBUILD opts)
932 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
933 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
934 export DISTCC_HOSTS
937 # use ccache if it is requested (check buildenv and PKGBUILD opts)
938 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
939 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
942 run_function "build"
945 run_check() {
946 run_function "check"
949 run_package() {
950 local pkgfunc
951 if [[ -z $1 ]]; then
952 pkgfunc="package"
953 else
954 pkgfunc="package_$1"
957 run_function "$pkgfunc"
960 tidy_install() {
961 cd "$pkgdir"
962 msg "$(gettext "Tidying install...")"
964 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
965 msg2 "$(gettext "Removing doc files...")"
966 rm -rf ${DOC_DIRS[@]}
969 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
970 msg2 "$(gettext "Purging unwanted files...")"
971 local pt
972 for pt in "${PURGE_TARGETS[@]}"; do
973 if [[ ${pt} = ${pt//\/} ]]; then
974 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
975 else
976 rm -f ${pt}
978 done
981 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
982 msg2 "$(gettext "Compressing man and info pages...")"
983 local manpage ext file link hardlinks hl
984 find ${MAN_DIRS[@]} -type f 2>/dev/null |
985 while read manpage ; do
986 ext="${manpage##*.}"
987 file="${manpage##*/}"
988 if [[ $ext != gz && $ext != bz2 ]]; then
989 # update symlinks to this manpage
990 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
991 while read link ; do
992 rm -f "$link" "${link}.gz"
993 ln -s "${file}.gz" "${link}.gz"
994 done
996 # check file still exists (potentially already compressed due to hardlink)
997 if [[ -f ${manpage} ]]; then
998 # find hard links and remove them
999 # the '|| true' part keeps the script from bailing on the EOF returned
1000 # by read at the end of the find output
1001 IFS=$'\n' read -rd '' -a hardlinks < \
1002 <(find "${MAN_DIRS[@]}" \! -name "$file" -samefile "$manpage" 2>/dev/null) || true
1003 rm -f "${hardlinks[@]}"
1004 # compress the original
1005 gzip -9 "$manpage"
1006 # recreate hard links removed earlier
1007 for hl in "${hardlinks[@]}"; do
1008 ln "${manpage}.gz" "${hl}.gz"
1009 chmod 644 ${hl}.gz
1010 done
1013 done
1016 if [[ $(check_option strip) = y ]]; then
1017 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1018 # make sure library stripping variables are defined to prevent excess stripping
1019 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1020 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1021 local binary
1022 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1023 case "$(file -bi "$binary")" in
1024 *application/x-sharedlib*) # Libraries (.so)
1025 strip $STRIP_SHARED "$binary";;
1026 *application/x-archive*) # Libraries (.a)
1027 strip $STRIP_STATIC "$binary";;
1028 *application/x-executable*) # Binaries
1029 strip $STRIP_BINARIES "$binary";;
1030 esac
1031 done
1034 if [[ $(check_option libtool) = "n" ]]; then
1035 msg2 "$(gettext "Removing "%s" files...")" "libtool"
1036 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
1039 if [[ $(check_option emptydirs) = "n" ]]; then
1040 msg2 "$(gettext "Removing empty directories...")"
1041 find . -depth -type d -empty -delete
1044 if [[ $(check_option upx) = "y" ]]; then
1045 msg2 "$(gettext "Compressing binaries with %s...")" "UPX"
1046 local binary
1047 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1048 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1049 upx $UPXFLAGS "$binary" &>/dev/null ||
1050 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1052 done
1056 find_libdepends() {
1057 local libdepends
1058 find "$pkgdir" -type f -perm -u+x | while read filename
1060 # get architecture of the file; if soarch is empty it's not an ELF binary
1061 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1062 [ -n "$soarch" ] || continue
1063 # process all libraries needed by the binary
1064 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1066 # extract the library name: libfoo.so
1067 soname="${sofile%%\.so\.*}.so"
1068 # extract the major version: 1
1069 soversion="${sofile##*\.so\.}"
1070 if in_array "${soname}" ${depends[@]}; then
1071 if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then
1072 # libfoo.so=1-64
1073 echo "${soname}=${soversion}-${soarch}"
1074 libdepends=(${libdepends[@]} "${soname}=${soversion}-${soarch}")
1077 done
1078 done
1081 find_libprovides() {
1082 local libprovides
1083 find "$pkgdir" -type f -name \*.so\* | while read filename
1085 # check if we really have a shared object
1086 if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1087 # 64
1088 soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1089 # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1
1090 sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1091 [ -z "$sofile" ] && sofile="${filename##*/}"
1093 # extract the library name: libfoo.so
1094 soname="${sofile%%\.so\.*}.so"
1095 # extract the major version: 1
1096 soversion="${sofile##*\.so\.}"
1097 if in_array "${soname}" ${provides[@]}; then
1098 if ! in_array "${soname}=${soversion}-${soarch}" ${libprovides[@]}; then
1099 # libfoo.so=1-64
1100 echo "${soname}=${soversion}-${soarch}"
1101 libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
1105 done
1108 write_pkginfo() {
1109 local builddate=$(date -u "+%s")
1110 if [[ -n $PACKAGER ]]; then
1111 local packager="$PACKAGER"
1112 else
1113 local packager="Unknown Packager"
1115 local size="$(@DUPATH@ -sk)"
1116 size="$(( ${size%%[^0-9]*} * 1024 ))"
1118 msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
1119 echo "# Generated by makepkg $myver"
1120 if (( INFAKEROOT )); then
1121 echo "# using $(fakeroot -v)"
1123 echo "# $(LC_ALL=C date -u)"
1124 echo "pkgname = $1"
1125 (( SPLITPKG )) && echo pkgbase = $pkgbase
1126 echo "pkgver = $(get_full_version)"
1127 echo "pkgdesc = $pkgdesc"
1128 echo "url = $url"
1129 echo "builddate = $builddate"
1130 echo "packager = $packager"
1131 echo "size = $size"
1132 echo "arch = $PKGARCH"
1134 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1135 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1136 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1137 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
1138 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1139 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1141 local it
1143 libprovides=$(find_libprovides)
1144 libdepends=$(find_libdepends)
1145 provides=("${provides[@]}" ${libprovides})
1146 depends=("${depends[@]}" ${libdepends})
1148 for it in "${depends[@]}"; do
1149 if [[ $it = *.so ]]; then
1150 # check if the entry has been found by find_libdepends
1151 # if not, it's unneeded; tell the user so he can remove it
1152 if [[ ! $libdepends =~ (^|\s)${it}=.* ]]; then
1153 error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it"
1154 return 1
1156 else
1157 echo "depend = $it"
1159 done
1161 for it in "${provides[@]}"; do
1162 # ignore versionless entires (those come from the PKGBUILD)
1163 if [[ $it = *.so ]]; then
1164 # check if the entry has been found by find_libprovides
1165 # if not, it's unneeded; tell the user so he can remove it
1166 if [[ ! $libprovides =~ (^|\s)${it}=.* ]]; then
1167 error "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$it"
1168 return 1
1170 else
1171 echo "provides = $it"
1173 done
1175 for it in "${packaging_options[@]}"; do
1176 local ret="$(check_option $it)"
1177 if [[ $ret != "?" ]]; then
1178 if [[ $ret = y ]]; then
1179 echo "makepkgopt = $it"
1180 else
1181 echo "makepkgopt = !$it"
1184 done
1186 # TODO maybe remove this at some point
1187 # warn if license array is not present or empty
1188 if [[ -z $license ]]; then
1189 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1190 plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
1194 check_package() {
1195 cd "$pkgdir"
1197 # check existence of backup files
1198 local file
1199 for file in "${backup[@]}"; do
1200 if [[ ! -f $file ]]; then
1201 warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
1203 done
1205 # check for references to the build and package directory
1206 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1207 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
1209 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
1210 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
1215 create_package() {
1216 if [[ ! -d $pkgdir ]]; then
1217 error "$(gettext "Missing %s directory.")" "pkg/"
1218 plain "$(gettext "Aborting...")"
1219 exit 1 # $E_MISSING_PKGDIR
1222 check_package
1224 cd "$pkgdir"
1225 msg "$(gettext "Creating package...")"
1227 local nameofpkg
1228 if [[ -z $1 ]]; then
1229 nameofpkg="$pkgname"
1230 else
1231 nameofpkg="$1"
1234 if [[ $arch = "any" ]]; then
1235 PKGARCH="any"
1236 else
1237 PKGARCH=$CARCH
1240 write_pkginfo $nameofpkg > .PKGINFO
1242 local comp_files=".PKGINFO"
1244 # check for changelog/install files
1245 for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1246 IFS='/' read -r orig dest < <(printf '%s\n' "$i")
1248 if [[ -n ${!orig} ]]; then
1249 msg2 "$(gettext "Adding %s file...")" "$orig"
1250 cp "$startdir/${!orig}" "$dest"
1251 chmod 644 "$dest"
1252 comp_files+=" $dest"
1254 done
1256 # tar it up
1257 msg2 "$(gettext "Compressing package...")"
1259 local fullver=$(get_full_version)
1260 local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}"
1261 local ret=0
1263 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1264 [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
1266 # when fileglobbing, we want * in an empty directory to expand to
1267 # the null string rather than itself
1268 shopt -s nullglob
1269 # TODO: Maybe this can be set globally for robustness
1270 shopt -s -o pipefail
1271 # bsdtar's gzip compression always saves the time stamp, making one
1272 # archive created using the same command line distinct from another.
1273 # Disable bsdtar compression and use gzip -n for now.
1274 bsdtar -cf - $comp_files * |
1275 case "$PKGEXT" in
1276 *tar.gz) gzip -c -f -n ;;
1277 *tar.bz2) bzip2 -c -f ;;
1278 *tar.xz) xz -c -z - ;;
1279 *tar.Z) compress -c -f ;;
1280 *tar) cat ;;
1281 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1282 "$PKGEXT"; cat ;;
1283 esac > "${pkg_file}" || ret=$?
1285 shopt -u nullglob
1286 shopt -u -o pipefail
1288 if (( ret )); then
1289 error "$(gettext "Failed to create package file.")"
1290 exit 1 # TODO: error code
1293 create_signature "$pkg_file"
1295 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1296 rm -f "${pkg_file/$PKGDEST/$startdir}"
1297 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1298 ret=$?
1299 if [[ -f $pkg_file.sig ]]; then
1300 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1301 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1305 if (( ret )); then
1306 warning "$(gettext "Failed to create symlink to package file.")"
1310 create_signature() {
1311 if [[ $SIGNPKG != 'y' ]]; then
1312 return
1314 local ret=0
1315 local filename="$1"
1316 msg "$(gettext "Signing package...")"
1318 local SIGNWITHKEY=""
1319 if [[ -n $GPGKEY ]]; then
1320 SIGNWITHKEY="-u ${GPGKEY}"
1322 # The signature will be generated directly in ascii-friendly format
1323 gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
1326 if (( ! ret )); then
1327 msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
1328 else
1329 warning "$(gettext "Failed to sign package file.")"
1333 create_srcpackage() {
1334 local ret=0
1335 msg "$(gettext "Creating source package...")"
1336 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1337 mkdir "${srclinks}"/${pkgbase}
1339 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1340 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1342 local file
1343 for file in "${source[@]}"; do
1344 if [[ -f $file ]]; then
1345 msg2 "$(gettext "Adding %s...")" "$file"
1346 ln -s "${startdir}/$file" "$srclinks/$pkgbase"
1347 elif (( SOURCEONLY == 2 )); then
1348 local absfile=$(get_filepath "$file") || missing_source_file "$file"
1349 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1350 ln -s "$absfile" "$srclinks/$pkgbase"
1352 done
1354 local i
1355 for i in 'changelog' 'install'; do
1356 local file
1357 while read -r file; do
1358 # evaluate any bash variables used
1359 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1360 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1361 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1362 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1364 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1365 done
1367 local TAR_OPT
1368 case "$SRCEXT" in
1369 *tar.gz) TAR_OPT="z" ;;
1370 *tar.bz2) TAR_OPT="j" ;;
1371 *tar.xz) TAR_OPT="J" ;;
1372 *tar.Z) TAR_OPT="Z" ;;
1373 *tar) TAR_OPT="" ;;
1374 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1375 "$SRCEXT" ;;
1376 esac
1378 local fullver=$(get_full_version)
1379 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1381 # tar it up
1382 msg2 "$(gettext "Compressing source package...")"
1383 cd "${srclinks}"
1384 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1385 error "$(gettext "Failed to create source package file.")"
1386 exit 1 # TODO: error code
1389 if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1390 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1391 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1392 ret=$?
1395 if (( ret )); then
1396 warning "$(gettext "Failed to create symlink to source package file.")"
1399 cd "${startdir}"
1400 rm -rf "${srclinks}"
1403 install_package() {
1404 (( ! INSTALL )) && return
1406 if (( ! SPLITPKG )); then
1407 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1408 else
1409 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1412 local fullver pkg pkglist
1413 for pkg in ${pkgname[@]}; do
1414 fullver=$(get_full_version $pkg)
1415 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then
1416 pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}"
1417 else
1418 pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}"
1420 done
1422 if ! run_pacman -U $pkglist; then
1423 warning "$(gettext "Failed to install built package(s).")"
1424 return 0
1428 check_sanity() {
1429 # check for no-no's in the build script
1430 local i
1431 local ret=0
1432 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1433 if [[ -z ${!i} ]]; then
1434 error "$(gettext "%s is not allowed to be empty.")" "$i"
1435 ret=1
1437 done
1439 for i in "${pkgname[@]}"; do
1440 if [[ ${i:0:1} = "-" ]]; then
1441 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1442 ret=1
1444 done
1446 if [[ ${pkgbase:0:1} = "-" ]]; then
1447 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1448 ret=1
1451 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1452 while IFS='=' read -r _ i; do
1453 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1454 if [[ $i = *[[:space:]:-]* ]]; then
1455 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1456 return 1
1458 done || ret=1
1460 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1461 while IFS='=' read -r _ i; do
1462 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1463 if [[ $i = *[[:space:]-]* ]]; then
1464 error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel"
1465 return 1
1467 done || ret=1
1469 awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
1470 while IFS='=' read -r _ i; do
1471 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1472 if [[ $i != *([[:digit:]]) ]]; then
1473 error "$(gettext "%s must be an integer.")" "epoch"
1474 return 1
1476 done || ret=1
1478 if [[ $arch != 'any' ]]; then
1479 if ! in_array $CARCH ${arch[@]}; then
1480 if (( ! IGNOREARCH )); then
1481 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1482 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1483 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1484 ret=1
1489 if (( ${#pkgname[@]} > 1 )); then
1490 for i in ${pkgname[@]}; do
1491 local arch_list=""
1492 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1493 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1494 if ! in_array $CARCH ${arch_list[@]}; then
1495 if (( ! IGNOREARCH )); then
1496 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1497 ret=1
1501 done
1504 local provides_list=()
1505 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1506 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1507 for i in ${provides_list[@]}; do
1508 if [[ $i == *['<>']* ]]; then
1509 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1510 ret=1
1512 done
1514 local backup_list=()
1515 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1516 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1517 for i in "${backup_list[@]}"; do
1518 if [[ ${i:0:1} = "/" ]]; then
1519 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1520 ret=1
1522 done
1524 local optdepends_list=()
1525 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1526 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1527 for i in "${optdepends_list[@]}"; do
1528 local pkg=${i%%:[[:space:]]*}
1529 # the '-' character _must_ be first or last in the character range
1530 if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then
1531 error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
1532 ret=1
1534 done
1536 for i in 'changelog' 'install'; do
1537 local file
1538 while read -r file; do
1539 # evaluate any bash variables used
1540 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1541 if [[ $file && ! -f $file ]]; then
1542 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1543 ret=1
1545 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1546 done
1548 local valid_options=1
1549 local known kopt options_list
1550 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
1551 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
1552 for i in ${options_list[@]}; do
1553 known=0
1554 # check if option matches a known option or its inverse
1555 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1556 if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then
1557 known=1
1559 done
1560 if (( ! known )); then
1561 error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
1562 valid_options=0
1564 done
1565 if (( ! valid_options )); then
1566 ret=1
1569 if (( ${#pkgname[@]} > 1 )); then
1570 for i in ${pkgname[@]}; do
1571 if ! declare -f package_${i} >/dev/null; then
1572 error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
1573 ret=1
1575 done
1578 for i in ${PKGLIST[@]}; do
1579 if ! in_array $i ${pkgname[@]}; then
1580 error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1581 ret=1
1583 done
1585 return $ret
1588 check_software() {
1589 # check for needed software
1590 local ret=0
1592 # check for sudo if we will need it during makepkg execution
1593 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1594 if ! type -p sudo >/dev/null; then
1595 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1599 # fakeroot - building as non-root user
1600 if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1601 if ! type -p fakeroot >/dev/null; then
1602 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
1603 ret=1
1607 # gpg - package signing
1608 if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then
1609 if ! type -p gpg >/dev/null; then
1610 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
1611 ret=1
1615 # gpg - source verification
1616 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
1617 if ! type -p gpg >/dev/null; then
1618 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
1619 ret=1
1623 # openssl - checksum operations
1624 if (( ! SKIPCHECKSUMS )); then
1625 if ! type -p openssl >/dev/null; then
1626 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
1627 ret=1
1631 # upx - binary compression
1632 if [[ $(check_option upx) == 'y' ]]; then
1633 if ! type -p upx >/dev/null; then
1634 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
1635 ret=1
1639 # distcc - compilation with distcc
1640 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
1641 if ! type -p distcc >/dev/null; then
1642 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
1643 ret=1
1647 # ccache - compilation with ccache
1648 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
1649 if ! type -p ccache >/dev/null; then
1650 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
1651 ret=1
1655 # strip - strip symbols from binaries/libraries
1656 if [[ $(check_option strip) = "y" ]]; then
1657 if ! type -p strip >/dev/null; then
1658 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
1659 ret=1
1663 # gzip - compressig man and info pages
1664 if [[ $(check_option zipman) = "y" ]]; then
1665 if ! type -p gzip >/dev/null; then
1666 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
1667 ret=1
1671 return $ret
1674 devel_check() {
1675 newpkgver=""
1677 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1678 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1679 if (( HOLDVER || SOURCEONLY || REPKG )) ||
1680 [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = /dev/stdin ]]; then
1681 return
1684 if [[ -z $FORCE_VER ]]; then
1685 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1686 # This will only be used on the first call to makepkg; subsequent
1687 # calls to makepkg via fakeroot will explicitly pass the version
1688 # number to avoid having to determine the version number twice.
1689 # Also do a check to make sure we have the VCS tool available.
1690 oldpkgver=$pkgver
1691 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1692 if ! type -p darcs >/dev/null; then
1693 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "darcs" "darcs"
1694 return 0
1696 msg "$(gettext "Determining latest %s revision...")" 'darcs'
1697 newpkgver=$(date +%Y%m%d)
1698 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1699 if ! type -p cvs >/dev/null; then
1700 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "cvs" "cvs"
1701 return 0
1703 msg "$(gettext "Determining latest %s revision...")" 'cvs'
1704 newpkgver=$(date +%Y%m%d)
1705 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1706 if ! type -p git >/dev/null; then
1707 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "git" "git"
1708 return 0
1710 msg "$(gettext "Determining latest %s revision...")" 'git'
1711 newpkgver=$(date +%Y%m%d)
1712 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1713 if ! type -p svn >/dev/null; then
1714 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "svn" "svn"
1715 return 0
1717 msg "$(gettext "Determining latest %s revision...")" 'svn'
1718 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1719 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1720 if ! type -p bzr >/dev/null; then
1721 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "bzr" "bzr"
1722 return 0
1724 msg "$(gettext "Determining latest %s revision...")" 'bzr'
1725 newpkgver=$(bzr revno ${_bzrtrunk})
1726 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1727 if ! type -p hg >/dev/null; then
1728 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "hg" "hg"
1729 return 0
1731 msg "$(gettext "Determining latest %s revision...")" 'hg'
1732 if [[ -d ./src/$_hgrepo ]] ; then
1733 cd ./src/$_hgrepo
1734 hg pull
1735 hg update
1736 else
1737 [[ ! -d ./src/ ]] && mkdir ./src/
1738 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1739 cd ./src/$_hgrepo
1741 newpkgver=$(hg tip --template "{rev}")
1742 cd ../../
1745 if [[ -n $newpkgver ]]; then
1746 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1749 else
1750 # Version number retrieved from fakeroot->makepkg argument
1751 newpkgver=$FORCE_VER
1755 devel_update() {
1756 # This is lame, but if we're wanting to use an updated pkgver for
1757 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1758 # the new pkgver and then re-source it. This is the most robust
1759 # method for dealing with PKGBUILDs that use, e.g.:
1761 # pkgver=23
1762 # ...
1763 # _foo=pkgver
1765 if [[ -n $newpkgver ]]; then
1766 if [[ $newpkgver != "$pkgver" ]]; then
1767 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1768 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1769 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1770 source "$BUILDFILE"
1776 backup_package_variables() {
1777 local var
1778 for var in ${splitpkg_overrides[@]}; do
1779 local indirect="${var}_backup"
1780 eval "${indirect}=(\"\${$var[@]}\")"
1781 done
1784 restore_package_variables() {
1785 local var
1786 for var in ${splitpkg_overrides[@]}; do
1787 local indirect="${var}_backup"
1788 if [[ -n ${!indirect} ]]; then
1789 eval "${var}=(\"\${$indirect[@]}\")"
1790 else
1791 unset ${var}
1793 done
1796 run_split_packaging() {
1797 local pkgname_backup=${pkgname[@]}
1798 for pkgname in ${pkgname_backup[@]}; do
1799 pkgdir="$pkgdir/$pkgname"
1800 mkdir -p "$pkgdir"
1801 chmod a-s "$pkgdir"
1802 backup_package_variables
1803 run_package $pkgname
1804 tidy_install
1805 create_package $pkgname
1806 restore_package_variables
1807 pkgdir="${pkgdir%/*}"
1808 done
1809 pkgname=${pkgname_backup[@]}
1812 # Canonicalize a directory path if it exists
1813 canonicalize_path() {
1814 local path="$1";
1816 if [[ -d $path ]]; then
1818 cd "$path"
1819 pwd -P
1821 else
1822 echo "$path"
1826 m4_include(library/parse_options.sh)
1828 usage() {
1829 printf "makepkg (pacman) %s\n" "$myver"
1830 echo
1831 printf "$(gettext "Usage: %s [options]")\n" "$0"
1832 echo
1833 echo "$(gettext "Options:")"
1834 printf "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
1835 echo "$(gettext " -c, --clean Clean up work files after build")"
1836 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1837 printf "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
1838 echo "$(gettext " -f, --force Overwrite existing package")"
1839 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1840 echo "$(gettext " -h, --help Show this help message and exit")"
1841 echo "$(gettext " -i, --install Install package after successful build")"
1842 echo "$(gettext " -L, --log Log package build process")"
1843 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1844 echo "$(gettext " -o, --nobuild Download and extract files only")"
1845 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1846 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1847 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1848 printf "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
1849 echo "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")"
1850 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1851 printf "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
1852 printf "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1853 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1854 printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1855 printf "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
1856 printf "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1857 echo "$(gettext " --nosign Do not create a signature for the package")"
1858 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1859 printf "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
1860 echo "$(gettext " --skipchecksums Do not verify checksums of the source files")"
1861 echo "$(gettext " --skipinteg Do not perform any verification checks on source files")"
1862 echo "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")"
1863 echo
1864 printf "$(gettext "These options can be passed to %s:")\n" "pacman"
1865 echo
1866 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1867 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1868 echo
1869 printf "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
1870 echo
1873 version() {
1874 printf "makepkg (pacman) %s\n" "$myver"
1875 printf "$(gettext "\
1876 Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1877 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1878 This is free software; see the source for copying conditions.\n\
1879 There is NO WARRANTY, to the extent permitted by law.\n")"
1882 # PROGRAM START
1884 # determine whether we have gettext; make it a no-op if we do not
1885 if ! type -p gettext >/dev/null; then
1886 gettext() {
1887 echo "$@"
1891 ARGLIST=("$@")
1893 # Parse Command Line Options.
1894 OPT_SHORT="AcdefFghiLmop:rRsSV"
1895 OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
1896 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck"
1897 OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
1898 OPT_LONG+=",repackage,skipchecksums,skipinteg,skippgpcheck,sign,source,syncdeps"
1899 OPT_LONG+=",version,config:"
1901 # Pacman Options
1902 OPT_LONG+=",noconfirm,noprogressbar"
1903 if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
1904 echo; usage; exit 1 # E_INVALID_OPTION;
1906 eval set -- "$OPT_TEMP"
1907 unset OPT_SHORT OPT_LONG OPT_TEMP
1909 while true; do
1910 case "$1" in
1911 # Pacman Options
1912 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1913 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1915 # Makepkg Options
1916 --allsource) SOURCEONLY=2 ;;
1917 --asroot) ASROOT=1 ;;
1918 -A|--ignorearch) IGNOREARCH=1 ;;
1919 -c|--clean) CLEANUP=1 ;;
1920 --check) RUN_CHECK='y' ;;
1921 --config) shift; MAKEPKG_CONF=$1 ;;
1922 -d|--nodeps) NODEPS=1 ;;
1923 -e|--noextract) NOEXTRACT=1 ;;
1924 -f|--force) FORCE=1 ;;
1925 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1926 --forcever) shift; FORCE_VER=$1;;
1927 -F) INFAKEROOT=1 ;;
1928 -g|--geninteg) GENINTEG=1 ;;
1929 --holdver) HOLDVER=1 ;;
1930 -i|--install) INSTALL=1 ;;
1931 --key) shift; GPGKEY=$1 ;;
1932 -L|--log) LOGGING=1 ;;
1933 -m|--nocolor) USE_COLOR='n' ;;
1934 --nocheck) RUN_CHECK='n' ;;
1935 --nosign) SIGNPKG='n' ;;
1936 -o|--nobuild) NOBUILD=1 ;;
1937 -p) shift; BUILDFILE=$1 ;;
1938 --pkg) shift; PKGLIST=($1) ;;
1939 -r|--rmdeps) RMDEPS=1 ;;
1940 -R|--repackage) REPKG=1 ;;
1941 --skipchecksums) SKIPCHECKSUMS=1 ;;
1942 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
1943 --skippgpcheck) SKIPPGPCHECK=1;;
1944 --sign) SIGNPKG='y' ;;
1945 -s|--syncdeps) DEP_BIN=1 ;;
1946 -S|--source) SOURCEONLY=1 ;;
1948 -h|--help) usage; exit 0 ;; # E_OK
1949 -V|--version) version; exit 0 ;; # E_OK
1951 --) OPT_IND=0; shift; break;;
1952 *) usage; exit 1 ;; # E_INVALID_OPTION
1953 esac
1954 shift
1955 done
1957 # preserve environment variables and canonicalize path
1958 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
1959 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
1960 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
1961 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
1962 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
1963 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
1964 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
1966 # default config is makepkg.conf
1967 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1969 # Source the config file; fail if it is not found
1970 if [[ -r $MAKEPKG_CONF ]]; then
1971 source "$MAKEPKG_CONF"
1972 else
1973 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1974 plain "$(gettext "Aborting...")"
1975 exit 1 # $E_CONFIG_ERROR
1978 # Source user-specific makepkg.conf overrides, but only if no override config
1979 # file was specified
1980 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
1981 source ~/.makepkg.conf
1984 # set pacman command if not already defined
1985 PACMAN=${PACMAN:-pacman}
1987 # check if messages are to be printed using color
1988 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1989 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1990 # prefer terminal safe colored and bold text when tput is supported
1991 if tput setaf 0 &>/dev/null; then
1992 ALL_OFF="$(tput sgr0)"
1993 BOLD="$(tput bold)"
1994 BLUE="${BOLD}$(tput setaf 4)"
1995 GREEN="${BOLD}$(tput setaf 2)"
1996 RED="${BOLD}$(tput setaf 1)"
1997 YELLOW="${BOLD}$(tput setaf 3)"
1998 else
1999 ALL_OFF="\e[1;0m"
2000 BOLD="\e[1;1m"
2001 BLUE="${BOLD}\e[1;34m"
2002 GREEN="${BOLD}\e[1;32m"
2003 RED="${BOLD}\e[1;31m"
2004 YELLOW="${BOLD}\e[1;33m"
2007 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2009 # override settings with an environment variable for batch processing
2010 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2011 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2012 if [[ ! -d $BUILDDIR ]]; then
2013 mkdir -p "$BUILDDIR" ||
2014 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2015 chmod a-s "$BUILDDIR"
2017 if [[ ! -w $BUILDDIR ]]; then
2018 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2019 plain "$(gettext "Aborting...")"
2020 exit 1
2022 srcdir="$BUILDDIR/src"
2023 pkgdir="$BUILDDIR/pkg"
2025 PKGDEST=${_PKGDEST:-$PKGDEST}
2026 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2027 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2028 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2029 plain "$(gettext "Aborting...")"
2030 exit 1
2033 SRCDEST=${_SRCDEST:-$SRCDEST}
2034 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2035 if [[ ! -w $SRCDEST ]] ; then
2036 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2037 plain "$(gettext "Aborting...")"
2038 exit 1
2041 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2042 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2044 PKGEXT=${_PKGEXT:-$PKGEXT}
2045 SRCEXT=${_SRCEXT:-$SRCEXT}
2046 GPGKEY=${_GPGKEY:-$GPGKEY}
2048 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
2049 # The '\\0' is here to prevent gettext from thinking --holdver is an option
2050 error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
2051 exit 1
2054 if (( ! INFAKEROOT )); then
2055 if (( EUID == 0 && ! ASROOT )); then
2056 # Warn those who like to live dangerously.
2057 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2058 catastrophic damage to your system. If you wish to run as root, please\n\
2059 use the %s option.")" "makepkg" "--asroot"
2060 exit 1 # $E_USER_ABORT
2061 elif (( EUID > 0 && ASROOT )); then
2062 # Warn those who try to use the --asroot option when they are not root
2063 error "$(gettext "The %s option is meant for the root user only. Please\n\
2064 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2065 exit 1 # $E_USER_ABORT
2066 elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
2067 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2068 ownership of the packaged files. Try using the %s environment by\n\
2069 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF"
2070 sleep 1
2072 else
2073 if [[ -z $FAKEROOTKEY ]]; then
2074 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2075 exit 1 # TODO: error code
2079 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2080 unset md5sums replaces depends conflicts backup source install changelog build
2081 unset makedepends optdepends options noextract
2083 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2084 if [[ ! -f $BUILDFILE ]]; then
2085 if [[ -t 0 ]]; then
2086 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2087 exit 1
2088 else
2089 # PKGBUILD passed through a pipe
2090 BUILDFILE=/dev/stdin
2091 source "$BUILDFILE"
2093 else
2094 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2095 if [[ -n $crlftest ]]; then
2096 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2097 exit 1
2100 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2101 BUILDFILE="$startdir/$BUILDFILE"
2103 source "$BUILDFILE"
2106 # set defaults if they weren't specified in buildfile
2107 pkgbase=${pkgbase:-${pkgname[0]}}
2108 epoch=${epoch:-0}
2110 if (( GENINTEG )); then
2111 mkdir -p "$srcdir"
2112 chmod a-s "$srcdir"
2113 cd "$srcdir"
2114 download_sources
2115 generate_checksums
2116 exit 0 # $E_OK
2119 # check the PKGBUILD for some basic requirements
2120 check_sanity || exit 1
2122 # check we have the software required to process the PKGBUILD
2123 check_software || exit 1
2125 # We need to run devel_update regardless of whether we are in the fakeroot
2126 # build process so that if the user runs makepkg --forcever manually, we
2127 # 1) output the correct pkgver, and 2) use the correct filename when
2128 # checking if the package file already exists - fixes FS #9194
2129 devel_check
2130 devel_update
2132 if (( ${#pkgname[@]} > 1 )); then
2133 SPLITPKG=1
2136 # test for available PKGBUILD functions
2137 if declare -f build >/dev/null; then
2138 BUILDFUNC=1
2140 if declare -f check >/dev/null; then
2141 # "Hide" check() function if not going to be run
2142 if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then
2143 CHECKFUNC=1
2146 if declare -f package >/dev/null; then
2147 PKGFUNC=1
2148 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
2149 SPLITPKG=1
2152 if [[ -n "${PKGLIST[@]}" ]]; then
2153 unset pkgname
2154 pkgname=("${PKGLIST[@]}")
2157 # check if gpg signature is to be created and if signing key is valid
2158 [[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign)
2159 if [[ $SIGNPKG == 'y' ]]; then
2160 if ! gpg --list-key ${GPGKEY} &>/dev/null; then
2161 if [[ ! -z $GPGKEY ]]; then
2162 error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2163 else
2164 error "$(gettext "There is no key in your keyring.")"
2166 exit 1
2171 if (( ! SPLITPKG )); then
2172 fullver=$(get_full_version)
2173 if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \
2174 || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \
2175 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2176 if (( INSTALL )); then
2177 warning "$(gettext "A package has already been built, installing existing package...")"
2178 install_package
2179 exit $?
2180 else
2181 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2182 exit 1
2185 else
2186 allpkgbuilt=1
2187 somepkgbuilt=0
2188 for pkg in ${pkgname[@]}; do
2189 fullver=$(get_full_version $pkg)
2190 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \
2191 || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then
2192 somepkgbuilt=1
2193 else
2194 allpkgbuilt=0
2196 done
2197 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2198 if (( allpkgbuilt )); then
2199 if (( INSTALL )); then
2200 warning "$(gettext "The package group has already been built, installing existing packages...")"
2201 install_package
2202 exit $?
2203 else
2204 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2205 exit 1
2208 if (( somepkgbuilt )); then
2209 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2210 exit 1
2213 unset allpkgbuilt somepkgbuilt
2216 # Run the bare minimum in fakeroot
2217 if (( INFAKEROOT )); then
2218 if (( SOURCEONLY )); then
2219 create_srcpackage
2220 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2221 exit 0 # $E_OK
2224 if (( ! SPLITPKG )); then
2225 if (( ! PKGFUNC )); then
2226 if (( ! REPKG )); then
2227 if (( BUILDFUNC )); then
2228 run_build
2229 (( CHECKFUNC )) && run_check
2230 tidy_install
2232 else
2233 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2234 plain "$(gettext "File permissions may not be preserved.")"
2236 else
2237 run_package
2238 tidy_install
2240 create_package
2241 else
2242 run_split_packaging
2245 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2246 exit 0 # $E_OK
2249 fullver=$(get_full_version)
2250 msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2252 # if we are creating a source-only package, go no further
2253 if (( SOURCEONLY )); then
2254 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2255 && (( ! FORCE )); then
2256 error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2257 exit 1
2260 # Get back to our src directory so we can begin with sources.
2261 mkdir -p "$srcdir"
2262 chmod a-s "$srcdir"
2263 cd "$srcdir"
2264 if ( (( ! SKIPCHECKSUMS )) || \
2265 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \
2266 (( SOURCEONLY == 2 )); then
2267 download_sources
2269 check_source_integrity
2270 cd "$startdir"
2272 # if we are root or if fakeroot is not enabled, then we don't use it
2273 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2274 create_srcpackage
2275 else
2276 enter_fakeroot
2279 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2280 exit 0
2283 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
2284 # no warning message needed for nobuild, repkg
2285 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
2286 warning "$(gettext "Skipping dependency checks.")"
2288 elif type -p "${PACMAN%% *}" >/dev/null; then
2289 if (( RMDEPS )); then
2290 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2292 deperr=0
2294 msg "$(gettext "Checking runtime dependencies...")"
2295 resolve_deps ${depends[@]} || deperr=1
2297 msg "$(gettext "Checking buildtime dependencies...")"
2298 resolve_deps ${makedepends[@]} || deperr=1
2300 if (( CHECKFUNC )); then
2301 resolve_deps ${checkdepends[@]} || deperr=1
2304 if (( RMDEPS )); then
2305 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2308 if (( deperr )); then
2309 error "$(gettext "Could not resolve all dependencies.")"
2310 exit 1
2312 else
2313 warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
2316 # ensure we have a sane umask set
2317 umask 0022
2319 # get back to our src directory so we can begin with sources
2320 mkdir -p "$srcdir"
2321 chmod a-s "$srcdir"
2322 cd "$srcdir"
2324 if (( NOEXTRACT )); then
2325 warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
2326 warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
2327 warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
2329 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
2330 error "$(gettext "The source directory is empty, there is nothing to build!")"
2331 plain "$(gettext "Aborting...")"
2332 exit 1
2334 elif (( REPKG )); then
2335 if (( ! PKGFUNC && ! SPLITPKG )) \
2336 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
2337 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2338 plain "$(gettext "Aborting...")"
2339 exit 1
2341 else
2342 download_sources
2343 check_source_integrity
2344 extract_sources
2347 if (( NOBUILD )); then
2348 msg "$(gettext "Sources are ready.")"
2349 exit 0 #E_OK
2350 else
2351 # check for existing pkg directory; don't remove if we are repackaging
2352 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2353 msg "$(gettext "Removing existing %s directory...")" "pkg/"
2354 rm -rf "$pkgdir"
2356 mkdir -p "$pkgdir"
2357 chmod a-s "$pkgdir"
2358 cd "$startdir"
2360 # if we are root or if fakeroot is not enabled, then we don't use it
2361 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2362 if (( ! REPKG )); then
2363 devel_update
2364 (( BUILDFUNC )) && run_build
2365 (( CHECKFUNC )) && run_check
2367 if (( ! SPLITPKG )); then
2368 if (( PKGFUNC )); then
2369 run_package
2370 tidy_install
2371 else
2372 if (( ! REPKG )); then
2373 tidy_install
2374 else
2375 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2376 plain "$(gettext "File permissions may not be preserved.")"
2379 create_package
2380 else
2381 run_split_packaging
2383 else
2384 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2385 devel_update
2386 (( BUILDFUNC )) && run_build
2387 (( CHECKFUNC )) && run_check
2388 cd "$startdir"
2391 enter_fakeroot
2395 fullver=$(get_full_version)
2396 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
2398 install_package
2400 exit 0 #E_OK
2402 # vim: set ts=2 sw=2 noet: