Add a new configure option for excessive compiler warning flags
[pacman-ng.git] / scripts / makepkg.sh.in
blob1fa4819afa70b6aa3f994f5ad41cae4b3bae2ba2
1 #!/bin/bash -e
3 # makepkg - make packages compatible for use with pacman
4 # @configure_input@
6 # Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
7 # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
8 # Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
9 # Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
10 # Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
11 # Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
12 # Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
28 # makepkg uses quite a few external programs during its execution. You
29 # need to have at least the following installed for makepkg to function:
30 # awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
31 # gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
33 # gettext initialization
34 export TEXTDOMAIN='pacman-scripts'
35 export TEXTDOMAINDIR='@localedir@'
37 # file -i does not work on Mac OSX unless legacy mode is set
38 export COMMAND_MODE='legacy'
39 # Ensure CDPATH doesn't screw with our cd calls
40 unset CDPATH
42 declare -r myver='@PACKAGE_VERSION@'
43 declare -r confdir='@sysconfdir@'
44 declare -r BUILDSCRIPT='@BUILDSCRIPT@'
45 declare -r startdir="$PWD"
47 packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx')
48 other_options=('ccache' 'distcc' 'buildflags' 'makeflags')
49 splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'license' \
50 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \
51 'replaces' 'backup' 'options' 'install' 'changelog')
52 readonly -a packaging_options other_options splitpkg_overrides
54 # Options
55 ASROOT=0
56 CLEANUP=0
57 DEP_BIN=0
58 FORCE=0
59 INFAKEROOT=0
60 GENINTEG=0
61 SKIPCHECKSUMS=0
62 SKIPPGPCHECK=0
63 INSTALL=0
64 NOBUILD=0
65 NODEPS=0
66 NOEXTRACT=0
67 RMDEPS=0
68 REPKG=0
69 LOGGING=0
70 SOURCEONLY=0
71 IGNOREARCH=0
72 HOLDVER=0
73 BUILDFUNC=0
74 CHECKFUNC=0
75 PKGFUNC=0
76 SPLITPKG=0
77 PKGLIST=()
78 SIGNPKG=''
80 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
81 # when dealing with svn/cvs/etc PKGBUILDs.
82 FORCE_VER=""
84 PACMAN_OPTS=
86 shopt -s extglob
88 ### SUBROUTINES ###
90 plain() {
91 local mesg=$1; shift
92 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
95 msg() {
96 local mesg=$1; shift
97 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
100 msg2() {
101 local mesg=$1; shift
102 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
105 warning() {
106 local mesg=$1; shift
107 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
110 error() {
111 local mesg=$1; shift
112 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
117 # Special exit call for traps, Don't print any error messages when inside,
118 # the fakeroot call, the error message will be printed by the main call.
120 trap_exit() {
121 local signal=$1; shift
123 if (( ! INFAKEROOT )); then
124 echo
125 error "$@"
127 [[ -n $srclinks ]] && rm -rf "$srclinks"
129 # unset the trap for this signal, and then call the default handler
130 trap -- "$signal"
131 kill "-$signal" "$$"
136 # Clean up function. Called automatically when the script exits.
138 clean_up() {
139 local EXIT_CODE=$?
141 if (( INFAKEROOT )); then
142 # Don't clean up when leaving fakeroot, we're not done yet.
143 return
146 if (( ! EXIT_CODE && CLEANUP )); then
147 local pkg file
149 # If it's a clean exit and -c/--clean has been passed...
150 msg "$(gettext "Cleaning up...")"
151 rm -rf "$pkgdir" "$srcdir"
152 if [[ -n $pkgbase ]]; then
153 local fullver=$(get_full_version)
154 # Can't do this unless the BUILDSCRIPT has been sourced.
155 if (( BUILDFUNC )); then
156 rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
158 if (( CHECKFUNC )); then
159 rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
161 if (( PKGFUNC )); then
162 rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
163 elif (( SPLITPKG )); then
164 for pkg in ${pkgname[@]}; do
165 rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
166 done
169 # clean up dangling symlinks to packages
170 for pkg in ${pkgname[@]}; do
171 for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do
172 if [[ -h $file && ! -e $file ]]; then
173 rm -f "$file"
175 done
176 done
180 remove_deps
184 enter_fakeroot() {
185 msg "$(gettext "Entering %s environment...")" "fakeroot"
187 if [[ -n $newpkgver ]]; then
188 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
189 else
190 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
195 # a source entry can have two forms :
196 # 1) "filename::http://path/to/file"
197 # 2) "http://path/to/file"
199 # Return the absolute filename of a source entry
201 # This function accepts a source entry or the already extracted filename of a
202 # source entry as input
203 get_filepath() {
204 local file="$(get_filename "$1")"
206 if [[ -f "$startdir/$file" ]]; then
207 file="$startdir/$file"
208 elif [[ -f "$SRCDEST/$file" ]]; then
209 file="$SRCDEST/$file"
210 else
211 return 1
214 printf "%s\n" "$file"
217 # Print 'source not found' error message and exit makepkg
218 missing_source_file() {
219 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
220 plain "$(gettext "Aborting...")"
221 exit 1 # $E_MISSING_FILE
224 # extract the filename from a source entry
225 get_filename() {
226 # if a filename is specified, use it
227 local filename="${1%%::*}"
228 # if it is just an URL, we only keep the last component
229 printf "%s\n" "${filename##*/}"
232 # extract the URL from a source entry
233 get_url() {
234 # strip an eventual filename
235 printf "%s\n" "${1#*::}"
239 # usage : get_full_version( [$pkgname] )
240 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
242 get_full_version() {
243 if [[ -z $1 ]]; then
244 if [[ $epoch ]] && (( ! $epoch )); then
245 printf "%s\n" "$pkgver-$pkgrel"
246 else
247 printf "%s\n" "$epoch:$pkgver-$pkgrel"
249 else
250 for i in pkgver pkgrel epoch; do
251 local indirect="${i}_override"
252 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
253 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
254 done
255 if (( ! $epoch_override )); then
256 printf "%s\n" "$pkgver_override-$pkgrel_override"
257 else
258 printf "%s\n" "$epoch_override:$pkgver_override-$pkgrel_override"
264 # 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 printf "%s\n" "$ret"
276 return
279 # fall back to makepkg.conf options
280 ret=$(in_opt_array "$1" ${OPTIONS[@]})
281 if [[ $ret != '?' ]]; then
282 printf "%s\n" "$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?(n)|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 printf "%s\n" "$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 if [[ ! $1 = -@(T|Qq) ]]; then
423 cmd=("$PACMAN" $PACMAN_OPTS "$@")
424 else
425 cmd=("$PACMAN" "$@")
427 if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
428 if type -p sudo >/dev/null; then
429 cmd=(sudo "${cmd[@]}")
430 else
431 cmd=(su root -c "$(printf '%q ' "${cmd[@]}")")
434 "${cmd[@]}"
437 check_deps() {
438 (( $# > 0 )) || return 0
440 # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility
441 # Also, a non-zero return value is not unexpected and we are manually dealing them
442 set +E
443 local ret=0
444 local pmout
445 pmout=$(run_pacman -T "$@") || ret=$?
446 set -E
448 if (( ret == 127 )); then #unresolved deps
449 printf "%s\n" "$pmout"
450 elif (( ret )); then
451 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
452 return "$ret"
456 handle_deps() {
457 local R_DEPS_SATISFIED=0
458 local R_DEPS_MISSING=1
460 (( $# == 0 )) && return $R_DEPS_SATISFIED
462 local deplist="$*"
464 if (( ! DEP_BIN )); then
465 return $R_DEPS_MISSING
468 if (( DEP_BIN )); then
469 # install missing deps from binary packages (using pacman -S)
470 msg "$(gettext "Installing missing dependencies...")"
472 if ! run_pacman -S --asdeps $deplist; then
473 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
474 exit 1 # TODO: error code
478 # we might need the new system environment
479 # avoid triggering the ERR trap and exiting
480 set +e
481 local restoretrap=$(trap -p ERR)
482 trap - ERR
483 source /etc/profile &>/dev/null
484 eval $restoretrap
485 set -e
487 return $R_DEPS_SATISFIED
490 resolve_deps() {
491 local R_DEPS_SATISFIED=0
492 local R_DEPS_MISSING=1
494 # deplist cannot be declared like this: local deplist=$(foo)
495 # Otherwise, the return value will depend on the assignment.
496 local deplist
497 deplist="$(set +E; check_deps $*)" || exit 1
498 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
500 if handle_deps $deplist; then
501 # check deps again to make sure they were resolved
502 deplist="$(set +E; check_deps $*)" || exit 1
503 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
506 msg "$(gettext "Missing Dependencies:")"
507 local dep
508 for dep in $deplist; do
509 msg2 "$dep"
510 done
512 return $R_DEPS_MISSING
515 remove_deps() {
516 (( ! RMDEPS )) && return
518 # check for packages removed during dependency install (e.g. due to conflicts)
519 # removing all installed packages is risky in this case
520 if [[ -n $(grep -xvFf <(printf '%s\n' "${current_packagelist[@]}") \
521 <(printf '%s\n' "${original_packagelist[@]}") || true) ]]; then
522 warning "$(gettext "Failed to remove installed dependencies.")"
523 return 0
526 local deplist
527 deplist=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
528 <(printf "%s\n" "${current_pkglist[@]}") || true))
529 if [[ -z $deplist ]]; then
530 return
533 msg "Removing installed dependencies..."
534 # exit cleanly on failure to remove deps as package has been built successfully
535 if ! run_pacman -Rn ${deplist[@]}; then
536 warning "$(gettext "Failed to remove installed dependencies.")"
537 return 0
541 download_sources() {
542 msg "$(gettext "Retrieving Sources...")"
544 pushd "$SRCDEST" &>/dev/null
546 local netfile
547 for netfile in "${source[@]}"; do
548 local file=$(get_filepath "$netfile" || true)
549 if [[ -n "$file" ]]; then
550 msg2 "$(gettext "Found %s")" "${file##*/}"
551 rm -f "$srcdir/${file##*/}"
552 ln -s "$file" "$srcdir/"
553 continue
556 file=$(get_filename "$netfile")
557 local url=$(get_url "$netfile")
559 # if we get here, check to make sure it was a URL, else fail
560 if [[ $file = "$url" ]]; then
561 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
562 exit 1 # $E_MISSING_FILE
565 # find the client we should use for this URL
566 local dlclient
567 dlclient=$(get_downloadclient "$url") || exit $?
569 msg2 "$(gettext "Downloading %s...")" "$file"
570 # fix flyspray bug #3289
571 local ret=0
572 download_file "$dlclient" "$url" "$file" || ret=$?
573 if (( ret )); then
574 error "$(gettext "Failure while downloading %s")" "$file"
575 plain "$(gettext "Aborting...")"
576 exit 1
578 rm -f "$srcdir/$file"
579 ln -s "$SRCDEST/$file" "$srcdir/"
580 done
582 popd &>/dev/null
585 get_integlist() {
586 local integ
587 local integlist=()
589 for integ in md5 sha1 sha256 sha384 sha512; do
590 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
591 if [[ -n "$integrity_sums" ]]; then
592 integlist=(${integlist[@]} $integ)
594 done
596 if (( ${#integlist[@]} > 0 )); then
597 printf "%s\n" "${integlist[@]}"
598 else
599 printf "%s\n" "${INTEGRITY_CHECK[@]}"
603 generate_checksums() {
604 msg "$(gettext "Generating checksums for source files...")"
605 plain ""
607 if ! type -p openssl >/dev/null; then
608 error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
609 exit 1 # $E_MISSING_PROGRAM
612 local integlist
613 if (( $# == 0 )); then
614 integlist=$(get_integlist)
615 else
616 integlist=$@
619 local integ
620 for integ in ${integlist[@]}; do
621 case "$integ" in
622 md5|sha1|sha256|sha384|sha512) : ;;
624 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
625 exit 1;; # $E_CONFIG_ERROR
626 esac
628 local ct=0
629 local numsrc=${#source[@]}
630 printf "%s" "${integ}sums=("
632 local i
633 local indent=''
634 for (( i = 0; i < ${#integ} + 6; i++ )); do
635 indent="$indent "
636 done
638 local netfile
639 for netfile in "${source[@]}"; do
640 local file
641 file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
642 local sum="$(openssl dgst -${integ} "$file")"
643 sum=${sum##* }
644 (( ct )) && printf "%s" "$indent"
645 printf "%s" "'$sum'"
646 ct=$(($ct+1))
647 (( $ct < $numsrc )) && echo
648 done
650 echo ")"
651 done
654 check_checksums() {
655 (( SKIPCHECKSUMS )) && return 0
656 (( ! ${#source[@]} )) && return 0
658 local correlation=0
659 local integ required
660 for integ in md5 sha1 sha256 sha384 sha512; do
661 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
662 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
663 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
664 correlation=1
665 local errors=0
666 local idx=0
667 local file
668 for file in "${source[@]}"; do
669 local found=1
670 file="$(get_filename "$file")"
671 printf "%s" " $file ... " >&2
673 if ! file="$(get_filepath "$file")"; then
674 printf -- "$(gettext "NOT FOUND")\n" >&2
675 errors=1
676 found=0
679 if (( $found )) ; then
680 if [[ ${integrity_sums[$idx]} = 'SKIP' ]]; then
681 echo "$(gettext "Skipped")" >&2
682 else
683 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
684 local realsum="$(openssl dgst -${integ} "$file")"
685 realsum="${realsum##* }"
686 if [[ $expectedsum = "$realsum" ]]; then
687 printf -- "$(gettext "Passed")\n" >&2
688 else
689 printf -- "$(gettext "FAILED")\n" >&2
690 errors=1
695 idx=$((idx + 1))
696 done
698 if (( errors )); then
699 error "$(gettext "One or more files did not pass the validity check!")"
700 exit 1 # TODO: error code
702 elif (( ${#integrity_sums[@]} )); then
703 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
704 exit 1 # TODO: error code
706 done
708 if (( ! correlation )); then
709 error "$(gettext "Integrity checks are missing.")"
710 exit 1 # TODO: error code
714 check_pgpsigs() {
715 (( SKIPPGPCHECK )) && return 0
716 ! source_has_signatures && return 0
718 msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
720 local file pubkey
721 local warning=0
722 local errors=0
723 local statusfile=$(mktemp)
725 for file in "${source[@]}"; do
726 file="$(get_filename "$file")"
727 if [[ ! $file = *.@(sig?(n)|asc) ]]; then
728 continue
731 printf " %s ... " "${file%.*}" >&2
733 if ! file="$(get_filepath "$file")"; then
734 printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
735 errors=1
736 continue
739 if ! sourcefile="$(get_filepath "${file%.*}")"; then
740 printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
741 errors=1
742 continue
745 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
746 printf '%s' "$(gettext "FAILED")" >&2
747 if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
748 printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
749 warnings=1
750 else
751 errors=1
753 printf '\n' >&2
754 else
755 if grep -q "REVKEYSIG" "$statusfile"; then
756 printf '%s (%s)' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
757 errors=1
758 else
759 printf '%s' "$(gettext "Passed")" >&2
760 if grep -q "EXPSIG" "$statusfile"; then
761 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
762 warnings=1
763 elif grep -q "EXPKEYSIG" "$statusfile"; then
764 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
765 warnings=1
768 printf '\n' >&2
770 done
772 rm -f "$statusfile"
774 if (( errors )); then
775 error "$(gettext "One or more PGP signatures could not be verified!")"
776 exit 1
779 if (( warnings )); then
780 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
781 plain "$(gettext "Please make sure you really trust them.")"
785 check_source_integrity() {
786 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
787 warning "$(gettext "Skipping all source file integrity checks.")"
788 elif (( SKIPCHECKSUMS )); then
789 warning "$(gettext "Skipping verification of source file checksums.")"
790 check_pgpsigs
791 elif (( SKIPPGPCHECK )); then
792 warning "$(gettext "Skipping verification of source file PGP signatures.")"
793 check_checksums
794 else
795 check_checksums
796 check_pgpsigs
800 extract_sources() {
801 msg "$(gettext "Extracting Sources...")"
802 local netfile
803 for netfile in "${source[@]}"; do
804 local file=$(get_filename "$netfile")
805 if in_array "$file" "${noextract[@]}"; then
806 #skip source files in the noextract=() array
807 # these are marked explicitly to NOT be extracted
808 continue
812 # fix flyspray #6246
813 local file_type=$(file -bizL "$file")
814 local ext=${file##*.}
815 local cmd=''
816 case "$file_type" in
817 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
818 cmd="bsdtar" ;;
819 *application/x-gzip*)
820 case "$ext" in
821 gz|z|Z) cmd="gzip" ;;
822 *) continue;;
823 esac ;;
824 *application/x-bzip*)
825 case "$ext" in
826 bz2|bz) cmd="bzip2" ;;
827 *) continue;;
828 esac ;;
829 *application/x-xz*)
830 case "$ext" in
831 xz) cmd="xz" ;;
832 *) continue;;
833 esac ;;
835 # See if bsdtar can recognize the file
836 if bsdtar -tf "$file" -q '*' &>/dev/null; then
837 cmd="bsdtar"
838 else
839 continue
840 fi ;;
841 esac
843 local ret=0
844 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
845 if [[ $cmd = "bsdtar" ]]; then
846 $cmd -xf "$file" || ret=$?
847 else
848 rm -f -- "${file%.*}"
849 $cmd -dcf "$file" > "${file%.*}" || ret=$?
851 if (( ret )); then
852 error "$(gettext "Failed to extract %s")" "$file"
853 plain "$(gettext "Aborting...")"
854 exit 1
856 done
858 if (( EUID == 0 )); then
859 # change perms of all source files to root user & root group
860 chown -R 0:0 "$srcdir"
864 error_function() {
865 if [[ -p $logpipe ]]; then
866 rm "$logpipe"
868 # first exit all subshells, then print the error
869 if (( ! BASH_SUBSHELL )); then
870 error "$(gettext "A failure occurred in %s().")" "$1"
871 plain "$(gettext "Aborting...")"
872 remove_deps
874 exit 2 # $E_BUILD_FAILED
877 cd_safe() {
878 if ! cd "$1"; then
879 error "$(gettext "Failed to change to directory %s")" "$1"
880 plain "$(gettext "Aborting...")"
881 exit 1
885 run_function() {
886 if [[ -z $1 ]]; then
887 return 1
889 local pkgfunc="$1"
891 # clear user-specified buildflags if requested
892 if [[ $(check_option buildflags) = "n" ]]; then
893 unset CFLAGS CXXFLAGS LDFLAGS
896 # clear user-specified makeflags if requested
897 if [[ $(check_option makeflags) = "n" ]]; then
898 unset MAKEFLAGS
901 msg "$(gettext "Starting %s()...")" "$pkgfunc"
902 cd_safe "$srcdir"
904 # ensure all necessary build variables are exported
905 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
906 # save our shell options so pkgfunc() can't override what we need
907 local shellopts=$(shopt -p)
909 local ret=0
910 local restoretrap
911 if (( LOGGING )); then
912 local fullver=$(get_full_version)
913 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
914 if [[ -f $BUILDLOG ]]; then
915 local i=1
916 while true; do
917 if [[ -f $BUILDLOG.$i ]]; then
918 i=$(($i +1))
919 else
920 break
922 done
923 mv "$BUILDLOG" "$BUILDLOG.$i"
926 # ensure overridden package variables survive tee with split packages
927 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
928 mkfifo "$logpipe"
929 tee "$BUILDLOG" < "$logpipe" &
930 local teepid=$!
932 restoretrap=$(trap -p ERR)
933 trap 'error_function $pkgfunc' ERR
934 $pkgfunc &>"$logpipe"
935 eval $restoretrap
937 wait $teepid
938 rm "$logpipe"
939 else
940 restoretrap=$(trap -p ERR)
941 trap 'error_function $pkgfunc' ERR
942 $pkgfunc 2>&1
943 eval $restoretrap
945 # reset our shell options
946 eval "$shellopts"
949 run_build() {
950 # use distcc if it is requested (check buildenv and PKGBUILD opts)
951 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
952 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
953 export DISTCC_HOSTS
956 # use ccache if it is requested (check buildenv and PKGBUILD opts)
957 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
958 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
961 run_function "build"
964 run_check() {
965 run_function "check"
968 run_package() {
969 local pkgfunc
970 if [[ -z $1 ]]; then
971 pkgfunc="package"
972 else
973 pkgfunc="package_$1"
976 run_function "$pkgfunc"
979 tidy_install() {
980 cd_safe "$pkgdir"
981 msg "$(gettext "Tidying install...")"
983 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
984 msg2 "$(gettext "Removing doc files...")"
985 rm -rf -- ${DOC_DIRS[@]}
988 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
989 msg2 "$(gettext "Purging unwanted files...")"
990 local pt
991 for pt in "${PURGE_TARGETS[@]}"; do
992 if [[ ${pt} = "${pt//\/}" ]]; then
993 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
994 else
995 rm -f ${pt}
997 done
1000 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
1001 msg2 "$(gettext "Compressing man and info pages...")"
1002 local manpage ext file link hardlinks hl
1003 find ${MAN_DIRS[@]} -type f 2>/dev/null |
1004 while read manpage ; do
1005 ext="${manpage##*.}"
1006 file="${manpage##*/}"
1007 if [[ $ext != gz && $ext != bz2 ]]; then
1008 # update symlinks to this manpage
1009 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
1010 while read link ; do
1011 rm -f "$link" "${link}.gz"
1012 ln -s -- "${file}.gz" "${link}.gz"
1013 done
1015 # check file still exists (potentially already compressed due to hardlink)
1016 if [[ -f ${manpage} ]]; then
1017 # find hard links and remove them
1018 # the '|| true' part keeps the script from bailing on the EOF returned
1019 # by read at the end of the find output
1020 IFS=$'\n' read -rd '' -a hardlinks < \
1021 <(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" \
1022 2>/dev/null || true) || true
1023 rm -f "${hardlinks[@]}"
1024 # compress the original
1025 gzip -9 "$manpage"
1026 # recreate hard links removed earlier
1027 for hl in "${hardlinks[@]}"; do
1028 ln "${manpage}.gz" "${hl}.gz"
1029 chmod 644 ${hl}.gz
1030 done
1033 done
1036 if [[ $(check_option strip) = "y" ]]; then
1037 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1038 # make sure library stripping variables are defined to prevent excess stripping
1039 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1040 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1041 local binary
1042 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1043 case "$(file -bi "$binary")" in
1044 *application/x-sharedlib*) # Libraries (.so)
1045 strip $STRIP_SHARED "$binary";;
1046 *application/x-archive*) # Libraries (.a)
1047 strip $STRIP_STATIC "$binary";;
1048 *application/x-executable*) # Binaries
1049 strip $STRIP_BINARIES "$binary";;
1050 esac
1051 done
1054 if [[ $(check_option libtool) = "n" ]]; then
1055 msg2 "$(gettext "Removing "%s" files...")" "libtool"
1056 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
1059 if [[ $(check_option emptydirs) = "n" ]]; then
1060 msg2 "$(gettext "Removing empty directories...")"
1061 find . -depth -type d -empty -delete
1064 if [[ $(check_option upx) = "y" ]]; then
1065 msg2 "$(gettext "Compressing binaries with %s...")" "UPX"
1066 local binary
1067 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1068 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1069 upx $UPXFLAGS "$binary" &>/dev/null ||
1070 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1072 done
1076 find_libdepends() {
1077 local libdepends
1078 find "$pkgdir" -type f -perm -u+x | while read filename
1080 # get architecture of the file; if soarch is empty it's not an ELF binary
1081 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1082 [ -n "$soarch" ] || continue
1083 # process all libraries needed by the binary
1084 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1086 # extract the library name: libfoo.so
1087 soname="${sofile%.so?(+(.+([0-9])))}".so
1088 # extract the major version: 1
1089 soversion="${sofile##*\.so\.}"
1090 if in_array "${soname}" ${depends[@]}; then
1091 if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then
1092 # libfoo.so=1-64
1093 printf "%s" "${soname}=${soversion}-${soarch}"
1094 libdepends+=("${soname}=${soversion}-${soarch}")
1097 done
1098 done
1101 find_libprovides() {
1102 local libprovides missing
1103 for p in "${provides[@]}"; do
1104 missing=0
1105 case "$p" in
1106 *.so)
1107 IFS=$'\n' read -rd '' -a filename < <(find "$pkgdir" -type f -name $p\*)
1108 if [[ $filename ]]; then
1109 # packages may provide multiple versions of the same library
1110 for fn in "${filename[@]}"; do
1111 # check if we really have a shared object
1112 if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1113 # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
1114 local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1115 if [[ -z "$sofile" ]]; then
1116 warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
1117 libprovides+=("$p")
1118 continue
1121 # get the library architecture (32 or 64 bit)
1122 local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1124 # extract the library major version
1125 local soversion="${sofile##*\.so\.}"
1127 libprovides+=("${p}=${soversion}-${soarch}")
1128 else
1129 warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
1130 libprovides+=("$p")
1132 done
1133 else
1134 libprovides+=("$p")
1135 missing=1
1139 libprovides+=("$p")
1141 esac
1143 if (( missing )); then
1144 warning "$(gettext "Can not find library listed in %s: %s")" "'provides'" "$p"
1146 done
1148 printf '%s\n' "${libprovides[@]}"
1151 check_license() {
1152 # TODO maybe remove this at some point
1153 # warn if license array is not present or empty
1154 if [[ -z $license ]]; then
1155 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1156 plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
1160 write_pkginfo() {
1161 local builddate=$(date -u "+%s")
1162 if [[ -n $PACKAGER ]]; then
1163 local packager="$PACKAGER"
1164 else
1165 local packager="Unknown Packager"
1168 # btrfs's delayed allocation causes the stat buffers from the kernel to "lie"
1169 # to us momentarily and report 0 blocks allocated (which is how du calculates
1170 # size). Sleeping for a second here is about the dirtiest thing possible,
1171 # but avoids reporting entirely bogus install sizes.
1172 sleep 1
1173 local size="$(@DUPATH@ -sk)"
1174 size="$(( ${size%%[^0-9]*} * 1024 ))"
1176 msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
1177 echo "# Generated by makepkg $myver"
1178 if (( INFAKEROOT )); then
1179 echo "# using $(fakeroot -v)"
1181 echo "# $(LC_ALL=C date -u)"
1182 printf "pkgname = %s\n" "$1"
1183 (( SPLITPKG )) && echo pkgbase = $pkgbase
1184 echo "pkgver = $(get_full_version)"
1185 printf "pkgdesc = %s\n" "$pkgdesc"
1186 printf "url = %s\n" "$url"
1187 printf "builddate = %s\n" "$builddate"
1188 printf "packager = %s\n" "$packager"
1189 printf "size = %s\n" "$size"
1190 printf "arch = %s\n" "$PKGARCH"
1192 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1193 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1194 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1195 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
1196 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1198 IFS=$'\n' read -rd '' -a provides < <(find_libprovides)
1199 [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
1201 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1204 local it
1205 IFS=$'\n' read -rd '' -a libdepends < <(find_libdepends)
1206 depends+=("${libdepends[@]}")
1208 for it in "${depends[@]}"; do
1209 if [[ $it = *.so ]]; then
1210 # check if the entry has been found by find_libdepends
1211 # if not, it's unneeded; tell the user so he can remove it
1212 printf -v re '(^|\s)%s=.*' "$it"
1213 if [[ ! $libdepends =~ $re ]]; then
1214 error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it"
1215 return 1
1217 else
1218 printf "depend = %s\n" "$it"
1220 done
1222 for it in "${packaging_options[@]}"; do
1223 local ret="$(check_option $it)"
1224 if [[ $ret != "?" ]]; then
1225 if [[ $ret = "y" ]]; then
1226 printf "makepkgopt = %s\n" "$it"
1227 else
1228 printf "makepkgopt = %s\n" "!$it"
1231 done
1233 check_license
1236 check_package() {
1237 cd_safe "$pkgdir"
1239 # check existence of backup files
1240 local file
1241 for file in "${backup[@]}"; do
1242 if [[ ! -f $file ]]; then
1243 warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
1245 done
1247 # check for references to the build and package directory
1248 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1249 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
1251 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then
1252 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
1257 create_package() {
1258 if [[ ! -d $pkgdir ]]; then
1259 error "$(gettext "Missing %s directory.")" "pkg/"
1260 plain "$(gettext "Aborting...")"
1261 exit 1 # $E_MISSING_PKGDIR
1264 check_package
1266 cd_safe "$pkgdir"
1267 msg "$(gettext "Creating package...")"
1269 local nameofpkg
1270 if [[ -z $1 ]]; then
1271 nameofpkg="$pkgname"
1272 else
1273 nameofpkg="$1"
1276 if [[ $arch = "any" ]]; then
1277 PKGARCH="any"
1278 else
1279 PKGARCH=$CARCH
1282 write_pkginfo $nameofpkg > .PKGINFO
1284 local comp_files=('.PKGINFO')
1286 # check for changelog/install files
1287 for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1288 IFS='/' read -r orig dest < <(printf '%s\n' "$i")
1290 if [[ -n ${!orig} ]]; then
1291 msg2 "$(gettext "Adding %s file...")" "$orig"
1292 cp "$startdir/${!orig}" "$dest"
1293 chmod 644 "$dest"
1294 comp_files+=("$dest")
1296 done
1298 # tar it up
1299 msg2 "$(gettext "Compressing package...")"
1301 local fullver=$(get_full_version)
1302 local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}"
1303 local ret=0
1305 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1306 [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
1308 # when fileglobbing, we want * in an empty directory to expand to
1309 # the null string rather than itself
1310 shopt -s nullglob
1311 # TODO: Maybe this can be set globally for robustness
1312 shopt -s -o pipefail
1313 # bsdtar's gzip compression always saves the time stamp, making one
1314 # archive created using the same command line distinct from another.
1315 # Disable bsdtar compression and use gzip -n for now.
1316 bsdtar -cf - "${comp_files[@]}" * |
1317 case "$PKGEXT" in
1318 *tar.gz) ${COMPRESSGZ[@]:-gzip -c -f -n} ;;
1319 *tar.bz2) ${COMPRESSBZ2[@]:-bzip2 -c -f} ;;
1320 *tar.xz) ${COMPRESSXZ[@]:-xz -c -z -} ;;
1321 *tar.Z) ${COMPRESSZ[@]:-compress -c -f} ;;
1322 *tar) cat ;;
1323 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1324 "$PKGEXT"; cat ;;
1325 esac > "${pkg_file}" || ret=$?
1327 shopt -u nullglob
1328 shopt -u -o pipefail
1330 if (( ret )); then
1331 error "$(gettext "Failed to create package file.")"
1332 exit 1 # TODO: error code
1335 create_signature "$pkg_file"
1337 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1338 rm -f "${pkg_file/$PKGDEST/$startdir}"
1339 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1340 ret=$?
1341 if [[ -f $pkg_file.sig ]]; then
1342 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1343 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1347 if (( ret )); then
1348 warning "$(gettext "Failed to create symlink to package file.")"
1352 create_signature() {
1353 if [[ $SIGNPKG != 'y' ]]; then
1354 return
1356 local ret=0
1357 local filename="$1"
1358 msg "$(gettext "Signing package...")"
1360 local SIGNWITHKEY=""
1361 if [[ -n $GPGKEY ]]; then
1362 SIGNWITHKEY="-u ${GPGKEY}"
1364 # The signature will be generated directly in ascii-friendly format
1365 gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
1368 if (( ! ret )); then
1369 msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
1370 else
1371 warning "$(gettext "Failed to sign package file.")"
1375 create_srcpackage() {
1376 local ret=0
1377 msg "$(gettext "Creating source package...")"
1378 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1379 mkdir "${srclinks}"/${pkgbase}
1381 check_license
1383 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1384 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1386 local file
1387 for file in "${source[@]}"; do
1388 if [[ "$file" = "$(get_filename "$file")" ]] || (( SOURCEONLY == 2 )); then
1389 local absfile
1390 absfile=$(get_filepath "$file") || missing_source_file "$file"
1391 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1392 ln -s "$absfile" "$srclinks/$pkgbase"
1394 done
1396 local i
1397 for i in 'changelog' 'install'; do
1398 local file
1399 while read -r file; do
1400 # evaluate any bash variables used
1401 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1402 if [[ $file && ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1403 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1404 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1406 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1407 done
1409 local TAR_OPT
1410 case "$SRCEXT" in
1411 *tar.gz) TAR_OPT="z" ;;
1412 *tar.bz2) TAR_OPT="j" ;;
1413 *tar.xz) TAR_OPT="J" ;;
1414 *tar.Z) TAR_OPT="Z" ;;
1415 *tar) TAR_OPT="" ;;
1416 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1417 "$SRCEXT" ;;
1418 esac
1420 local fullver=$(get_full_version)
1421 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1423 # tar it up
1424 msg2 "$(gettext "Compressing source package...")"
1425 cd_safe "${srclinks}"
1426 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1427 error "$(gettext "Failed to create source package file.")"
1428 exit 1 # TODO: error code
1431 if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1432 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1433 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1434 ret=$?
1437 if (( ret )); then
1438 warning "$(gettext "Failed to create symlink to source package file.")"
1441 cd_safe "${startdir}"
1442 rm -rf "${srclinks}"
1445 install_package() {
1446 (( ! INSTALL )) && return
1448 if (( ! SPLITPKG )); then
1449 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1450 else
1451 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1454 local fullver pkg pkglist
1455 for pkg in ${pkgname[@]}; do
1456 fullver=$(get_full_version $pkg)
1457 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then
1458 pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}"
1459 else
1460 pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}"
1462 done
1464 if ! run_pacman -U $pkglist; then
1465 warning "$(gettext "Failed to install built package(s).")"
1466 return 0
1470 check_sanity() {
1471 # check for no-no's in the build script
1472 local i
1473 local ret=0
1474 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1475 if [[ -z ${!i} ]]; then
1476 error "$(gettext "%s is not allowed to be empty.")" "$i"
1477 ret=1
1479 done
1481 for i in "${pkgname[@]}"; do
1482 if [[ ${i:0:1} = "-" ]]; then
1483 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1484 ret=1
1486 done
1488 if [[ ${pkgbase:0:1} = "-" ]]; then
1489 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1490 ret=1
1493 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1494 while IFS='=' read -r _ i; do
1495 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1496 if [[ $i = *[[:space:]:-]* ]]; then
1497 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1498 return 1
1500 done || ret=1
1502 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
1503 while IFS='=' read -r _ i; do
1504 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1505 if [[ $i != +([0-9])?(.+([0-9])) ]]; then
1506 error "$(gettext "%s must be a decimal.")" "pkgrel"
1507 return 1
1509 done || ret=1
1511 awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
1512 while IFS='=' read -r _ i; do
1513 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
1514 if [[ $i != *([[:digit:]]) ]]; then
1515 error "$(gettext "%s must be an integer.")" "epoch"
1516 return 1
1518 done || ret=1
1520 if [[ $arch != 'any' ]]; then
1521 if ! in_array $CARCH ${arch[@]}; then
1522 if (( ! IGNOREARCH )); then
1523 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1524 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1525 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1526 ret=1
1531 if (( ${#pkgname[@]} > 1 )); then
1532 for i in ${pkgname[@]}; do
1533 local arch_list=""
1534 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1535 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1536 if ! in_array $CARCH ${arch_list[@]}; then
1537 if (( ! IGNOREARCH )); then
1538 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1539 ret=1
1543 done
1546 local provides_list=()
1547 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1548 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1549 for i in ${provides_list[@]}; do
1550 if [[ $i == *['<>']* ]]; then
1551 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1552 ret=1
1554 done
1556 local backup_list=()
1557 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1558 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1559 for i in "${backup_list[@]}"; do
1560 if [[ ${i:0:1} = "/" ]]; then
1561 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1562 ret=1
1564 done
1566 local optdepends_list=()
1567 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1568 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1569 for i in "${optdepends_list[@]}"; do
1570 local pkg=${i%%:[[:space:]]*}
1571 # the '-' character _must_ be first or last in the character range
1572 if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then
1573 error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
1574 ret=1
1576 done
1578 for i in 'changelog' 'install'; do
1579 local file
1580 while read -r file; do
1581 # evaluate any bash variables used
1582 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1583 if [[ $file && ! -f $file ]]; then
1584 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1585 ret=1
1587 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1588 done
1590 local valid_options=1
1591 local known kopt options_list
1592 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
1593 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
1594 for i in ${options_list[@]}; do
1595 known=0
1596 # check if option matches a known option or its inverse
1597 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1598 if [[ ${i} = "${kopt}" || ${i} = "!${kopt}" ]]; then
1599 known=1
1601 done
1602 if (( ! known )); then
1603 error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
1604 valid_options=0
1606 done
1607 if (( ! valid_options )); then
1608 ret=1
1611 if (( ${#pkgname[@]} > 1 )); then
1612 for i in ${pkgname[@]}; do
1613 if ! declare -f package_${i} >/dev/null; then
1614 error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
1615 ret=1
1617 done
1620 for i in ${PKGLIST[@]}; do
1621 if ! in_array $i ${pkgname[@]}; then
1622 error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1623 ret=1
1625 done
1627 return $ret
1630 check_software() {
1631 # check for needed software
1632 local ret=0
1634 # check for sudo if we will need it during makepkg execution
1635 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1636 if ! type -p sudo >/dev/null; then
1637 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1641 # fakeroot - building as non-root user
1642 if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1643 if ! type -p fakeroot >/dev/null; then
1644 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
1645 ret=1
1649 # gpg - package signing
1650 if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then
1651 if ! type -p gpg >/dev/null; then
1652 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
1653 ret=1
1657 # gpg - source verification
1658 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
1659 if ! type -p gpg >/dev/null; then
1660 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
1661 ret=1
1665 # openssl - checksum operations
1666 if (( ! SKIPCHECKSUMS )); then
1667 if ! type -p openssl >/dev/null; then
1668 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
1669 ret=1
1673 # upx - binary compression
1674 if [[ $(check_option upx) == 'y' ]]; then
1675 if ! type -p upx >/dev/null; then
1676 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
1677 ret=1
1681 # distcc - compilation with distcc
1682 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
1683 if ! type -p distcc >/dev/null; then
1684 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
1685 ret=1
1689 # ccache - compilation with ccache
1690 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
1691 if ! type -p ccache >/dev/null; then
1692 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
1693 ret=1
1697 # strip - strip symbols from binaries/libraries
1698 if [[ $(check_option strip) = "y" ]]; then
1699 if ! type -p strip >/dev/null; then
1700 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
1701 ret=1
1705 # gzip - compressig man and info pages
1706 if [[ $(check_option zipman) = "y" ]]; then
1707 if ! type -p gzip >/dev/null; then
1708 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
1709 ret=1
1713 return $ret
1716 devel_check() {
1717 newpkgver=""
1719 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1720 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1721 if (( HOLDVER || SOURCEONLY || REPKG )) ||
1722 [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = "/dev/stdin" ]]; then
1723 return
1726 if [[ -z $FORCE_VER ]]; then
1727 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1728 # This will only be used on the first call to makepkg; subsequent
1729 # calls to makepkg via fakeroot will explicitly pass the version
1730 # number to avoid having to determine the version number twice.
1731 # Also do a check to make sure we have the VCS tool available.
1732 local vcs=()
1734 [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] && vcs+=("darcs")
1735 [[ -n ${_cvsroot} && -n ${_cvsmod} ]] && vcs+=("cvs")
1736 [[ -n ${_gitroot} && -n ${_gitname} ]] && vcs+=("git")
1737 [[ -n ${_svntrunk} && -n ${_svnmod} ]] && vcs+=("svn")
1738 [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] && vcs+=("bzr")
1739 [[ -n ${_hgroot} && -n ${_hgrepo} ]] && vcs+=("hg")
1741 if (( ${#vcs[@]} == 0 )); then
1742 return
1743 elif (( ${#vcs[@]} > 1 )); then
1744 warning "$(gettext "Ambiguous VCS package. Cannot pick from: %s.")" "${vcs[*]}"
1745 return 0
1748 if ! type -p "$vcs" >/dev/null; then
1749 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "$vcs" "$vcs"
1750 return 0
1753 msg "$(gettext "Determining latest %s revision...")" "$vcs"
1755 case "$vcs" in
1756 darcs)
1757 newpkgver=$(date +%Y%m%d)
1759 cvs)
1760 newpkgver=$(date +%Y%m%d)
1762 git)
1763 newpkgver=$(date +%Y%m%d)
1765 svn)
1766 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1768 bzr)
1769 newpkgver=$(bzr revno ${_bzrtrunk})
1772 if pushd "./src/$_hgrepo" > /dev/null; then
1773 local ret=0
1774 hg pull || ret=$?
1775 if (( ! ret )); then
1776 hg update
1777 elif (( ret != 1 )); then
1778 return 1
1780 else
1781 [[ ! -d ./src/ ]] && mkdir ./src/
1782 hg clone "$_hgroot/$_hgrepo" "./src/$_hgrepo"
1783 if ! pushd "./src/$_hgrepo" > /dev/null; then
1784 warning "$(gettext "An error occured while determining the hg version number.")"
1785 return 0
1788 newpkgver=$(hg tip --template "{rev}")
1789 popd > /dev/null
1791 esac
1793 if [[ -n $newpkgver ]]; then
1794 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1797 else
1798 # Version number retrieved from fakeroot->makepkg argument
1799 newpkgver=$FORCE_VER
1803 devel_update() {
1804 # This is lame, but if we're wanting to use an updated pkgver for
1805 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1806 # the new pkgver and then re-source it. This is the most robust
1807 # method for dealing with PKGBUILDs that use, e.g.:
1809 # pkgver=23
1810 # ...
1811 # _foo=pkgver
1813 if [[ -n $newpkgver ]]; then
1814 if [[ $newpkgver != "$pkgver" ]]; then
1815 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1816 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1817 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1818 source "$BUILDFILE"
1824 backup_package_variables() {
1825 local var
1826 for var in ${splitpkg_overrides[@]}; do
1827 local indirect="${var}_backup"
1828 eval "${indirect}=(\"\${$var[@]}\")"
1829 done
1832 restore_package_variables() {
1833 local var
1834 for var in ${splitpkg_overrides[@]}; do
1835 local indirect="${var}_backup"
1836 if [[ -n ${!indirect} ]]; then
1837 eval "${var}=(\"\${$indirect[@]}\")"
1838 else
1839 unset ${var}
1841 done
1844 run_split_packaging() {
1845 local pkgname_backup=${pkgname[@]}
1846 for pkgname in ${pkgname_backup[@]}; do
1847 pkgdir="$pkgdir/$pkgname"
1848 mkdir -p "$pkgdir"
1849 chmod a-s "$pkgdir"
1850 backup_package_variables
1851 run_package $pkgname
1852 tidy_install
1853 create_package $pkgname
1854 restore_package_variables
1855 pkgdir="${pkgdir%/*}"
1856 done
1857 pkgname=${pkgname_backup[@]}
1860 # Canonicalize a directory path if it exists
1861 canonicalize_path() {
1862 local path="$1";
1864 if [[ -d $path ]]; then
1866 cd_safe "$path"
1867 pwd -P
1869 else
1870 printf "%s\n" "$path"
1874 m4_include(library/parse_options.sh)
1876 usage() {
1877 printf "makepkg (pacman) %s\n" "$myver"
1878 echo
1879 printf -- "$(gettext "Usage: %s [options]")\n" "$0"
1880 echo
1881 printf -- "$(gettext "Options:")\n"
1882 printf -- "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
1883 printf -- "$(gettext " -c, --clean Clean up work files after build")\n"
1884 printf -- "$(gettext " -d, --nodeps Skip all dependency checks")\n"
1885 printf -- "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
1886 printf -- "$(gettext " -f, --force Overwrite existing package")\n"
1887 printf -- "$(gettext " -g, --geninteg Generate integrity checks for source files")\n"
1888 printf -- "$(gettext " -h, --help Show this help message and exit")\n"
1889 printf -- "$(gettext " -i, --install Install package after successful build")\n"
1890 printf -- "$(gettext " -L, --log Log package build process")\n"
1891 printf -- "$(gettext " -m, --nocolor Disable colorized output messages")\n"
1892 printf -- "$(gettext " -o, --nobuild Download and extract files only")\n"
1893 printf -- "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1894 printf -- "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")\n"
1895 printf -- "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")\n"
1896 printf -- "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
1897 printf -- "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")\n"
1898 printf -- "$(gettext " --allsource Generate a source-only tarball including downloaded sources")\n"
1899 printf -- "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
1900 printf -- "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1901 printf -- "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1902 printf -- "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1903 printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
1904 printf -- "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1905 printf -- "$(gettext " --nosign Do not create a signature for the package")\n"
1906 printf -- "$(gettext " --pkg <list> Only build listed packages from a split package")\n"
1907 printf -- "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
1908 printf -- "$(gettext " --skipchecksums Do not verify checksums of the source files")\n"
1909 printf -- "$(gettext " --skipinteg Do not perform any verification checks on source files")\n"
1910 printf -- "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")\n"
1911 echo
1912 printf -- "$(gettext "These options can be passed to %s:")\n" "pacman"
1913 echo
1914 printf -- "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")\n"
1915 printf -- "$(gettext " --noprogressbar Do not show a progress bar when downloading files")\n"
1916 echo
1917 printf -- "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
1918 echo
1921 version() {
1922 printf "makepkg (pacman) %s\n" "$myver"
1923 printf -- "$(gettext "\
1924 Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1925 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1926 This is free software; see the source for copying conditions.\n\
1927 There is NO WARRANTY, to the extent permitted by law.\n")"
1930 # PROGRAM START
1932 # determine whether we have gettext; make it a no-op if we do not
1933 if ! type -p gettext >/dev/null; then
1934 gettext() {
1935 printf "%s\n" "$@"
1939 ARGLIST=("$@")
1941 # Parse Command Line Options.
1942 OPT_SHORT="AcdefFghiLmop:rRsSV"
1943 OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
1944 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck"
1945 OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
1946 OPT_LONG+=",repackage,skipchecksums,skipinteg,skippgpcheck,sign,source,syncdeps"
1947 OPT_LONG+=",version,config:"
1949 # Pacman Options
1950 OPT_LONG+=",noconfirm,noprogressbar"
1951 if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
1952 echo; usage; exit 1 # E_INVALID_OPTION;
1954 eval set -- "$OPT_TEMP"
1955 unset OPT_SHORT OPT_LONG OPT_TEMP
1957 while true; do
1958 case "$1" in
1959 # Pacman Options
1960 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1961 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1963 # Makepkg Options
1964 --allsource) SOURCEONLY=2 ;;
1965 --asroot) ASROOT=1 ;;
1966 -A|--ignorearch) IGNOREARCH=1 ;;
1967 -c|--clean) CLEANUP=1 ;;
1968 --check) RUN_CHECK='y' ;;
1969 --config) shift; MAKEPKG_CONF=$1 ;;
1970 -d|--nodeps) NODEPS=1 ;;
1971 -e|--noextract) NOEXTRACT=1 ;;
1972 -f|--force) FORCE=1 ;;
1973 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1974 --forcever) shift; FORCE_VER=$1;;
1975 -F) INFAKEROOT=1 ;;
1976 -g|--geninteg) GENINTEG=1 ;;
1977 --holdver) HOLDVER=1 ;;
1978 -i|--install) INSTALL=1 ;;
1979 --key) shift; GPGKEY=$1 ;;
1980 -L|--log) LOGGING=1 ;;
1981 -m|--nocolor) USE_COLOR='n' ;;
1982 --nocheck) RUN_CHECK='n' ;;
1983 --nosign) SIGNPKG='n' ;;
1984 -o|--nobuild) NOBUILD=1 ;;
1985 -p) shift; BUILDFILE=$1 ;;
1986 --pkg) shift; PKGLIST=($1) ;;
1987 -r|--rmdeps) RMDEPS=1 ;;
1988 -R|--repackage) REPKG=1 ;;
1989 --skipchecksums) SKIPCHECKSUMS=1 ;;
1990 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
1991 --skippgpcheck) SKIPPGPCHECK=1;;
1992 --sign) SIGNPKG='y' ;;
1993 -s|--syncdeps) DEP_BIN=1 ;;
1994 -S|--source) SOURCEONLY=1 ;;
1996 -h|--help) usage; exit 0 ;; # E_OK
1997 -V|--version) version; exit 0 ;; # E_OK
1999 --) OPT_IND=0; shift; break;;
2000 *) usage; exit 1 ;; # E_INVALID_OPTION
2001 esac
2002 shift
2003 done
2005 # setup signal traps
2006 trap 'clean_up' 0
2007 for signal in TERM HUP QUIT; do
2008 trap "trap_exit $signal \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal"
2009 done
2010 trap 'trap_exit INT "$(gettext "Aborted by user! Exiting...")"' INT
2011 trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' ERR
2012 set -E
2014 # preserve environment variables and canonicalize path
2015 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
2016 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
2017 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
2018 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
2019 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
2020 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
2021 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
2022 [[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
2024 # default config is makepkg.conf
2025 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
2027 # Source the config file; fail if it is not found
2028 if [[ -r $MAKEPKG_CONF ]]; then
2029 source "$MAKEPKG_CONF"
2030 else
2031 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
2032 plain "$(gettext "Aborting...")"
2033 exit 1 # $E_CONFIG_ERROR
2036 # Source user-specific makepkg.conf overrides, but only if no override config
2037 # file was specified
2038 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
2039 source ~/.makepkg.conf
2042 # set pacman command if not already defined
2043 PACMAN=${PACMAN:-pacman}
2045 # check if messages are to be printed using color
2046 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
2047 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
2048 # prefer terminal safe colored and bold text when tput is supported
2049 if tput setaf 0 &>/dev/null; then
2050 ALL_OFF="$(tput sgr0)"
2051 BOLD="$(tput bold)"
2052 BLUE="${BOLD}$(tput setaf 4)"
2053 GREEN="${BOLD}$(tput setaf 2)"
2054 RED="${BOLD}$(tput setaf 1)"
2055 YELLOW="${BOLD}$(tput setaf 3)"
2056 else
2057 ALL_OFF="\e[1;0m"
2058 BOLD="\e[1;1m"
2059 BLUE="${BOLD}\e[1;34m"
2060 GREEN="${BOLD}\e[1;32m"
2061 RED="${BOLD}\e[1;31m"
2062 YELLOW="${BOLD}\e[1;33m"
2065 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2067 # override settings with an environment variable for batch processing
2068 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2069 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2070 if [[ ! -d $BUILDDIR ]]; then
2071 if ! mkdir -p "$BUILDDIR"; then
2072 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2073 plain "$(gettext "Aborting...")"
2074 exit 1
2076 chmod a-s "$BUILDDIR"
2078 if [[ ! -w $BUILDDIR ]]; then
2079 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2080 plain "$(gettext "Aborting...")"
2081 exit 1
2084 PKGDEST=${_PKGDEST:-$PKGDEST}
2085 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2086 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2087 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2088 plain "$(gettext "Aborting...")"
2089 exit 1
2092 SRCDEST=${_SRCDEST:-$SRCDEST}
2093 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2094 if [[ ! -w $SRCDEST ]] ; then
2095 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2096 plain "$(gettext "Aborting...")"
2097 exit 1
2100 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2101 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2102 if (( SOURCEONLY )) && [[ ! -w $SRCPKGDEST ]]; then
2103 error "$(gettext "You do not have write permission to store source tarballs in %s.")" "$SRCPKGDEST"
2104 plain "$(gettext "Aborting...")"
2105 exit 1
2108 PKGEXT=${_PKGEXT:-$PKGEXT}
2109 SRCEXT=${_SRCEXT:-$SRCEXT}
2110 GPGKEY=${_GPGKEY:-$GPGKEY}
2111 PACKAGER=${_PACKAGER:-$PACKAGER}
2113 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
2114 # The '\\0' is here to prevent gettext from thinking --holdver is an option
2115 error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
2116 exit 1
2119 if (( ! INFAKEROOT )); then
2120 if (( EUID == 0 && ! ASROOT )); then
2121 # Warn those who like to live dangerously.
2122 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2123 catastrophic damage to your system. If you wish to run as root, please\n\
2124 use the %s option.")" "makepkg" "--asroot"
2125 exit 1 # $E_USER_ABORT
2126 elif (( EUID > 0 && ASROOT )); then
2127 # Warn those who try to use the --asroot option when they are not root
2128 error "$(gettext "The %s option is meant for the root user only. Please\n\
2129 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2130 exit 1 # $E_USER_ABORT
2131 elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
2132 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2133 ownership of the packaged files. Try using the %s environment by\n\
2134 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF"
2135 sleep 1
2137 else
2138 if [[ -z $FAKEROOTKEY ]]; then
2139 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2140 exit 1 # TODO: error code
2144 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2145 unset md5sums replaces depends conflicts backup source install changelog build
2146 unset makedepends optdepends options noextract
2148 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2149 if [[ ! -f $BUILDFILE ]]; then
2150 if [[ -t 0 ]]; then
2151 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2152 exit 1
2153 else
2154 # PKGBUILD passed through a pipe
2155 BUILDFILE=/dev/stdin
2156 shopt -u extglob
2157 source "$BUILDFILE"
2158 shopt -s extglob
2160 else
2161 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2162 if [[ -n $crlftest ]]; then
2163 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2164 exit 1
2167 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2168 BUILDFILE="$startdir/$BUILDFILE"
2170 shopt -u extglob
2171 source "$BUILDFILE"
2172 shopt -s extglob
2175 # set defaults if they weren't specified in buildfile
2176 pkgbase=${pkgbase:-${pkgname[0]}}
2177 epoch=${epoch:-0}
2179 if [[ $BUILDDIR = "$startdir" ]]; then
2180 srcdir="$BUILDDIR/src"
2181 pkgdir="$BUILDDIR/pkg"
2182 else
2183 srcdir="$BUILDDIR/$pkgbase/src"
2184 pkgdir="$BUILDDIR/$pkgbase/pkg"
2187 if (( GENINTEG )); then
2188 mkdir -p "$srcdir"
2189 chmod a-s "$srcdir"
2190 cd_safe "$srcdir"
2191 download_sources
2192 generate_checksums
2193 exit 0 # $E_OK
2196 # check the PKGBUILD for some basic requirements
2197 check_sanity || exit 1
2199 # check we have the software required to process the PKGBUILD
2200 check_software || exit 1
2202 # We need to run devel_update regardless of whether we are in the fakeroot
2203 # build process so that if the user runs makepkg --forcever manually, we
2204 # 1) output the correct pkgver, and 2) use the correct filename when
2205 # checking if the package file already exists - fixes FS #9194
2206 devel_check
2207 devel_update
2209 if (( ${#pkgname[@]} > 1 )); then
2210 SPLITPKG=1
2213 # test for available PKGBUILD functions
2214 if declare -f build >/dev/null; then
2215 BUILDFUNC=1
2217 if declare -f check >/dev/null; then
2218 # "Hide" check() function if not going to be run
2219 if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then
2220 CHECKFUNC=1
2223 if declare -f package >/dev/null; then
2224 PKGFUNC=1
2225 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
2226 SPLITPKG=1
2229 if [[ -n "${PKGLIST[@]}" ]]; then
2230 unset pkgname
2231 pkgname=("${PKGLIST[@]}")
2234 # check if gpg signature is to be created and if signing key is valid
2235 [[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign)
2236 if [[ $SIGNPKG == 'y' ]]; then
2237 if ! gpg --list-key ${GPGKEY} &>/dev/null; then
2238 if [[ ! -z $GPGKEY ]]; then
2239 error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2240 else
2241 error "$(gettext "There is no key in your keyring.")"
2243 exit 1
2248 if (( ! SPLITPKG )); then
2249 fullver=$(get_full_version)
2250 if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \
2251 || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \
2252 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2253 if (( INSTALL )); then
2254 warning "$(gettext "A package has already been built, installing existing package...")"
2255 install_package
2256 exit $?
2257 else
2258 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2259 exit 1
2262 else
2263 allpkgbuilt=1
2264 somepkgbuilt=0
2265 for pkg in ${pkgname[@]}; do
2266 fullver=$(get_full_version $pkg)
2267 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \
2268 || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then
2269 somepkgbuilt=1
2270 else
2271 allpkgbuilt=0
2273 done
2274 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2275 if (( allpkgbuilt )); then
2276 if (( INSTALL )); then
2277 warning "$(gettext "The package group has already been built, installing existing packages...")"
2278 install_package
2279 exit $?
2280 else
2281 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2282 exit 1
2285 if (( somepkgbuilt )); then
2286 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2287 exit 1
2290 unset allpkgbuilt somepkgbuilt
2293 # Run the bare minimum in fakeroot
2294 if (( INFAKEROOT )); then
2295 if (( SOURCEONLY )); then
2296 create_srcpackage
2297 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2298 exit 0 # $E_OK
2301 if (( ! SPLITPKG )); then
2302 if (( ! PKGFUNC )); then
2303 if (( ! REPKG )); then
2304 if (( BUILDFUNC )); then
2305 run_build
2306 (( CHECKFUNC )) && run_check
2307 tidy_install
2309 else
2310 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2311 plain "$(gettext "File permissions may not be preserved.")"
2313 else
2314 run_package
2315 tidy_install
2317 create_package
2318 else
2319 run_split_packaging
2322 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2323 exit 0 # $E_OK
2326 fullver=$(get_full_version)
2327 msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2329 # if we are creating a source-only package, go no further
2330 if (( SOURCEONLY )); then
2331 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2332 && (( ! FORCE )); then
2333 error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2334 exit 1
2337 # Get back to our src directory so we can begin with sources.
2338 mkdir -p "$srcdir"
2339 chmod a-s "$srcdir"
2340 cd_safe "$srcdir"
2341 if ( (( ! SKIPCHECKSUMS )) || \
2342 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \
2343 (( SOURCEONLY == 2 )); then
2344 download_sources
2346 check_source_integrity
2347 cd_safe "$startdir"
2349 # if we are root or if fakeroot is not enabled, then we don't use it
2350 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2351 create_srcpackage
2352 else
2353 enter_fakeroot
2356 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2357 exit 0
2360 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
2361 # no warning message needed for nobuild, repkg
2362 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
2363 warning "$(gettext "Skipping dependency checks.")"
2365 elif type -p "${PACMAN%% *}" >/dev/null; then
2366 if (( RMDEPS && ! INSTALL )); then
2367 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2369 deperr=0
2371 msg "$(gettext "Checking runtime dependencies...")"
2372 resolve_deps ${depends[@]} || deperr=1
2374 if (( RMDEPS && INSTALL )); then
2375 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2378 msg "$(gettext "Checking buildtime dependencies...")"
2379 resolve_deps ${makedepends[@]} || deperr=1
2381 if (( CHECKFUNC )); then
2382 resolve_deps ${checkdepends[@]} || deperr=1
2385 if (( RMDEPS )); then
2386 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2389 if (( deperr )); then
2390 error "$(gettext "Could not resolve all dependencies.")"
2391 exit 1
2393 else
2394 warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
2397 # ensure we have a sane umask set
2398 umask 0022
2400 # get back to our src directory so we can begin with sources
2401 mkdir -p "$srcdir"
2402 chmod a-s "$srcdir"
2403 cd_safe "$srcdir"
2405 if (( NOEXTRACT )); then
2406 warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
2407 warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
2408 warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
2410 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
2411 error "$(gettext "The source directory is empty, there is nothing to build!")"
2412 plain "$(gettext "Aborting...")"
2413 exit 1
2415 elif (( REPKG )); then
2416 if (( ! PKGFUNC && ! SPLITPKG )) \
2417 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
2418 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2419 plain "$(gettext "Aborting...")"
2420 exit 1
2422 else
2423 download_sources
2424 check_source_integrity
2425 extract_sources
2428 if (( NOBUILD )); then
2429 msg "$(gettext "Sources are ready.")"
2430 exit 0 #E_OK
2431 else
2432 # check for existing pkg directory; don't remove if we are repackaging
2433 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2434 msg "$(gettext "Removing existing %s directory...")" "pkg/"
2435 rm -rf "$pkgdir"
2437 mkdir -p "$pkgdir"
2438 chmod a-s "$pkgdir"
2439 cd_safe "$startdir"
2441 # if we are root or if fakeroot is not enabled, then we don't use it
2442 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2443 if (( ! REPKG )); then
2444 devel_update
2445 (( BUILDFUNC )) && run_build
2446 (( CHECKFUNC )) && run_check
2448 if (( ! SPLITPKG )); then
2449 if (( PKGFUNC )); then
2450 run_package
2451 tidy_install
2452 else
2453 if (( ! REPKG )); then
2454 tidy_install
2455 else
2456 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2457 plain "$(gettext "File permissions may not be preserved.")"
2460 create_package
2461 else
2462 run_split_packaging
2464 else
2465 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2466 devel_update
2467 (( BUILDFUNC )) && run_build
2468 (( CHECKFUNC )) && run_check
2469 cd_safe "$startdir"
2472 enter_fakeroot
2476 fullver=$(get_full_version)
2477 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
2479 install_package
2481 exit 0 #E_OK
2483 # vim: set ts=2 sw=2 noet: