makepkg: unset errexit when sourcing /etc/profile
[pacman-ng.git] / scripts / makepkg.sh.in
blobb678f7e50937234537134806b1d67148708ed04c
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)\n' "$(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)\n' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
751 warnings=1
752 elif grep -q "EXPKEYSIG" "$statusfile"; then
753 printf ' (%s)\n' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
754 warnings=1
758 done
760 rm -f "$statusfile"
762 if (( errors )); then
763 error "$(gettext "One or more PGP signatures could not be verified!")"
764 exit 1
767 if (( warnings )); then
768 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
769 plain "$(gettext "Please make sure you really trust them.")"
773 check_source_integrity() {
774 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
775 warning "$(gettext "Skipping all source file integrity checks.")"
776 elif (( SKIPCHECKSUMS )); then
777 warning "$(gettext "Skipping verification of source file checksums.")"
778 check_pgpsigs
779 elif (( SKIPPGPCHECK )); then
780 warning "$(gettext "Skipping verification of source file PGP signatures.")"
781 check_checksums
782 else
783 check_checksums
784 check_pgpsigs
788 extract_sources() {
789 msg "$(gettext "Extracting Sources...")"
790 local netfile
791 for netfile in "${source[@]}"; do
792 local file=$(get_filename "$netfile")
793 if in_array "$file" "${noextract[@]}"; then
794 #skip source files in the noextract=() array
795 # these are marked explicitly to NOT be extracted
796 continue
800 # fix flyspray #6246
801 local file_type=$(file -bizL "$file")
802 local ext=${file##*.}
803 local cmd=''
804 case "$file_type" in
805 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
806 cmd="bsdtar" ;;
807 *application/x-gzip*)
808 case "$ext" in
809 gz|z|Z) cmd="gzip" ;;
810 *) continue;;
811 esac ;;
812 *application/x-bzip*)
813 case "$ext" in
814 bz2|bz) cmd="bzip2" ;;
815 *) continue;;
816 esac ;;
817 *application/x-xz*)
818 case "$ext" in
819 xz) cmd="xz" ;;
820 *) continue;;
821 esac ;;
823 # See if bsdtar can recognize the file
824 if bsdtar -tf "$file" -q '*' &>/dev/null; then
825 cmd="bsdtar"
826 else
827 continue
828 fi ;;
829 esac
831 local ret=0
832 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
833 if [[ $cmd = bsdtar ]]; then
834 $cmd -xf "$file" || ret=$?
835 else
836 rm -f "${file%.*}"
837 $cmd -dcf "$file" > "${file%.*}" || ret=$?
839 if (( ret )); then
840 error "$(gettext "Failed to extract %s")" "$file"
841 plain "$(gettext "Aborting...")"
842 exit 1
844 done
846 if (( EUID == 0 )); then
847 # change perms of all source files to root user & root group
848 chown -R 0:0 "$srcdir"
852 error_function() {
853 if [[ -p $logpipe ]]; then
854 rm "$logpipe"
856 # first exit all subshells, then print the error
857 if (( ! BASH_SUBSHELL )); then
858 error "$(gettext "A failure occurred in %s().")" "$1"
859 plain "$(gettext "Aborting...")"
860 remove_deps
862 exit 2 # $E_BUILD_FAILED
865 run_function() {
866 if [[ -z $1 ]]; then
867 return 1
869 local pkgfunc="$1"
871 # clear user-specified buildflags if requested
872 if [[ $(check_option buildflags) = "n" ]]; then
873 unset CFLAGS CXXFLAGS LDFLAGS
876 # clear user-specified makeflags if requested
877 if [[ $(check_option makeflags) = "n" ]]; then
878 unset MAKEFLAGS
881 msg "$(gettext "Starting %s()...")" "$pkgfunc"
882 cd "$srcdir"
884 # ensure all necessary build variables are exported
885 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
886 # save our shell options so pkgfunc() can't override what we need
887 local shellopts=$(shopt -p)
889 local ret=0
890 local restoretrap
891 if (( LOGGING )); then
892 local fullver=$(get_full_version)
893 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
894 if [[ -f $BUILDLOG ]]; then
895 local i=1
896 while true; do
897 if [[ -f $BUILDLOG.$i ]]; then
898 i=$(($i +1))
899 else
900 break
902 done
903 mv "$BUILDLOG" "$BUILDLOG.$i"
906 # ensure overridden package variables survive tee with split packages
907 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
908 mkfifo "$logpipe"
909 tee "$BUILDLOG" < "$logpipe" &
910 local teepid=$!
912 restoretrap=$(trap -p ERR)
913 trap 'error_function $pkgfunc' ERR
914 $pkgfunc &>"$logpipe"
915 eval $restoretrap
917 wait $teepid
918 rm "$logpipe"
919 else
920 restoretrap=$(trap -p ERR)
921 trap 'error_function $pkgfunc' ERR
922 $pkgfunc 2>&1
923 eval $restoretrap
925 # reset our shell options
926 eval "$shellopts"
929 run_build() {
930 # use distcc if it is requested (check buildenv and PKGBUILD opts)
931 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
932 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
933 export DISTCC_HOSTS
936 # use ccache if it is requested (check buildenv and PKGBUILD opts)
937 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
938 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
941 run_function "build"
944 run_check() {
945 run_function "check"
948 run_package() {
949 local pkgfunc
950 if [[ -z $1 ]]; then
951 pkgfunc="package"
952 else
953 pkgfunc="package_$1"
956 run_function "$pkgfunc"
959 tidy_install() {
960 cd "$pkgdir"
961 msg "$(gettext "Tidying install...")"
963 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
964 msg2 "$(gettext "Removing doc files...")"
965 rm -rf ${DOC_DIRS[@]}
968 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
969 msg2 "$(gettext "Purging unwanted files...")"
970 local pt
971 for pt in "${PURGE_TARGETS[@]}"; do
972 if [[ ${pt} = ${pt//\/} ]]; then
973 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
974 else
975 rm -f ${pt}
977 done
980 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
981 msg2 "$(gettext "Compressing man and info pages...")"
982 local manpage ext file link hardlinks hl
983 find ${MAN_DIRS[@]} -type f 2>/dev/null |
984 while read manpage ; do
985 ext="${manpage##*.}"
986 file="${manpage##*/}"
987 if [[ $ext != gz && $ext != bz2 ]]; then
988 # update symlinks to this manpage
989 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
990 while read link ; do
991 rm -f "$link" "${link}.gz"
992 ln -s "${file}.gz" "${link}.gz"
993 done
995 # check file still exists (potentially already compressed due to hardlink)
996 if [[ -f ${manpage} ]]; then
997 # find hard links and remove them
998 # the '|| true' part keeps the script from bailing if find returned an
999 # error, such as when one of the man directories doesn't exist
1000 find "${MAN_DIRS[@]}" \! -name "$file" -samefile "$manpage" \
1001 -exec rm -f {} \; 2>/dev/null || true
1002 # compress the original
1003 gzip -9 "$manpage"
1004 # recreate hard links removed earlier
1005 for hl in ${hardlinks}; do
1006 ln "${manpage}.gz" "${hl}.gz"
1007 chmod 644 ${hl}.gz
1008 done
1011 done
1014 if [[ $(check_option strip) = y ]]; then
1015 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1016 # make sure library stripping variables are defined to prevent excess stripping
1017 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1018 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1019 local binary
1020 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1021 case "$(file -bi "$binary")" in
1022 *application/x-sharedlib*) # Libraries (.so)
1023 strip $STRIP_SHARED "$binary";;
1024 *application/x-archive*) # Libraries (.a)
1025 strip $STRIP_STATIC "$binary";;
1026 *application/x-executable*) # Binaries
1027 strip $STRIP_BINARIES "$binary";;
1028 esac
1029 done
1032 if [[ $(check_option libtool) = "n" ]]; then
1033 msg2 "$(gettext "Removing "%s" files...")" "libtool"
1034 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
1037 if [[ $(check_option emptydirs) = "n" ]]; then
1038 msg2 "$(gettext "Removing empty directories...")"
1039 find . -depth -type d -empty -delete
1042 if [[ $(check_option upx) = "y" ]]; then
1043 msg2 "$(gettext "Compressing binaries with %s...")" "UPX"
1044 local binary
1045 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1046 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1047 upx $UPXFLAGS "$binary" &>/dev/null ||
1048 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1050 done
1054 find_libdepends() {
1055 local libdepends
1056 find "$pkgdir" -type f -perm -u+x | while read filename
1058 # get architecture of the file; if soarch is empty it's not an ELF binary
1059 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1060 [ -n "$soarch" ] || continue
1061 # process all libraries needed by the binary
1062 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1064 # extract the library name: libfoo.so
1065 soname="${sofile%%\.so\.*}.so"
1066 # extract the major version: 1
1067 soversion="${sofile##*\.so\.}"
1068 if in_array "${soname}" ${depends[@]}; then
1069 if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then
1070 # libfoo.so=1-64
1071 echo "${soname}=${soversion}-${soarch}"
1072 libdepends=(${libdepends[@]} "${soname}=${soversion}-${soarch}")
1075 done
1076 done
1079 find_libprovides() {
1080 local libprovides
1081 find "$pkgdir" -type f -name \*.so\* | while read filename
1083 # check if we really have a shared object
1084 if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1085 # 64
1086 soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1087 # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1
1088 sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1089 [ -z "$sofile" ] && sofile="${filename##*/}"
1091 # extract the library name: libfoo.so
1092 soname="${sofile%%\.so\.*}.so"
1093 # extract the major version: 1
1094 soversion="${sofile##*\.so\.}"
1095 if in_array "${soname}" ${provides[@]}; then
1096 if ! in_array "${soname}=${soversion}-${soarch}" ${libprovides[@]}; then
1097 # libfoo.so=1-64
1098 echo "${soname}=${soversion}-${soarch}"
1099 libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
1103 done
1106 write_pkginfo() {
1107 local builddate=$(date -u "+%s")
1108 if [[ -n $PACKAGER ]]; then
1109 local packager="$PACKAGER"
1110 else
1111 local packager="Unknown Packager"
1113 local size="$(@DUPATH@ -sk)"
1114 size="$(( ${size%%[^0-9]*} * 1024 ))"
1116 msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
1117 echo "# Generated by makepkg $myver"
1118 if (( INFAKEROOT )); then
1119 echo "# using $(fakeroot -v)"
1121 echo "# $(LC_ALL=C date -u)"
1122 echo "pkgname = $1"
1123 (( SPLITPKG )) && echo pkgbase = $pkgbase
1124 echo "pkgver = $(get_full_version)"
1125 echo "pkgdesc = $pkgdesc"
1126 echo "url = $url"
1127 echo "builddate = $builddate"
1128 echo "packager = $packager"
1129 echo "size = $size"
1130 echo "arch = $PKGARCH"
1132 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1133 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1134 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1135 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}"
1136 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1137 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1139 local it
1141 libprovides=$(find_libprovides)
1142 libdepends=$(find_libdepends)
1143 provides=("${provides[@]}" ${libprovides})
1144 depends=("${depends[@]}" ${libdepends})
1146 for it in "${depends[@]}"; do
1147 if [[ $it = *.so ]]; then
1148 # check if the entry has been found by find_libdepends
1149 # if not, it's unneeded; tell the user so he can remove it
1150 if [[ ! $libdepends =~ (^|\s)${it}=.* ]]; then
1151 error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it"
1152 return 1
1154 else
1155 echo "depend = $it"
1157 done
1159 for it in "${provides[@]}"; do
1160 # ignore versionless entires (those come from the PKGBUILD)
1161 if [[ $it = *.so ]]; then
1162 # check if the entry has been found by find_libprovides
1163 # if not, it's unneeded; tell the user so he can remove it
1164 if [[ ! $libprovides =~ (^|\s)${it}=.* ]]; then
1165 error "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$it"
1166 return 1
1168 else
1169 echo "provides = $it"
1171 done
1173 for it in "${packaging_options[@]}"; do
1174 local ret="$(check_option $it)"
1175 if [[ $ret != "?" ]]; then
1176 if [[ $ret = y ]]; then
1177 echo "makepkgopt = $it"
1178 else
1179 echo "makepkgopt = !$it"
1182 done
1184 # TODO maybe remove this at some point
1185 # warn if license array is not present or empty
1186 if [[ -z $license ]]; then
1187 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1188 plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
1192 check_package() {
1193 cd "$pkgdir"
1195 # check existence of backup files
1196 local file
1197 for file in "${backup[@]}"; do
1198 if [[ ! -f $file ]]; then
1199 warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
1201 done
1203 # check for references to the build and package directory
1204 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1205 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
1207 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
1208 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
1213 create_package() {
1214 if [[ ! -d $pkgdir ]]; then
1215 error "$(gettext "Missing %s directory.")" "pkg/"
1216 plain "$(gettext "Aborting...")"
1217 exit 1 # $E_MISSING_PKGDIR
1220 check_package
1222 cd "$pkgdir"
1223 msg "$(gettext "Creating package...")"
1225 local nameofpkg
1226 if [[ -z $1 ]]; then
1227 nameofpkg="$pkgname"
1228 else
1229 nameofpkg="$1"
1232 if [[ $arch = "any" ]]; then
1233 PKGARCH="any"
1234 else
1235 PKGARCH=$CARCH
1238 write_pkginfo $nameofpkg > .PKGINFO
1240 local comp_files=".PKGINFO"
1242 # check for changelog/install files
1243 for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1244 IFS='/' read -r orig dest < <(printf '%s\n' "$i")
1246 if [[ -n ${!orig} ]]; then
1247 msg2 "$(gettext "Adding %s file...")" "$orig"
1248 cp "$startdir/${!orig}" "$dest"
1249 chmod 644 "$dest"
1250 comp_files+=" $dest"
1252 done
1254 # tar it up
1255 msg2 "$(gettext "Compressing package...")"
1257 local EXT
1258 case "$PKGEXT" in
1259 *tar.gz) EXT=${PKGEXT%.gz} ;;
1260 *tar.bz2) EXT=${PKGEXT%.bz2} ;;
1261 *tar.xz) EXT=${PKGEXT%.xz} ;;
1262 *tar.Z) EXT=${PKGEXT%.Z} ;;
1263 *tar) EXT=${PKGEXT} ;;
1264 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1265 "$PKGEXT" ; EXT=$PKGEXT ;;
1266 esac
1268 local fullver=$(get_full_version)
1269 local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}"
1270 local ret=0
1272 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1273 [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
1275 # when fileglobbing, we want * in an empty directory to expand to
1276 # the null string rather than itself
1277 shopt -s nullglob
1278 # TODO: Maybe this can be set globally for robustness
1279 shopt -s -o pipefail
1280 bsdtar -cf - $comp_files * |
1281 case "$PKGEXT" in
1282 *tar.gz) gzip -c -f -n ;;
1283 *tar.bz2) bzip2 -c -f ;;
1284 *tar.xz) xz -c -z - ;;
1285 *tar.Z) compress -c -f ;;
1286 *tar) cat ;;
1287 esac > "${pkg_file}" || ret=$?
1289 shopt -u nullglob
1290 shopt -u -o pipefail
1292 if (( ret )); then
1293 error "$(gettext "Failed to create package file.")"
1294 exit 1 # TODO: error code
1297 create_signature "$pkg_file"
1299 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1300 rm -f "${pkg_file/$PKGDEST/$startdir}"
1301 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1302 ret=$?
1303 if [[ -f $pkg_file.sig ]]; then
1304 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1305 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1309 if (( ret )); then
1310 warning "$(gettext "Failed to create symlink to package file.")"
1314 create_signature() {
1315 if [[ $SIGNPKG != 'y' ]]; then
1316 return
1318 local ret=0
1319 local filename="$1"
1320 msg "$(gettext "Signing package...")"
1322 local SIGNWITHKEY=""
1323 if [[ -n $GPGKEY ]]; then
1324 SIGNWITHKEY="-u ${GPGKEY}"
1326 # The signature will be generated directly in ascii-friendly format
1327 gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
1330 if (( ! ret )); then
1331 msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
1332 else
1333 warning "$(gettext "Failed to sign package file.")"
1337 create_srcpackage() {
1338 msg "$(gettext "Creating source package...")"
1339 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1340 mkdir "${srclinks}"/${pkgbase}
1342 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1343 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1345 local file
1346 for file in "${source[@]}"; do
1347 if [[ -f $file ]]; then
1348 msg2 "$(gettext "Adding %s...")" "$file"
1349 ln -s "${startdir}/$file" "$srclinks/$pkgbase"
1350 elif (( SOURCEONLY == 2 )); then
1351 local absfile=$(get_filepath "$file") || missing_source_file "$file"
1352 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1353 ln -s "$absfile" "$srclinks/$pkgbase"
1355 done
1357 local i
1358 for i in 'changelog' 'install'; do
1359 local file
1360 while read -r file; do
1361 # evaluate any bash variables used
1362 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1363 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1364 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1365 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1367 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1368 done
1370 local TAR_OPT
1371 case "$SRCEXT" in
1372 *tar.gz) TAR_OPT="z" ;;
1373 *tar.bz2) TAR_OPT="j" ;;
1374 *tar.xz) TAR_OPT="J" ;;
1375 *tar) TAR_OPT="" ;;
1376 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1377 "$SRCEXT" ;;
1378 esac
1380 local fullver=$(get_full_version)
1381 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1383 # tar it up
1384 msg2 "$(gettext "Compressing source package...")"
1385 cd "${srclinks}"
1386 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1387 error "$(gettext "Failed to create source package file.")"
1388 exit 1 # TODO: error code
1391 if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1392 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1393 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1394 ret=$?
1397 if (( ret )); then
1398 warning "$(gettext "Failed to create symlink to source package file.")"
1401 cd "${startdir}"
1402 rm -rf "${srclinks}"
1405 install_package() {
1406 (( ! INSTALL )) && return
1408 if (( ! SPLITPKG )); then
1409 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1410 else
1411 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1414 local fullver pkg pkglist
1415 for pkg in ${pkgname[@]}; do
1416 fullver=$(get_full_version $pkg)
1417 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then
1418 pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}"
1419 else
1420 pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}"
1422 done
1424 if ! run_pacman -U $pkglist; then
1425 warning "$(gettext "Failed to install built package(s).")"
1426 return 0
1430 check_sanity() {
1431 # check for no-no's in the build script
1432 local i
1433 local ret=0
1434 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1435 if [[ -z ${!i} ]]; then
1436 error "$(gettext "%s is not allowed to be empty.")" "$i"
1437 ret=1
1439 done
1441 for i in "${pkgname[@]}"; do
1442 if [[ ${i:0:1} = "-" ]]; then
1443 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1444 ret=1
1446 done
1448 if [[ ${pkgbase:0:1} = "-" ]]; then
1449 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1450 ret=1
1453 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" |
1454 while IFS='=' read -r _ i; do
1455 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1456 if [[ $i = *[[:space:]:-]* ]]; then
1457 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1458 return 1
1460 done || ret=1
1462 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" |
1463 while IFS='=' read -r _ i; do
1464 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1465 if [[ $i = *[[:space:]-]* ]]; then
1466 error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel"
1467 return 1
1469 done || ret=1
1471 awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
1472 while IFS='=' read -r _ i; do
1473 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1474 if [[ $i != *([[:digit:]]) ]]; then
1475 error "$(gettext "%s must be an integer.")" "epoch"
1476 return 1
1478 done || ret=1
1480 if [[ $arch != 'any' ]]; then
1481 if ! in_array $CARCH ${arch[@]}; then
1482 if (( ! IGNOREARCH )); then
1483 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1484 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1485 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1486 ret=1
1491 if (( ${#pkgname[@]} > 1 )); then
1492 for i in ${pkgname[@]}; do
1493 local arch_list=""
1494 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1495 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1496 if ! in_array $CARCH ${arch_list[@]}; then
1497 if (( ! IGNOREARCH )); then
1498 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1499 ret=1
1503 done
1506 local provides_list=()
1507 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1508 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1509 for i in ${provides_list[@]}; do
1510 if [[ $i != ${i//</} || $i != ${i//>/} ]]; then
1511 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1512 ret=1
1514 done
1516 local backup_list=()
1517 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1518 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1519 for i in "${backup_list[@]}"; do
1520 if [[ ${i:0:1} = "/" ]]; then
1521 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1522 ret=1
1524 done
1526 local optdepends_list=()
1527 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1528 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1529 for i in "${optdepends_list[@]}"; do
1530 local pkg=${i%%:*}
1531 if [[ $pkg != +([[:alnum:]><=.+_-]) ]]; then
1532 error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
1533 ret=1
1535 done
1537 for i in 'changelog' 'install'; do
1538 local file
1539 while read -r file; do
1540 # evaluate any bash variables used
1541 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1542 if [[ ! -f $file ]]; then
1543 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1544 ret=1
1546 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1547 done
1549 local valid_options=1
1550 local known kopt options_list
1551 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
1552 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
1553 for i in ${options_list[@]}; do
1554 known=0
1555 # check if option matches a known option or its inverse
1556 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1557 if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then
1558 known=1
1560 done
1561 if (( ! known )); then
1562 error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
1563 valid_options=0
1565 done
1566 if (( ! valid_options )); then
1567 ret=1
1570 if (( ${#pkgname[@]} > 1 )); then
1571 for i in ${pkgname[@]}; do
1572 if ! declare -f package_${i} >/dev/null; then
1573 error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
1574 ret=1
1576 done
1579 for i in ${PKGLIST[@]}; do
1580 if ! in_array $i ${pkgname[@]}; then
1581 error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1582 ret=1
1584 done
1586 return $ret
1589 check_software() {
1590 # check for needed software
1591 local ret=0
1593 # check for sudo if we will need it during makepkg execution
1594 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1595 if ! type -p sudo >/dev/null; then
1596 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1600 # fakeroot - building as non-root user
1601 if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1602 if ! type -p fakeroot >/dev/null; then
1603 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
1604 ret=1
1608 # gpg - package signing
1609 if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then
1610 if ! type -p gpg >/dev/null; then
1611 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
1612 ret=1
1616 # gpg - source verification
1617 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
1618 if ! type -p gpg >/dev/null; then
1619 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
1620 ret=1
1624 # openssl - checksum operations
1625 if (( ! SKIPCHECKSUMS )); then
1626 if ! type -p openssl >/dev/null; then
1627 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
1628 ret=1
1632 # upx - binary compression
1633 if [[ $(check_option upx) == 'y' ]]; then
1634 if ! type -p upx >/dev/null; then
1635 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
1636 ret=1
1640 # distcc - compilation with distcc
1641 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
1642 if ! type -p distcc >/dev/null; then
1643 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
1644 ret=1
1648 # ccache - compilation with ccache
1649 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
1650 if ! type -p ccache >/dev/null; then
1651 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
1652 ret=1
1656 # strip - strip symbols from binaries/libraries
1657 if [[ $(check_option strip) = "y" ]]; then
1658 if ! type -p strip >/dev/null; then
1659 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
1660 ret=1
1664 # gzip - compressig man and info pages
1665 if [[ $(check_option zipman) = "y" ]]; then
1666 if ! type -p gzip >/dev/null; then
1667 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
1668 ret=1
1672 return $ret
1675 devel_check() {
1676 newpkgver=""
1678 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1679 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1680 if (( HOLDVER || SOURCEONLY || REPKG )) ||
1681 [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = /dev/stdin ]]; then
1682 return
1685 if [[ -z $FORCE_VER ]]; then
1686 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1687 # This will only be used on the first call to makepkg; subsequent
1688 # calls to makepkg via fakeroot will explicitly pass the version
1689 # number to avoid having to determine the version number twice.
1690 # Also do a check to make sure we have the VCS tool available.
1691 oldpkgver=$pkgver
1692 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1693 if ! type -p darcs >/dev/null; then
1694 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "darcs" "darcs"
1695 return 0
1697 msg "$(gettext "Determining latest %s revision...")" 'darcs'
1698 newpkgver=$(date +%Y%m%d)
1699 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1700 if ! type -p cvs >/dev/null; then
1701 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "cvs" "cvs"
1702 return 0
1704 msg "$(gettext "Determining latest %s revision...")" 'cvs'
1705 newpkgver=$(date +%Y%m%d)
1706 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1707 if ! type -p git >/dev/null; then
1708 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "git" "git"
1709 return 0
1711 msg "$(gettext "Determining latest %s revision...")" 'git'
1712 newpkgver=$(date +%Y%m%d)
1713 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1714 if ! type -p svn >/dev/null; then
1715 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "svn" "svn"
1716 return 0
1718 msg "$(gettext "Determining latest %s revision...")" 'svn'
1719 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1720 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1721 if ! type -p bzr >/dev/null; then
1722 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "bzr" "bzr"
1723 return 0
1725 msg "$(gettext "Determining latest %s revision...")" 'bzr'
1726 newpkgver=$(bzr revno ${_bzrtrunk})
1727 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1728 if ! type -p hg >/dev/null; then
1729 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "hg" "hg"
1730 return 0
1732 msg "$(gettext "Determining latest %s revision...")" 'hg'
1733 if [[ -d ./src/$_hgrepo ]] ; then
1734 cd ./src/$_hgrepo
1735 hg pull
1736 hg update
1737 else
1738 [[ ! -d ./src/ ]] && mkdir ./src/
1739 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1740 cd ./src/$_hgrepo
1742 newpkgver=$(hg tip --template "{rev}")
1743 cd ../../
1746 if [[ -n $newpkgver ]]; then
1747 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1750 else
1751 # Version number retrieved from fakeroot->makepkg argument
1752 newpkgver=$FORCE_VER
1756 devel_update() {
1757 # This is lame, but if we're wanting to use an updated pkgver for
1758 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1759 # the new pkgver and then re-source it. This is the most robust
1760 # method for dealing with PKGBUILDs that use, e.g.:
1762 # pkgver=23
1763 # ...
1764 # _foo=pkgver
1766 if [[ -n $newpkgver ]]; then
1767 if [[ $newpkgver != $pkgver ]]; then
1768 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1769 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1770 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1771 source "$BUILDFILE"
1777 backup_package_variables() {
1778 local var
1779 for var in ${splitpkg_overrides[@]}; do
1780 local indirect="${var}_backup"
1781 eval "${indirect}=(\"\${$var[@]}\")"
1782 done
1785 restore_package_variables() {
1786 local var
1787 for var in ${splitpkg_overrides[@]}; do
1788 local indirect="${var}_backup"
1789 if [[ -n ${!indirect} ]]; then
1790 eval "${var}=(\"\${$indirect[@]}\")"
1791 else
1792 unset ${var}
1794 done
1797 run_split_packaging() {
1798 local pkgname_backup=${pkgname[@]}
1799 for pkgname in ${pkgname_backup[@]}; do
1800 pkgdir="$pkgdir/$pkgname"
1801 mkdir -p "$pkgdir"
1802 chmod a-s "$pkgdir"
1803 backup_package_variables
1804 run_package $pkgname
1805 tidy_install
1806 create_package $pkgname
1807 restore_package_variables
1808 pkgdir="${pkgdir%/*}"
1809 done
1810 pkgname=${pkgname_backup[@]}
1813 # Canonicalize a directory path if it exists
1814 canonicalize_path() {
1815 local path="$1";
1817 if [[ -d $path ]]; then
1819 cd "$path"
1820 pwd -P
1822 else
1823 echo "$path"
1827 m4_include(library/parse_options.sh)
1829 usage() {
1830 printf "makepkg (pacman) %s\n" "$myver"
1831 echo
1832 printf "$(gettext "Usage: %s [options]")\n" "$0"
1833 echo
1834 echo "$(gettext "Options:")"
1835 printf "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
1836 echo "$(gettext " -c, --clean Clean up work files after build")"
1837 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1838 printf "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
1839 echo "$(gettext " -f, --force Overwrite existing package")"
1840 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1841 echo "$(gettext " -h, --help Show this help message and exit")"
1842 echo "$(gettext " -i, --install Install package after successful build")"
1843 echo "$(gettext " -L, --log Log package build process")"
1844 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1845 echo "$(gettext " -o, --nobuild Download and extract files only")"
1846 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1847 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1848 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1849 printf "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
1850 echo "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")"
1851 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1852 printf "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
1853 printf "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1854 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1855 printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1856 printf "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
1857 printf "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1858 echo "$(gettext " --nosign Do not create a signature for the package")"
1859 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1860 printf "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
1861 echo "$(gettext " --skipchecksums Do not verify checksums of the source files")"
1862 echo "$(gettext " --skipinteg Do not perform any verification checks on source files")"
1863 echo "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")"
1864 echo
1865 printf "$(gettext "These options can be passed to %s:")\n" "pacman"
1866 echo
1867 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1868 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1869 echo
1870 printf "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
1871 echo
1874 version() {
1875 printf "makepkg (pacman) %s\n" "$myver"
1876 printf "$(gettext "\
1877 Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1878 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1879 This is free software; see the source for copying conditions.\n\
1880 There is NO WARRANTY, to the extent permitted by law.\n")"
1883 # PROGRAM START
1885 # determine whether we have gettext; make it a no-op if we do not
1886 if ! type -p gettext >/dev/null; then
1887 gettext() {
1888 echo "$@"
1892 ARGLIST=("$@")
1894 # Parse Command Line Options.
1895 OPT_SHORT="AcdefFghiLmop:rRsSV"
1896 OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
1897 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck"
1898 OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
1899 OPT_LONG+=",repackage,skipchecksums,skipinteg,skippgpcheck,sign,source,syncdeps"
1900 OPT_LONG+=",version,config:"
1902 # Pacman Options
1903 OPT_LONG+=",noconfirm,noprogressbar"
1904 if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
1905 echo; usage; exit 1 # E_INVALID_OPTION;
1907 eval set -- "$OPT_TEMP"
1908 unset OPT_SHORT OPT_LONG OPT_TEMP
1910 while true; do
1911 case "$1" in
1912 # Pacman Options
1913 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1914 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1916 # Makepkg Options
1917 --allsource) SOURCEONLY=2 ;;
1918 --asroot) ASROOT=1 ;;
1919 -A|--ignorearch) IGNOREARCH=1 ;;
1920 -c|--clean) CLEANUP=1 ;;
1921 --check) RUN_CHECK='y' ;;
1922 --config) shift; MAKEPKG_CONF=$1 ;;
1923 -d|--nodeps) NODEPS=1 ;;
1924 -e|--noextract) NOEXTRACT=1 ;;
1925 -f|--force) FORCE=1 ;;
1926 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1927 --forcever) shift; FORCE_VER=$1;;
1928 -F) INFAKEROOT=1 ;;
1929 -g|--geninteg) GENINTEG=1 ;;
1930 --holdver) HOLDVER=1 ;;
1931 -i|--install) INSTALL=1 ;;
1932 --key) shift; GPGKEY=$1 ;;
1933 -L|--log) LOGGING=1 ;;
1934 -m|--nocolor) USE_COLOR='n' ;;
1935 --nocheck) RUN_CHECK='n' ;;
1936 --nosign) SIGNPKG='n' ;;
1937 -o|--nobuild) NOBUILD=1 ;;
1938 -p) shift; BUILDFILE=$1 ;;
1939 --pkg) shift; PKGLIST=($1) ;;
1940 -r|--rmdeps) RMDEPS=1 ;;
1941 -R|--repackage) REPKG=1 ;;
1942 --skipchecksums) SKIPCHECKSUMS=1 ;;
1943 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
1944 --skippgpcheck) SKIPPGPCHECK=1;;
1945 --sign) SIGNPKG='y' ;;
1946 -s|--syncdeps) DEP_BIN=1 ;;
1947 -S|--source) SOURCEONLY=1 ;;
1949 -h|--help) usage; exit 0 ;; # E_OK
1950 -V|--version) version; exit 0 ;; # E_OK
1952 --) OPT_IND=0; shift; break;;
1953 *) usage; exit 1 ;; # E_INVALID_OPTION
1954 esac
1955 shift
1956 done
1958 # preserve environment variables and canonicalize path
1959 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
1960 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
1961 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
1962 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
1963 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
1964 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
1965 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
1967 # default config is makepkg.conf
1968 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1970 # Source the config file; fail if it is not found
1971 if [[ -r $MAKEPKG_CONF ]]; then
1972 source "$MAKEPKG_CONF"
1973 else
1974 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1975 plain "$(gettext "Aborting...")"
1976 exit 1 # $E_CONFIG_ERROR
1979 # Source user-specific makepkg.conf overrides, but only if no override config
1980 # file was specified
1981 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
1982 source ~/.makepkg.conf
1985 # set pacman command if not already defined
1986 PACMAN=${PACMAN:-pacman}
1988 # check if messages are to be printed using color
1989 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1990 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1991 # prefer terminal safe colored and bold text when tput is supported
1992 if tput setaf 0 &>/dev/null; then
1993 ALL_OFF="$(tput sgr0)"
1994 BOLD="$(tput bold)"
1995 BLUE="${BOLD}$(tput setaf 4)"
1996 GREEN="${BOLD}$(tput setaf 2)"
1997 RED="${BOLD}$(tput setaf 1)"
1998 YELLOW="${BOLD}$(tput setaf 3)"
1999 else
2000 ALL_OFF="\e[1;0m"
2001 BOLD="\e[1;1m"
2002 BLUE="${BOLD}\e[1;34m"
2003 GREEN="${BOLD}\e[1;32m"
2004 RED="${BOLD}\e[1;31m"
2005 YELLOW="${BOLD}\e[1;33m"
2008 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2010 # override settings with an environment variable for batch processing
2011 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2012 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2013 if [[ ! -d $BUILDDIR ]]; then
2014 mkdir -p "$BUILDDIR" ||
2015 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2016 chmod a-s "$BUILDDIR"
2018 if [[ ! -w $BUILDDIR ]]; then
2019 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2020 plain "$(gettext "Aborting...")"
2021 exit 1
2023 srcdir="$BUILDDIR/src"
2024 pkgdir="$BUILDDIR/pkg"
2026 PKGDEST=${_PKGDEST:-$PKGDEST}
2027 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2028 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2029 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2030 plain "$(gettext "Aborting...")"
2031 exit 1
2034 SRCDEST=${_SRCDEST:-$SRCDEST}
2035 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2036 if [[ ! -w $SRCDEST ]] ; then
2037 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2038 plain "$(gettext "Aborting...")"
2039 exit 1
2042 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2043 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2045 PKGEXT=${_PKGEXT:-$PKGEXT}
2046 SRCEXT=${_SRCEXT:-$SRCEXT}
2047 GPGKEY=${_GPGKEY:-$GPGKEY}
2049 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
2050 # The '\\0' is here to prevent gettext from thinking --holdver is an option
2051 error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
2052 exit 1
2055 if (( ! INFAKEROOT )); then
2056 if (( EUID == 0 && ! ASROOT )); then
2057 # Warn those who like to live dangerously.
2058 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2059 catastrophic damage to your system. If you wish to run as root, please\n\
2060 use the %s option.")" "makepkg" "--asroot"
2061 exit 1 # $E_USER_ABORT
2062 elif (( EUID > 0 && ASROOT )); then
2063 # Warn those who try to use the --asroot option when they are not root
2064 error "$(gettext "The %s option is meant for the root user only. Please\n\
2065 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2066 exit 1 # $E_USER_ABORT
2067 elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
2068 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2069 ownership of the packaged files. Try using the %s environment by\n\
2070 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF"
2071 sleep 1
2073 else
2074 if [[ -z $FAKEROOTKEY ]]; then
2075 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2076 exit 1 # TODO: error code
2080 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2081 unset md5sums replaces depends conflicts backup source install changelog build
2082 unset makedepends optdepends options noextract
2084 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2085 if [[ ! -f $BUILDFILE ]]; then
2086 if [[ -t 0 ]]; then
2087 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2088 exit 1
2089 else
2090 # PKGBUILD passed through a pipe
2091 BUILDFILE=/dev/stdin
2092 source "$BUILDFILE"
2094 else
2095 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2096 if [[ -n $crlftest ]]; then
2097 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2098 exit 1
2101 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2102 BUILDFILE="$startdir/$BUILDFILE"
2104 source "$BUILDFILE"
2107 # set defaults if they weren't specified in buildfile
2108 pkgbase=${pkgbase:-${pkgname[0]}}
2109 epoch=${epoch:-0}
2111 if (( GENINTEG )); then
2112 mkdir -p "$srcdir"
2113 chmod a-s "$srcdir"
2114 cd "$srcdir"
2115 download_sources
2116 generate_checksums
2117 exit 0 # $E_OK
2120 # check the PKGBUILD for some basic requirements
2121 check_sanity || exit 1
2123 # check we have the software required to process the PKGBUILD
2124 check_software || exit 1
2126 # We need to run devel_update regardless of whether we are in the fakeroot
2127 # build process so that if the user runs makepkg --forcever manually, we
2128 # 1) output the correct pkgver, and 2) use the correct filename when
2129 # checking if the package file already exists - fixes FS #9194
2130 devel_check
2131 devel_update
2133 if (( ${#pkgname[@]} > 1 )); then
2134 SPLITPKG=1
2137 # test for available PKGBUILD functions
2138 if declare -f build >/dev/null; then
2139 BUILDFUNC=1
2141 if declare -f check >/dev/null; then
2142 # "Hide" check() function if not going to be run
2143 if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then
2144 CHECKFUNC=1
2147 if declare -f package >/dev/null; then
2148 PKGFUNC=1
2149 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
2150 SPLITPKG=1
2153 if [[ -n "${PKGLIST[@]}" ]]; then
2154 unset pkgname
2155 pkgname=("${PKGLIST[@]}")
2158 # check if gpg signature is to be created and if signing key is valid
2159 [[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign)
2160 if [[ $SIGNPKG == 'y' ]]; then
2161 if ! gpg --list-key ${GPGKEY} &>/dev/null; then
2162 if [[ ! -z $GPGKEY ]]; then
2163 error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2164 else
2165 error "$(gettext "There is no key in your keyring.")"
2167 exit 1
2172 if (( ! SPLITPKG )); then
2173 fullver=$(get_full_version)
2174 if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \
2175 || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \
2176 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2177 if (( INSTALL )); then
2178 warning "$(gettext "A package has already been built, installing existing package...")"
2179 install_package
2180 exit $?
2181 else
2182 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2183 exit 1
2186 else
2187 allpkgbuilt=1
2188 somepkgbuilt=0
2189 for pkg in ${pkgname[@]}; do
2190 fullver=$(get_full_version $pkg)
2191 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \
2192 || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then
2193 somepkgbuilt=1
2194 else
2195 allpkgbuilt=0
2197 done
2198 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2199 if (( allpkgbuilt )); then
2200 if (( INSTALL )); then
2201 warning "$(gettext "The package group has already been built, installing existing packages...")"
2202 install_package
2203 exit $?
2204 else
2205 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2206 exit 1
2209 if (( somepkgbuilt )); then
2210 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2211 exit 1
2214 unset allpkgbuilt somepkgbuilt
2217 # Run the bare minimum in fakeroot
2218 if (( INFAKEROOT )); then
2219 if (( SOURCEONLY )); then
2220 create_srcpackage
2221 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2222 exit 0 # $E_OK
2225 if (( ! SPLITPKG )); then
2226 if (( ! PKGFUNC )); then
2227 if (( ! REPKG )); then
2228 if (( BUILDFUNC )); then
2229 run_build
2230 (( CHECKFUNC )) && run_check
2231 tidy_install
2233 else
2234 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2235 plain "$(gettext "File permissions may not be preserved.")"
2237 else
2238 run_package
2239 tidy_install
2241 create_package
2242 else
2243 run_split_packaging
2246 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2247 exit 0 # $E_OK
2250 fullver=$(get_full_version)
2251 msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2253 # if we are creating a source-only package, go no further
2254 if (( SOURCEONLY )); then
2255 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2256 && (( ! FORCE )); then
2257 error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2258 exit 1
2261 # Get back to our src directory so we can begin with sources.
2262 mkdir -p "$srcdir"
2263 chmod a-s "$srcdir"
2264 cd "$srcdir"
2265 if ( (( ! SKIPCHECKSUMS )) || \
2266 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \
2267 (( SOURCEONLY == 2 )); then
2268 download_sources
2270 check_source_integrity
2271 cd "$startdir"
2273 # if we are root or if fakeroot is not enabled, then we don't use it
2274 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2275 create_srcpackage
2276 else
2277 enter_fakeroot
2280 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2281 exit 0
2284 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
2285 # no warning message needed for nobuild, repkg
2286 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
2287 warning "$(gettext "Skipping dependency checks.")"
2289 elif type -p "${PACMAN%% *}" >/dev/null; then
2290 if (( RMDEPS )); then
2291 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2293 deperr=0
2295 msg "$(gettext "Checking runtime dependencies...")"
2296 resolve_deps ${depends[@]} || deperr=1
2298 msg "$(gettext "Checking buildtime dependencies...")"
2299 resolve_deps ${makedepends[@]} || deperr=1
2301 if (( CHECKFUNC )); then
2302 resolve_deps ${checkdepends[@]} || deperr=1
2305 if (( RMDEPS )); then
2306 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2309 if (( deperr )); then
2310 error "$(gettext "Could not resolve all dependencies.")"
2311 exit 1
2313 else
2314 warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
2317 # ensure we have a sane umask set
2318 umask 0022
2320 # get back to our src directory so we can begin with sources
2321 mkdir -p "$srcdir"
2322 chmod a-s "$srcdir"
2323 cd "$srcdir"
2325 if (( NOEXTRACT )); then
2326 warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
2327 warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
2328 warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
2330 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
2331 error "$(gettext "The source directory is empty, there is nothing to build!")"
2332 plain "$(gettext "Aborting...")"
2333 exit 1
2335 elif (( REPKG )); then
2336 if (( ! PKGFUNC && ! SPLITPKG )) \
2337 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
2338 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2339 plain "$(gettext "Aborting...")"
2340 exit 1
2342 else
2343 download_sources
2344 check_source_integrity
2345 extract_sources
2348 if (( NOBUILD )); then
2349 msg "$(gettext "Sources are ready.")"
2350 exit 0 #E_OK
2351 else
2352 # check for existing pkg directory; don't remove if we are repackaging
2353 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2354 msg "$(gettext "Removing existing %s directory...")" "pkg/"
2355 rm -rf "$pkgdir"
2357 mkdir -p "$pkgdir"
2358 chmod a-s "$pkgdir"
2359 cd "$startdir"
2361 # if we are root or if fakeroot is not enabled, then we don't use it
2362 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2363 if (( ! REPKG )); then
2364 devel_update
2365 (( BUILDFUNC )) && run_build
2366 (( CHECKFUNC )) && run_check
2368 if (( ! SPLITPKG )); then
2369 if (( PKGFUNC )); then
2370 run_package
2371 tidy_install
2372 else
2373 if (( ! REPKG )); then
2374 tidy_install
2375 else
2376 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2377 plain "$(gettext "File permissions may not be preserved.")"
2380 create_package
2381 else
2382 run_split_packaging
2384 else
2385 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2386 devel_update
2387 (( BUILDFUNC )) && run_build
2388 (( CHECKFUNC )) && run_check
2389 cd "$startdir"
2392 enter_fakeroot
2396 fullver=$(get_full_version)
2397 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
2399 install_package
2401 exit 0 #E_OK
2403 # vim: set ts=2 sw=2 noet: