pacman-key: rework importing distro/repo provided keyrings
[pacman-ng.git] / scripts / makepkg.sh.in
blobd0a514a6e03703be843cafc8582fa745a9bf7c2d
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 ### SUBROUTINES ###
86 plain() {
87 local mesg=$1; shift
88 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
91 msg() {
92 local mesg=$1; shift
93 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
96 msg2() {
97 local mesg=$1; shift
98 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
101 warning() {
102 local mesg=$1; shift
103 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
106 error() {
107 local mesg=$1; shift
108 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
113 # Special exit call for traps, Don't print any error messages when inside,
114 # the fakeroot call, the error message will be printed by the main call.
116 trap_exit() {
117 if (( ! INFAKEROOT )); then
118 echo
119 error "$@"
121 [[ -n $srclinks ]] && rm -rf "$srclinks"
122 exit 1
127 # Clean up function. Called automatically when the script exits.
129 clean_up() {
130 local EXIT_CODE=$?
132 if (( INFAKEROOT )); then
133 # Don't clean up when leaving fakeroot, we're not done yet.
134 return
137 if (( ! EXIT_CODE && CLEANUP )); then
138 local pkg file
140 # If it's a clean exit and -c/--clean has been passed...
141 msg "$(gettext "Cleaning up...")"
142 rm -rf "$pkgdir" "$srcdir"
143 if [[ -n $pkgbase ]]; then
144 local fullver=$(get_full_version)
145 # Can't do this unless the BUILDSCRIPT has been sourced.
146 if (( BUILDFUNC )); then
147 rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
149 if (( CHECKFUNC )); then
150 rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
152 if (( PKGFUNC )); then
153 rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
154 elif (( SPLITPKG )); then
155 for pkg in ${pkgname[@]}; do
156 rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
157 done
160 # clean up dangling symlinks to packages
161 for pkg in ${pkgname[@]}; do
162 for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do
163 if [[ -h $file && ! -e $file ]]; then
164 rm -f $file
166 done
167 done
171 remove_deps
176 # Signal Traps
178 set -E
179 trap 'clean_up' 0
180 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
181 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
182 trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
184 enter_fakeroot() {
185 msg "$(gettext "Entering %s environment...")" "fakeroot"
187 if [[ -n $newpkgver ]]; then
188 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
189 else
190 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
195 # a source entry can have two forms :
196 # 1) "filename::http://path/to/file"
197 # 2) "http://path/to/file"
199 # Return the absolute filename of a source entry
201 # This function accepts a source entry or the already extracted filename of a
202 # source entry as input
203 get_filepath() {
204 local file="$(get_filename "$1")"
206 if [[ -f "$startdir/$file" ]]; then
207 file="$startdir/$file"
208 elif [[ -f "$SRCDEST/$file" ]]; then
209 file="$SRCDEST/$file"
210 else
211 return 1
214 echo "$file"
217 # Print 'source not found' error message and exit makepkg
218 missing_source_file() {
219 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
220 plain "$(gettext "Aborting...")"
221 exit 1 # $E_MISSING_FILE
224 # extract the filename from a source entry
225 get_filename() {
226 # if a filename is specified, use it
227 local filename="${1%%::*}"
228 # if it is just an URL, we only keep the last component
229 echo "${filename##*/}"
232 # extract the URL from a source entry
233 get_url() {
234 # strip an eventual filename
235 echo "${1#*::}"
239 # usage : get_full_version( [$pkgname] )
240 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
242 get_full_version() {
243 if [[ -z $1 ]]; then
244 if [[ $epoch ]] && (( ! $epoch )); then
245 echo $pkgver-$pkgrel
246 else
247 echo $epoch:$pkgver-$pkgrel
249 else
250 for i in pkgver pkgrel epoch; do
251 local indirect="${i}_override"
252 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
253 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
254 done
255 if (( ! $epoch_override )); then
256 echo $pkgver_override-$pkgrel_override
257 else
258 echo $epoch_override:$pkgver_override-$pkgrel_override
264 # Checks to see if options are present in makepkg.conf or PKGBUILD;
265 # PKGBUILD options always take precedence.
267 # usage : check_option( $option )
268 # return : y - enabled
269 # n - disabled
270 # ? - not found
272 check_option() {
273 local ret=$(in_opt_array "$1" ${options[@]})
274 if [[ $ret != '?' ]]; then
275 echo $ret
276 return
279 # fall back to makepkg.conf options
280 ret=$(in_opt_array "$1" ${OPTIONS[@]})
281 if [[ $ret != '?' ]]; then
282 echo $ret
283 return
286 echo '?' # Not Found
291 # Check if option is present in BUILDENV
293 # usage : check_buildenv( $option )
294 # return : y - enabled
295 # n - disabled
296 # ? - not found
298 check_buildenv() {
299 in_opt_array "$1" ${BUILDENV[@]}
304 # usage : in_opt_array( $needle, $haystack )
305 # return : y - enabled
306 # n - disabled
307 # ? - not found
309 in_opt_array() {
310 local needle=$1; shift
312 local opt
313 for opt in "$@"; do
314 if [[ $opt = $needle ]]; then
315 echo 'y' # Enabled
316 return
317 elif [[ $opt = "!$needle" ]]; then
318 echo 'n' # Disabled
319 return
321 done
323 echo '?' # Not Found
328 # usage : in_array( $needle, $haystack )
329 # return : 0 - found
330 # 1 - not found
332 in_array() {
333 local needle=$1; shift
334 local item
335 for item in "$@"; do
336 [[ $item = $needle ]] && return 0 # Found
337 done
338 return 1 # Not Found
341 source_has_signatures(){
342 local file
343 for file in "${source[@]}"; do
344 if [[ $file =~ .*(sig|asc) ]]; then
345 return 0
347 done
348 return 1
351 get_downloadclient() {
352 # $1 = URL with valid protocol prefix
353 local url=$1
354 local proto="${url%%://*}"
356 # loop through DOWNLOAD_AGENTS variable looking for protocol
357 local i
358 for i in "${DLAGENTS[@]}"; do
359 local handler="${i%%::*}"
360 if [[ $proto = $handler ]]; then
361 local agent="${i##*::}"
362 break
364 done
366 # if we didn't find an agent, return an error
367 if [[ -z $agent ]]; then
368 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
369 plain "$(gettext "Aborting...")"
370 exit 1 # $E_CONFIG_ERROR
373 # ensure specified program is installed
374 local program="${agent%% *}"
375 if [[ ! -x $program ]]; then
376 local baseprog="${program##*/}"
377 error "$(gettext "The download program %s is not installed.")" "$baseprog"
378 plain "$(gettext "Aborting...")"
379 exit 1 # $E_MISSING_PROGRAM
382 echo "$agent"
385 download_file() {
386 # download command
387 local dlcmd=$1
388 # URL of the file
389 local url=$2
390 # destination file
391 local file=$3
392 # temporary download file, default to last component of the URL
393 local dlfile="${url##*/}"
395 # replace %o by the temporary dlfile if it exists
396 if [[ $dlcmd = *%o* ]]; then
397 dlcmd=${dlcmd//\%o/\"$file.part\"}
398 dlfile="$file.part"
400 # add the URL, either in place of %u or at the end
401 if [[ $dlcmd = *%u* ]]; then
402 dlcmd=${dlcmd//\%u/\"$url\"}
403 else
404 dlcmd="$dlcmd \"$url\""
407 local ret=0
408 eval "$dlcmd || ret=\$?"
409 if (( ret )); then
410 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
411 return $ret
414 # rename the temporary download file to the final destination
415 if [[ $dlfile != $file ]]; then
416 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
420 run_pacman() {
421 local cmd
422 printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
423 if (( ! ASROOT )) && [[ ! $1 =~ ^-(T|Qq)$ ]]; then
424 if type -p sudo >/dev/null; then
425 cmd="sudo $cmd"
426 else
427 cmd="su root -c '$cmd'"
430 eval "$cmd"
433 check_deps() {
434 (( $# > 0 )) || return 0
436 # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility
437 # Also, a non-zero return value is not unexpected and we are manually dealing them
438 set +E
439 local ret=0
440 local pmout
441 pmout=$(run_pacman -T "$@") || ret=$?
442 set -E
444 if (( ret == 127 )); then #unresolved deps
445 echo "$pmout"
446 elif (( ret )); then
447 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
448 return "$ret"
452 handle_deps() {
453 local R_DEPS_SATISFIED=0
454 local R_DEPS_MISSING=1
456 (( $# == 0 )) && return $R_DEPS_SATISFIED
458 local deplist="$*"
460 if (( ! DEP_BIN )); then
461 return $R_DEPS_MISSING
464 if (( DEP_BIN )); then
465 # install missing deps from binary packages (using pacman -S)
466 msg "$(gettext "Installing missing dependencies...")"
468 if ! run_pacman -S --asdeps $deplist; then
469 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
470 exit 1 # TODO: error code
474 # we might need the new system environment
475 # avoid triggering the ERR trap
476 local restoretrap=$(trap -p ERR)
477 trap - ERR
478 source /etc/profile &>/dev/null
479 eval $restoretrap
481 return $R_DEPS_SATISFIED
484 resolve_deps() {
485 local R_DEPS_SATISFIED=0
486 local R_DEPS_MISSING=1
488 # deplist cannot be declared like this: local deplist=$(foo)
489 # Otherwise, the return value will depend on the assignment.
490 local deplist
491 deplist="$(set +E; check_deps $*)" || exit 1
492 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
494 if handle_deps $deplist; then
495 # check deps again to make sure they were resolved
496 deplist="$(set +E; check_deps $*)" || exit 1
497 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
500 msg "$(gettext "Missing Dependencies:")"
501 local dep
502 for dep in $deplist; do
503 msg2 "$dep"
504 done
506 return $R_DEPS_MISSING
509 remove_deps() {
510 (( ! RMDEPS )) && return
512 # check for packages removed during dependency install (e.g. due to conflicts)
513 # removing all installed packages is risky in this case
514 if [[ -n $(comm -23 <(printf "%s\n" "${original_pkglist[@]}") \
515 <(printf "%s\n" "${current_pkglist[@]}")) ]]; then
516 warning "$(gettext "Failed to remove installed dependencies.")"
517 return 0
520 local deplist=($(comm -13 <(printf "%s\n" "${original_pkglist[@]}") \
521 <(printf "%s\n" "${current_pkglist[@]}")))
522 (( ${#deplist[@]} == 0 )) && return
524 msg "Removing installed dependencies..."
525 # exit cleanly on failure to remove deps as package has been built successfully
526 if ! run_pacman -Rn ${deplist[@]}; then
527 warning "$(gettext "Failed to remove installed dependencies.")"
528 return 0
532 download_sources() {
533 msg "$(gettext "Retrieving Sources...")"
535 pushd "$SRCDEST" &>/dev/null
537 local netfile
538 for netfile in "${source[@]}"; do
539 local file=$(get_filepath "$netfile" || true)
540 if [[ -n "$file" ]]; then
541 msg2 "$(gettext "Found %s")" "${file##*/}"
542 rm -f "$srcdir/${file##*/}"
543 ln -s "$file" "$srcdir/"
544 continue
547 file=$(get_filename "$netfile")
548 local url=$(get_url "$netfile")
550 # if we get here, check to make sure it was a URL, else fail
551 if [[ $file = $url ]]; then
552 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
553 exit 1 # $E_MISSING_FILE
556 # find the client we should use for this URL
557 local dlclient=$(get_downloadclient "$url") || exit $?
559 msg2 "$(gettext "Downloading %s...")" "$file"
560 # fix flyspray bug #3289
561 local ret=0
562 download_file "$dlclient" "$url" "$file" || ret=$?
563 if (( ret )); then
564 error "$(gettext "Failure while downloading %s")" "$file"
565 plain "$(gettext "Aborting...")"
566 exit 1
568 rm -f "$srcdir/$file"
569 ln -s "$SRCDEST/$file" "$srcdir/"
570 done
572 popd &>/dev/null
575 get_integlist() {
576 local integ
577 local integlist=()
579 for integ in md5 sha1 sha256 sha384 sha512; do
580 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
581 if [[ -n "$integrity_sums" ]]; then
582 integlist=(${integlist[@]} $integ)
584 done
586 if (( ${#integlist[@]} > 0 )); then
587 echo ${integlist[@]}
588 else
589 echo ${INTEGRITY_CHECK[@]}
593 generate_checksums() {
594 msg "$(gettext "Generating checksums for source files...")"
595 plain ""
597 if ! type -p openssl >/dev/null; then
598 error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
599 exit 1 # $E_MISSING_PROGRAM
602 local integlist
603 if (( $# == 0 )); then
604 integlist=$(get_integlist)
605 else
606 integlist=$@
609 local integ
610 for integ in ${integlist[@]}; do
611 case "$integ" in
612 md5|sha1|sha256|sha384|sha512) : ;;
614 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
615 exit 1;; # $E_CONFIG_ERROR
616 esac
618 local ct=0
619 local numsrc=${#source[@]}
620 echo -n "${integ}sums=("
622 local i
623 local indent=''
624 for (( i = 0; i < ${#integ} + 6; i++ )); do
625 indent="$indent "
626 done
628 local netfile
629 for netfile in "${source[@]}"; do
630 local file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
631 local sum="$(openssl dgst -${integ} "$file")"
632 sum=${sum##* }
633 (( ct )) && echo -n "$indent"
634 echo -n "'$sum'"
635 ct=$(($ct+1))
636 (( $ct < $numsrc )) && echo
637 done
639 echo ")"
640 done
643 check_checksums() {
644 (( SKIPCHECKSUMS )) && return 0
645 (( ! ${#source[@]} )) && return 0
647 local correlation=0
648 local integ required
649 for integ in md5 sha1 sha256 sha384 sha512; do
650 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
651 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
652 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
653 correlation=1
654 local errors=0
655 local idx=0
656 local file
657 for file in "${source[@]}"; do
658 local found=1
659 file="$(get_filename "$file")"
660 echo -n " $file ... " >&2
662 if ! file="$(get_filepath "$file")"; then
663 echo "$(gettext "NOT FOUND")" >&2
664 errors=1
665 found=0
668 if (( $found )) ; then
669 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
670 local realsum="$(openssl dgst -${integ} "$file")"
671 realsum="${realsum##* }"
672 if [[ $expectedsum = $realsum ]]; then
673 echo "$(gettext "Passed")" >&2
674 else
675 echo "$(gettext "FAILED")" >&2
676 errors=1
680 idx=$((idx + 1))
681 done
683 if (( errors )); then
684 error "$(gettext "One or more files did not pass the validity check!")"
685 exit 1 # TODO: error code
687 elif (( ${#integrity_sums[@]} )); then
688 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
689 exit 1 # TODO: error code
691 done
693 if (( ! correlation )); then
694 error "$(gettext "Integrity checks are missing.")"
695 exit 1 # TODO: error code
699 check_pgpsigs() {
700 (( SKIPPGPCHECK )) && return 0
701 ! source_has_signatures && return 0
703 msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
705 local file
706 local warning=0
707 local errors=0
708 local statusfile=$(mktemp)
710 for file in "${source[@]}"; do
711 file="$(get_filename "$file")"
712 if [[ ! $file =~ .*(sig|asc) ]]; then
713 continue
716 echo -n " ${file%.*} ... " >&2
718 if ! file="$(get_filepath "$file")"; then
719 echo "$(gettext "SIGNATURE NOT FOUND")" >&2
720 errors=1
721 continue
724 if ! sourcefile="$(get_filepath "${file%.*}")"; then
725 echo "$(gettext "SOURCE FILE NOT FOUND")" >&2
726 errors=1
727 continue
730 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
731 if grep "NO_PUBKEY" "$statusfile" > /dev/null; then
732 warning "$(gettext "Unknown public key") $(awk '/NO_PUBKEY/ {print $3}' $statusfile)" >&2
733 warnings=1
734 else
735 echo "$(gettext "FAILED")" >&2
736 errors=1
738 else
739 if grep "REVKEYSIG" "$statusfile" > /dev/null; then
740 echo "$(gettext "Passed")" "-" "$(gettext "Warning: the key has been revoked.")" >&2
741 errors=1
742 elif grep "EXPSIG" "$statusfile" > /dev/null; then
743 echo "$(gettext "Passed")" "-" "$(gettext "Warning: the signature has expired.")" >&2
744 warnings=1
745 elif grep "EXPKEYSIG" "$statusfile" > /dev/null; then
746 echo "$(gettext "Passed")" "-" "$(gettext "Warning: the key has expired.")" >&2
747 warnings=1
748 else
749 echo $(gettext "Passed") >&2
752 done
754 rm -f "$statusfile"
756 if (( errors )); then
757 error "$(gettext "One or more PGP signatures could not be verified!")"
758 exit 1
761 if (( warnings )); then
762 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
763 plain "$(gettext "Please make sure you really trust them.")"
767 check_source_integrity() {
768 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
769 warning "$(gettext "Skipping all source file integrity checks.")"
770 elif (( SKIPCHECKSUMS )); then
771 warning "$(gettext "Skipping verification of source file checksums.")"
772 check_pgpsigs
773 elif (( SKIPPGPCHECK )); then
774 warning "$(gettext "Skipping verification of source file PGP signatures.")"
775 check_checksums
776 else
777 check_checksums
778 check_pgpsigs
782 extract_sources() {
783 msg "$(gettext "Extracting Sources...")"
784 local netfile
785 for netfile in "${source[@]}"; do
786 local file=$(get_filename "$netfile")
787 if in_array "$file" "${noextract[@]}"; then
788 #skip source files in the noextract=() array
789 # these are marked explicitly to NOT be extracted
790 continue
794 # fix flyspray #6246
795 local file_type=$(file -bizL "$file")
796 local ext=${file##*.}
797 local cmd=''
798 case "$file_type" in
799 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
800 cmd="bsdtar" ;;
801 *application/x-gzip*)
802 case "$ext" in
803 gz|z|Z) cmd="gzip" ;;
804 *) continue;;
805 esac ;;
806 *application/x-bzip*)
807 case "$ext" in
808 bz2|bz) cmd="bzip2" ;;
809 *) continue;;
810 esac ;;
811 *application/x-xz*)
812 case "$ext" in
813 xz) cmd="xz" ;;
814 *) continue;;
815 esac ;;
817 # See if bsdtar can recognize the file
818 if bsdtar -tf "$file" -q '*' &>/dev/null; then
819 cmd="bsdtar"
820 else
821 continue
822 fi ;;
823 esac
825 local ret=0
826 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
827 if [[ $cmd = bsdtar ]]; then
828 $cmd -xf "$file" || ret=$?
829 else
830 rm -f "${file%.*}"
831 $cmd -dcf "$file" > "${file%.*}" || ret=$?
833 if (( ret )); then
834 error "$(gettext "Failed to extract %s")" "$file"
835 plain "$(gettext "Aborting...")"
836 exit 1
838 done
840 if (( EUID == 0 )); then
841 # change perms of all source files to root user & root group
842 chown -R 0:0 "$srcdir"
846 error_function() {
847 if [[ -p $logpipe ]]; then
848 rm "$logpipe"
850 # first exit all subshells, then print the error
851 if (( ! BASH_SUBSHELL )); then
852 error "$(gettext "A failure occurred in %s().")" "$1"
853 plain "$(gettext "Aborting...")"
854 remove_deps
856 exit 2 # $E_BUILD_FAILED
859 run_function() {
860 if [[ -z $1 ]]; then
861 return 1
863 local pkgfunc="$1"
865 # clear user-specified buildflags if requested
866 if [[ $(check_option buildflags) = "n" ]]; then
867 CFLAGS=""
868 CXXFLAGS=""
869 LDFLAGS=""
872 # clear user-specified makeflags if requested
873 if [[ $(check_option makeflags) = "n" ]]; then
874 MAKEFLAGS=""
877 msg "$(gettext "Starting %s()...")" "$pkgfunc"
878 cd "$srcdir"
880 # ensure all necessary build variables are exported
881 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
882 # save our shell options so pkgfunc() can't override what we need
883 local shellopts=$(shopt -p)
885 local ret=0
886 local restoretrap
887 if (( LOGGING )); then
888 local fullver=$(get_full_version)
889 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
890 if [[ -f $BUILDLOG ]]; then
891 local i=1
892 while true; do
893 if [[ -f $BUILDLOG.$i ]]; then
894 i=$(($i +1))
895 else
896 break
898 done
899 mv "$BUILDLOG" "$BUILDLOG.$i"
902 # ensure overridden package variables survive tee with split packages
903 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
904 mkfifo "$logpipe"
905 tee "$BUILDLOG" < "$logpipe" &
906 local teepid=$!
908 restoretrap=$(trap -p ERR)
909 trap 'error_function $pkgfunc' ERR
910 $pkgfunc &>"$logpipe"
911 eval $restoretrap
913 wait $teepid
914 rm "$logpipe"
915 else
916 restoretrap=$(trap -p ERR)
917 trap 'error_function $pkgfunc' ERR
918 $pkgfunc 2>&1
919 eval $restoretrap
921 # reset our shell options
922 eval "$shellopts"
925 run_build() {
926 # use distcc if it is requested (check buildenv and PKGBUILD opts)
927 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
928 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
929 export DISTCC_HOSTS
932 # use ccache if it is requested (check buildenv and PKGBUILD opts)
933 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
934 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
937 run_function "build"
940 run_check() {
941 run_function "check"
944 run_package() {
945 local pkgfunc
946 if [[ -z $1 ]]; then
947 pkgfunc="package"
948 else
949 pkgfunc="package_$1"
952 run_function "$pkgfunc"
955 tidy_install() {
956 cd "$pkgdir"
957 msg "$(gettext "Tidying install...")"
959 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
960 msg2 "$(gettext "Removing doc files...")"
961 rm -rf ${DOC_DIRS[@]}
964 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
965 msg2 "$(gettext "Purging unwanted files...")"
966 local pt
967 for pt in "${PURGE_TARGETS[@]}"; do
968 if [[ ${pt} = ${pt//\/} ]]; then
969 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
970 else
971 rm -f ${pt}
973 done
976 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
977 msg2 "$(gettext "Compressing man and info pages...")"
978 local manpage ext file link hardlinks hl
979 find ${MAN_DIRS[@]} -type f 2>/dev/null |
980 while read manpage ; do
981 ext="${manpage##*.}"
982 file="${manpage##*/}"
983 if [[ $ext != gz && $ext != bz2 ]]; then
984 # update symlinks to this manpage
985 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
986 while read link ; do
987 rm -f "$link" "${link}.gz"
988 ln -s "${file}.gz" "${link}.gz"
989 done
991 # check file still exists (potentially already compressed due to hardlink)
992 if [[ -f ${manpage} ]]; then
993 # find hard links and remove them
994 # the '|| true' part keeps the script from bailing if find returned an
995 # error, such as when one of the man directories doesn't exist
996 hardlinks="$(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
997 for hl in ${hardlinks}; do
998 rm -f "${hl}";
999 done
1000 # compress the original
1001 gzip -9 "$manpage"
1002 # recreate hard links removed earlier
1003 for hl in ${hardlinks}; do
1004 ln "${manpage}.gz" "${hl}.gz"
1005 chmod 644 ${hl}.gz
1006 done
1009 done
1012 if [[ $(check_option strip) = y ]]; then
1013 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1014 # make sure library stripping variables are defined to prevent excess stripping
1015 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1016 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1017 local binary
1018 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1019 case "$(file -bi "$binary")" in
1020 *application/x-sharedlib*) # Libraries (.so)
1021 strip $STRIP_SHARED "$binary";;
1022 *application/x-archive*) # Libraries (.a)
1023 strip $STRIP_STATIC "$binary";;
1024 *application/x-executable*) # Binaries
1025 strip $STRIP_BINARIES "$binary";;
1026 esac
1027 done
1030 if [[ $(check_option libtool) = "n" ]]; then
1031 msg2 "$(gettext "Removing "%s" files...")" "libtool"
1032 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
1035 if [[ $(check_option emptydirs) = "n" ]]; then
1036 msg2 "$(gettext "Removing empty directories...")"
1037 find . -depth -type d -empty -delete
1040 if [[ $(check_option upx) = "y" ]]; then
1041 msg2 "$(gettext "Compressing binaries with %s...")" "UPX"
1042 local binary
1043 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1044 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1045 upx $UPXFLAGS "$binary" &>/dev/null ||
1046 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1048 done
1052 find_libdepends() {
1053 local libdepends
1054 find "$pkgdir" -type f -perm -u+x | while read filename
1056 # get architecture of the file; if soarch is empty it's not an ELF binary
1057 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1058 [ -n "$soarch" ] || continue
1059 # process all libraries needed by the binary
1060 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1062 # extract the library name: libfoo.so
1063 soname="${sofile%%\.so\.*}.so"
1064 # extract the major version: 1
1065 soversion="${sofile##*\.so\.}"
1066 if in_array "${soname}" ${depends[@]}; then
1067 if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then
1068 # libfoo.so=1-64
1069 echo "${soname}=${soversion}-${soarch}"
1070 libdepends=(${libdepends[@]} "${soname}=${soversion}-${soarch}")
1073 done
1074 done
1077 find_libprovides() {
1078 local libprovides
1079 find "$pkgdir" -type f -name \*.so\* | while read filename
1081 # check if we really have a shared object
1082 if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1083 # 64
1084 soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1085 # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1
1086 sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1087 [ -z "$sofile" ] && sofile="${filename##*/}"
1089 # extract the library name: libfoo.so
1090 soname="${sofile%%\.so\.*}.so"
1091 # extract the major version: 1
1092 soversion="${sofile##*\.so\.}"
1093 if in_array "${soname}" ${provides[@]}; then
1094 if ! in_array "${soname}=${soversion}-${soarch}" ${libprovides[@]}; then
1095 # libfoo.so=1-64
1096 echo "${soname}=${soversion}-${soarch}"
1097 libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
1101 done
1104 write_pkginfo() {
1105 local builddate=$(date -u "+%s")
1106 if [[ -n $PACKAGER ]]; then
1107 local packager="$PACKAGER"
1108 else
1109 local packager="Unknown Packager"
1111 local size="$(@DUPATH@ -sk)"
1112 size="$(( ${size%%[^0-9]*} * 1024 ))"
1114 msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
1115 echo "# Generated by makepkg $myver"
1116 if (( INFAKEROOT )); then
1117 echo "# using $(fakeroot -v)"
1119 echo "# $(LC_ALL=C date -u)"
1120 echo "pkgname = $1"
1121 (( SPLITPKG )) && echo pkgbase = $pkgbase
1122 echo "pkgver = $(get_full_version)"
1123 echo "pkgdesc = $pkgdesc"
1124 echo "url = $url"
1125 echo "builddate = $builddate"
1126 echo "packager = $packager"
1127 echo "size = $size"
1128 echo "arch = $PKGARCH"
1130 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1131 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1132 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1133 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}"
1134 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1135 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1137 local it
1139 libprovides=$(find_libprovides)
1140 libdepends=$(find_libdepends)
1141 provides=("${provides[@]}" ${libprovides})
1142 depends=("${depends[@]}" ${libdepends})
1144 for it in "${depends[@]}"; do
1145 if [[ $it = *.so ]]; then
1146 # check if the entry has been found by find_libdepends
1147 # if not, it's unneeded; tell the user so he can remove it
1148 if [[ ! $libdepends =~ (^|\s)${it}=.* ]]; then
1149 error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it"
1150 return 1
1152 else
1153 echo "depend = $it"
1155 done
1157 for it in "${provides[@]}"; do
1158 # ignore versionless entires (those come from the PKGBUILD)
1159 if [[ $it = *.so ]]; then
1160 # check if the entry has been found by find_libprovides
1161 # if not, it's unneeded; tell the user so he can remove it
1162 if [[ ! $libprovides =~ (^|\s)${it}=.* ]]; then
1163 error "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$it"
1164 return 1
1166 else
1167 echo "provides = $it"
1169 done
1171 for it in "${packaging_options[@]}"; do
1172 local ret="$(check_option $it)"
1173 if [[ $ret != "?" ]]; then
1174 if [[ $ret = y ]]; then
1175 echo "makepkgopt = $it"
1176 else
1177 echo "makepkgopt = !$it"
1180 done
1182 # TODO maybe remove this at some point
1183 # warn if license array is not present or empty
1184 if [[ -z $license ]]; then
1185 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1186 plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
1190 check_package() {
1191 cd "$pkgdir"
1193 # check existence of backup files
1194 local file
1195 for file in "${backup[@]}"; do
1196 if [[ ! -f $file ]]; then
1197 warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
1199 done
1201 # check for references to the build and package directory
1202 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1203 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
1205 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
1206 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
1211 create_package() {
1212 if [[ ! -d $pkgdir ]]; then
1213 error "$(gettext "Missing %s directory.")" "pkg/"
1214 plain "$(gettext "Aborting...")"
1215 exit 1 # $E_MISSING_PKGDIR
1218 check_package
1220 cd "$pkgdir"
1221 msg "$(gettext "Creating package...")"
1223 local nameofpkg
1224 if [[ -z $1 ]]; then
1225 nameofpkg="$pkgname"
1226 else
1227 nameofpkg="$1"
1230 if [[ $arch = "any" ]]; then
1231 PKGARCH="any"
1232 else
1233 PKGARCH=$CARCH
1236 write_pkginfo $nameofpkg > .PKGINFO
1238 local comp_files=".PKGINFO"
1240 # check for changelog/install files
1241 for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1242 IFS='/' read -r orig dest < <(printf '%s\n' "$i")
1244 if [[ -n ${!orig} ]]; then
1245 msg2 "$(gettext "Adding %s file...")" "$orig"
1246 cp "$startdir/${!orig}" "$dest"
1247 chmod 644 "$dest"
1248 comp_files+=" $dest"
1250 done
1252 # tar it up
1253 msg2 "$(gettext "Compressing package...")"
1255 local EXT
1256 case "$PKGEXT" in
1257 *tar.gz) EXT=${PKGEXT%.gz} ;;
1258 *tar.bz2) EXT=${PKGEXT%.bz2} ;;
1259 *tar.xz) EXT=${PKGEXT%.xz} ;;
1260 *tar.Z) EXT=${PKGEXT%.Z} ;;
1261 *tar) EXT=${PKGEXT} ;;
1262 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1263 "$PKGEXT" ; EXT=$PKGEXT ;;
1264 esac
1266 local fullver=$(get_full_version)
1267 local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}"
1268 local ret=0
1270 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1271 [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
1273 # when fileglobbing, we want * in an empty directory to expand to
1274 # the null string rather than itself
1275 shopt -s nullglob
1276 # TODO: Maybe this can be set globally for robustness
1277 shopt -s -o pipefail
1278 bsdtar -cf - $comp_files * |
1279 case "$PKGEXT" in
1280 *tar.gz) gzip -c -f -n ;;
1281 *tar.bz2) bzip2 -c -f ;;
1282 *tar.xz) xz -c -z - ;;
1283 *tar.Z) compress -c -f ;;
1284 *tar) cat ;;
1285 esac > "${pkg_file}" || ret=$?
1287 shopt -u nullglob
1288 shopt -u -o pipefail
1290 if (( ret )); then
1291 error "$(gettext "Failed to create package file.")"
1292 exit 1 # TODO: error code
1295 create_signature "$pkg_file"
1297 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1298 rm -f "${pkg_file/$PKGDEST/$startdir}"
1299 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1300 ret=$?
1301 if [[ -f $pkg_file.sig ]]; then
1302 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1303 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1307 if (( ret )); then
1308 warning "$(gettext "Failed to create symlink to package file.")"
1312 create_signature() {
1313 if [[ $SIGNPKG != 'y' ]]; then
1314 return
1316 local ret=0
1317 local filename="$1"
1318 msg "$(gettext "Signing package...")"
1320 local SIGNWITHKEY=""
1321 if [[ -n $GPGKEY ]]; then
1322 SIGNWITHKEY="-u ${GPGKEY}"
1324 # The signature will be generated directly in ascii-friendly format
1325 gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
1328 if (( ! ret )); then
1329 msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
1330 else
1331 warning "$(gettext "Failed to sign package file.")"
1335 create_srcpackage() {
1336 msg "$(gettext "Creating source package...")"
1337 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1338 mkdir "${srclinks}"/${pkgbase}
1340 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1341 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1343 local file
1344 for file in "${source[@]}"; do
1345 if [[ -f $file ]]; then
1346 msg2 "$(gettext "Adding %s...")" "$file"
1347 ln -s "${startdir}/$file" "$srclinks/$pkgbase"
1348 elif (( SOURCEONLY == 2 )); then
1349 local absfile=$(get_filepath "$file") || missing_source_file "$file"
1350 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1351 ln -s "$absfile" "$srclinks/$pkgbase"
1353 done
1355 local i
1356 for i in 'changelog' 'install'; do
1357 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1358 local file
1359 for file in $filelist; do
1360 # evaluate any bash variables used
1361 eval file=\"${file}\"
1362 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1363 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1364 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1366 done
1367 done
1369 local TAR_OPT
1370 case "$SRCEXT" in
1371 *tar.gz) TAR_OPT="z" ;;
1372 *tar.bz2) TAR_OPT="j" ;;
1373 *tar.xz) TAR_OPT="J" ;;
1374 *tar) TAR_OPT="" ;;
1375 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1376 "$SRCEXT" ;;
1377 esac
1379 local fullver=$(get_full_version)
1380 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1382 # tar it up
1383 msg2 "$(gettext "Compressing source package...")"
1384 cd "${srclinks}"
1385 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1386 error "$(gettext "Failed to create source package file.")"
1387 exit 1 # TODO: error code
1390 if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1391 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1392 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1393 ret=$?
1396 if (( ret )); then
1397 warning "$(gettext "Failed to create symlink to source package file.")"
1400 cd "${startdir}"
1401 rm -rf "${srclinks}"
1404 install_package() {
1405 (( ! INSTALL )) && return
1407 if (( ! SPLITPKG )); then
1408 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1409 else
1410 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1413 local fullver pkg pkglist
1414 for pkg in ${pkgname[@]}; do
1415 fullver=$(get_full_version $pkg)
1416 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then
1417 pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}"
1418 else
1419 pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}"
1421 done
1423 if ! run_pacman -U $pkglist; then
1424 warning "$(gettext "Failed to install built package(s).")"
1425 return 0
1429 check_sanity() {
1430 # check for no-no's in the build script
1431 local i
1432 local ret=0
1433 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1434 if [[ -z ${!i} ]]; then
1435 error "$(gettext "%s is not allowed to be empty.")" "$i"
1436 ret=1
1438 done
1440 for i in "${pkgname[@]}"; do
1441 if [[ ${i:0:1} = "-" ]]; then
1442 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1443 ret=1
1445 done
1447 if [[ ${pkgbase:0:1} = "-" ]]; then
1448 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1449 ret=1
1452 awk -F'=' '/^[[:space:]]*pkgver=/ { $1=""; print $0 }' "$BUILDFILE" |
1453 while read i _; do
1454 eval i=\"$i\"
1455 if [[ $i =~ [[:space:]:-] ]]; then
1456 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1457 return 1
1459 done || ret=1
1461 awk -F'=' '/^[[:space:]]*pkgrel=/ { $1=""; print $0 }' "$BUILDFILE" |
1462 while read i _; do
1463 eval i=\"$i\"
1464 if [[ $i =~ [[:space:]-] ]]; then
1465 error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel"
1466 return 1
1468 done || ret=1
1470 awk -F'=' '/^[[:space:]]*epoch=/ { $1=""; print $0 }' "$BUILDFILE" |
1471 while read i _; do
1472 eval i=\"$i\"
1473 if [[ ! $i =~ ^[0-9]*$ ]]; then
1474 error "$(gettext "%s must be an integer.")" "epoch"
1475 return 1
1477 done || ret=1
1479 if [[ $arch != 'any' ]]; then
1480 if ! in_array $CARCH ${arch[@]}; then
1481 if (( ! IGNOREARCH )); then
1482 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1483 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1484 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1485 ret=1
1490 if (( ${#pkgname[@]} > 1 )); then
1491 for i in ${pkgname[@]}; do
1492 local arch_list=""
1493 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1494 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1495 if ! in_array $CARCH ${arch_list[@]}; then
1496 if (( ! IGNOREARCH )); then
1497 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1498 ret=1
1502 done
1505 local provides_list=()
1506 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1507 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1508 for i in ${provides_list[@]}; do
1509 if [[ $i != ${i//</} || $i != ${i//>/} ]]; then
1510 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1511 ret=1
1513 done
1515 local backup_list=()
1516 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1517 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1518 for i in "${backup_list[@]}"; do
1519 if [[ ${i:0:1} = "/" ]]; then
1520 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1521 ret=1
1523 done
1525 local optdepends_list=()
1526 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1527 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1528 for i in "${optdepends_list[@]}"; do
1529 local pkg=${i%%:*}
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 filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1538 local file
1539 for file in $filelist; do
1540 # evaluate any bash variables used
1541 eval file=\"${file}\"
1542 if [[ ! -f $file ]]; then
1543 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1544 ret=1
1546 done
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: