download callback: show decimal places in rate if we have room
[pacman-ng.git] / scripts / makepkg.sh.in
blob5981603bf30b975ff8aab365638cdc5573cafdf8
1 #!/bin/bash -e
3 # makepkg - make packages compatible for use with pacman
4 # @configure_input@
6 # Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
7 # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
8 # Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
9 # Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
10 # Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
11 # Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
12 # Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
28 # makepkg uses quite a few external programs during its execution. You
29 # need to have at least the following installed for makepkg to function:
30 # awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
31 # gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
33 # gettext initialization
34 export TEXTDOMAIN='pacman-scripts'
35 export TEXTDOMAINDIR='@localedir@'
37 # file -i does not work on Mac OSX unless legacy mode is set
38 export COMMAND_MODE='legacy'
40 myver='@PACKAGE_VERSION@'
41 confdir='@sysconfdir@'
42 BUILDSCRIPT='@BUILDSCRIPT@'
43 startdir="$PWD"
45 packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx')
46 other_options=('ccache' 'distcc' 'buildflags' 'makeflags')
47 splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'license' \
48 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \
49 'replaces' 'backup' 'options' 'install' 'changelog')
50 readonly -a packaging_options other_options splitpkg_overrides
52 # Options
53 ASROOT=0
54 CLEANUP=0
55 DEP_BIN=0
56 FORCE=0
57 INFAKEROOT=0
58 GENINTEG=0
59 SKIPCHECKSUMS=0
60 SKIPPGPCHECK=0
61 INSTALL=0
62 NOBUILD=0
63 NODEPS=0
64 NOEXTRACT=0
65 RMDEPS=0
66 REPKG=0
67 LOGGING=0
68 SOURCEONLY=0
69 IGNOREARCH=0
70 HOLDVER=0
71 BUILDFUNC=0
72 CHECKFUNC=0
73 PKGFUNC=0
74 SPLITPKG=0
75 PKGLIST=()
76 SIGNPKG=''
78 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
79 # when dealing with svn/cvs/etc PKGBUILDs.
80 FORCE_VER=""
82 PACMAN_OPTS=
84 shopt -s extglob
86 ### SUBROUTINES ###
88 plain() {
89 local mesg=$1; shift
90 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
93 msg() {
94 local mesg=$1; shift
95 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
98 msg2() {
99 local mesg=$1; shift
100 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
103 warning() {
104 local mesg=$1; shift
105 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
108 error() {
109 local mesg=$1; shift
110 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
115 # Special exit call for traps, Don't print any error messages when inside,
116 # the fakeroot call, the error message will be printed by the main call.
118 trap_exit() {
119 if (( ! INFAKEROOT )); then
120 echo
121 error "$@"
123 [[ -n $srclinks ]] && rm -rf "$srclinks"
124 exit 1
129 # Clean up function. Called automatically when the script exits.
131 clean_up() {
132 local EXIT_CODE=$?
134 if (( INFAKEROOT )); then
135 # Don't clean up when leaving fakeroot, we're not done yet.
136 return
139 if (( ! EXIT_CODE && CLEANUP )); then
140 local pkg file
142 # If it's a clean exit and -c/--clean has been passed...
143 msg "$(gettext "Cleaning up...")"
144 rm -rf "$pkgdir" "$srcdir"
145 if [[ -n $pkgbase ]]; then
146 local fullver=$(get_full_version)
147 # Can't do this unless the BUILDSCRIPT has been sourced.
148 if (( BUILDFUNC )); then
149 rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
151 if (( CHECKFUNC )); then
152 rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
154 if (( PKGFUNC )); then
155 rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
156 elif (( SPLITPKG )); then
157 for pkg in ${pkgname[@]}; do
158 rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
159 done
162 # clean up dangling symlinks to packages
163 for pkg in ${pkgname[@]}; do
164 for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do
165 if [[ -h $file && ! -e $file ]]; then
166 rm -f $file
168 done
169 done
173 remove_deps
178 # Signal Traps
180 set -E
181 trap 'clean_up' 0
182 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
183 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
184 trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
186 enter_fakeroot() {
187 msg "$(gettext "Entering %s environment...")" "fakeroot"
189 if [[ -n $newpkgver ]]; then
190 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
191 else
192 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
197 # a source entry can have two forms :
198 # 1) "filename::http://path/to/file"
199 # 2) "http://path/to/file"
201 # Return the absolute filename of a source entry
203 # This function accepts a source entry or the already extracted filename of a
204 # source entry as input
205 get_filepath() {
206 local file="$(get_filename "$1")"
208 if [[ -f "$startdir/$file" ]]; then
209 file="$startdir/$file"
210 elif [[ -f "$SRCDEST/$file" ]]; then
211 file="$SRCDEST/$file"
212 else
213 return 1
216 echo "$file"
219 # Print 'source not found' error message and exit makepkg
220 missing_source_file() {
221 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
222 plain "$(gettext "Aborting...")"
223 exit 1 # $E_MISSING_FILE
226 # extract the filename from a source entry
227 get_filename() {
228 # if a filename is specified, use it
229 local filename="${1%%::*}"
230 # if it is just an URL, we only keep the last component
231 echo "${filename##*/}"
234 # extract the URL from a source entry
235 get_url() {
236 # strip an eventual filename
237 echo "${1#*::}"
241 # usage : get_full_version( [$pkgname] )
242 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
244 get_full_version() {
245 if [[ -z $1 ]]; then
246 if [[ $epoch ]] && (( ! $epoch )); then
247 echo $pkgver-$pkgrel
248 else
249 echo $epoch:$pkgver-$pkgrel
251 else
252 for i in pkgver pkgrel epoch; do
253 local indirect="${i}_override"
254 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
255 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
256 done
257 if (( ! $epoch_override )); then
258 echo $pkgver_override-$pkgrel_override
259 else
260 echo $epoch_override:$pkgver_override-$pkgrel_override
266 # Checks to see if options are present in makepkg.conf or PKGBUILD;
267 # PKGBUILD options always take precedence.
269 # usage : check_option( $option )
270 # return : y - enabled
271 # n - disabled
272 # ? - not found
274 check_option() {
275 local ret=$(in_opt_array "$1" ${options[@]})
276 if [[ $ret != '?' ]]; then
277 echo $ret
278 return
281 # fall back to makepkg.conf options
282 ret=$(in_opt_array "$1" ${OPTIONS[@]})
283 if [[ $ret != '?' ]]; then
284 echo $ret
285 return
288 echo '?' # Not Found
293 # Check if option is present in BUILDENV
295 # usage : check_buildenv( $option )
296 # return : y - enabled
297 # n - disabled
298 # ? - not found
300 check_buildenv() {
301 in_opt_array "$1" ${BUILDENV[@]}
306 # usage : in_opt_array( $needle, $haystack )
307 # return : y - enabled
308 # n - disabled
309 # ? - not found
311 in_opt_array() {
312 local needle=$1; shift
314 local opt
315 for opt in "$@"; do
316 if [[ $opt = $needle ]]; then
317 echo 'y' # Enabled
318 return
319 elif [[ $opt = "!$needle" ]]; then
320 echo 'n' # Disabled
321 return
323 done
325 echo '?' # Not Found
330 # usage : in_array( $needle, $haystack )
331 # return : 0 - found
332 # 1 - not found
334 in_array() {
335 local needle=$1; shift
336 local item
337 for item in "$@"; do
338 [[ $item = $needle ]] && return 0 # Found
339 done
340 return 1 # Not Found
343 source_has_signatures(){
344 local file
345 for file in "${source[@]}"; do
346 if [[ $file = *.@(sig|asc) ]]; then
347 return 0
349 done
350 return 1
353 get_downloadclient() {
354 # $1 = URL with valid protocol prefix
355 local url=$1
356 local proto="${url%%://*}"
358 # loop through DOWNLOAD_AGENTS variable looking for protocol
359 local i
360 for i in "${DLAGENTS[@]}"; do
361 local handler="${i%%::*}"
362 if [[ $proto = $handler ]]; then
363 local agent="${i##*::}"
364 break
366 done
368 # if we didn't find an agent, return an error
369 if [[ -z $agent ]]; then
370 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
371 plain "$(gettext "Aborting...")"
372 exit 1 # $E_CONFIG_ERROR
375 # ensure specified program is installed
376 local program="${agent%% *}"
377 if [[ ! -x $program ]]; then
378 local baseprog="${program##*/}"
379 error "$(gettext "The download program %s is not installed.")" "$baseprog"
380 plain "$(gettext "Aborting...")"
381 exit 1 # $E_MISSING_PROGRAM
384 echo "$agent"
387 download_file() {
388 # download command
389 local dlcmd=$1
390 # URL of the file
391 local url=$2
392 # destination file
393 local file=$3
394 # temporary download file, default to last component of the URL
395 local dlfile="${url##*/}"
397 # replace %o by the temporary dlfile if it exists
398 if [[ $dlcmd = *%o* ]]; then
399 dlcmd=${dlcmd//\%o/\"$file.part\"}
400 dlfile="$file.part"
402 # add the URL, either in place of %u or at the end
403 if [[ $dlcmd = *%u* ]]; then
404 dlcmd=${dlcmd//\%u/\"$url\"}
405 else
406 dlcmd="$dlcmd \"$url\""
409 local ret=0
410 eval "$dlcmd || ret=\$?"
411 if (( ret )); then
412 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
413 return $ret
416 # rename the temporary download file to the final destination
417 if [[ $dlfile != $file ]]; then
418 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
422 run_pacman() {
423 local cmd
424 printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
425 if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
426 if type -p sudo >/dev/null; then
427 cmd="sudo $cmd"
428 else
429 cmd="su root -c '$cmd'"
432 eval "$cmd"
435 check_deps() {
436 (( $# > 0 )) || return 0
438 # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility
439 # Also, a non-zero return value is not unexpected and we are manually dealing them
440 set +E
441 local ret=0
442 local pmout
443 pmout=$(run_pacman -T "$@") || ret=$?
444 set -E
446 if (( ret == 127 )); then #unresolved deps
447 echo "$pmout"
448 elif (( ret )); then
449 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
450 return "$ret"
454 handle_deps() {
455 local R_DEPS_SATISFIED=0
456 local R_DEPS_MISSING=1
458 (( $# == 0 )) && return $R_DEPS_SATISFIED
460 local deplist="$*"
462 if (( ! DEP_BIN )); then
463 return $R_DEPS_MISSING
466 if (( DEP_BIN )); then
467 # install missing deps from binary packages (using pacman -S)
468 msg "$(gettext "Installing missing dependencies...")"
470 if ! run_pacman -S --asdeps $deplist; then
471 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
472 exit 1 # TODO: error code
476 # we might need the new system environment
477 # avoid triggering the ERR trap
478 local restoretrap=$(trap -p ERR)
479 trap - ERR
480 source /etc/profile &>/dev/null
481 eval $restoretrap
483 return $R_DEPS_SATISFIED
486 resolve_deps() {
487 local R_DEPS_SATISFIED=0
488 local R_DEPS_MISSING=1
490 # deplist cannot be declared like this: local deplist=$(foo)
491 # Otherwise, the return value will depend on the assignment.
492 local deplist
493 deplist="$(set +E; check_deps $*)" || exit 1
494 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
496 if handle_deps $deplist; then
497 # check deps again to make sure they were resolved
498 deplist="$(set +E; check_deps $*)" || exit 1
499 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
502 msg "$(gettext "Missing Dependencies:")"
503 local dep
504 for dep in $deplist; do
505 msg2 "$dep"
506 done
508 return $R_DEPS_MISSING
511 remove_deps() {
512 (( ! RMDEPS )) && return
514 # check for packages removed during dependency install (e.g. due to conflicts)
515 # removing all installed packages is risky in this case
516 if [[ -n $(comm -23 <(printf "%s\n" "${original_pkglist[@]}") \
517 <(printf "%s\n" "${current_pkglist[@]}")) ]]; then
518 warning "$(gettext "Failed to remove installed dependencies.")"
519 return 0
522 local deplist=($(comm -13 <(printf "%s\n" "${original_pkglist[@]}") \
523 <(printf "%s\n" "${current_pkglist[@]}")))
524 (( ${#deplist[@]} == 0 )) && return
526 msg "Removing installed dependencies..."
527 # exit cleanly on failure to remove deps as package has been built successfully
528 if ! run_pacman -Rn ${deplist[@]}; then
529 warning "$(gettext "Failed to remove installed dependencies.")"
530 return 0
534 download_sources() {
535 msg "$(gettext "Retrieving Sources...")"
537 pushd "$SRCDEST" &>/dev/null
539 local netfile
540 for netfile in "${source[@]}"; do
541 local file=$(get_filepath "$netfile" || true)
542 if [[ -n "$file" ]]; then
543 msg2 "$(gettext "Found %s")" "${file##*/}"
544 rm -f "$srcdir/${file##*/}"
545 ln -s "$file" "$srcdir/"
546 continue
549 file=$(get_filename "$netfile")
550 local url=$(get_url "$netfile")
552 # if we get here, check to make sure it was a URL, else fail
553 if [[ $file = $url ]]; then
554 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
555 exit 1 # $E_MISSING_FILE
558 # find the client we should use for this URL
559 local dlclient=$(get_downloadclient "$url") || exit $?
561 msg2 "$(gettext "Downloading %s...")" "$file"
562 # fix flyspray bug #3289
563 local ret=0
564 download_file "$dlclient" "$url" "$file" || ret=$?
565 if (( ret )); then
566 error "$(gettext "Failure while downloading %s")" "$file"
567 plain "$(gettext "Aborting...")"
568 exit 1
570 rm -f "$srcdir/$file"
571 ln -s "$SRCDEST/$file" "$srcdir/"
572 done
574 popd &>/dev/null
577 get_integlist() {
578 local integ
579 local integlist=()
581 for integ in md5 sha1 sha256 sha384 sha512; do
582 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
583 if [[ -n "$integrity_sums" ]]; then
584 integlist=(${integlist[@]} $integ)
586 done
588 if (( ${#integlist[@]} > 0 )); then
589 echo ${integlist[@]}
590 else
591 echo ${INTEGRITY_CHECK[@]}
595 generate_checksums() {
596 msg "$(gettext "Generating checksums for source files...")"
597 plain ""
599 if ! type -p openssl >/dev/null; then
600 error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
601 exit 1 # $E_MISSING_PROGRAM
604 local integlist
605 if (( $# == 0 )); then
606 integlist=$(get_integlist)
607 else
608 integlist=$@
611 local integ
612 for integ in ${integlist[@]}; do
613 case "$integ" in
614 md5|sha1|sha256|sha384|sha512) : ;;
616 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
617 exit 1;; # $E_CONFIG_ERROR
618 esac
620 local ct=0
621 local numsrc=${#source[@]}
622 echo -n "${integ}sums=("
624 local i
625 local indent=''
626 for (( i = 0; i < ${#integ} + 6; i++ )); do
627 indent="$indent "
628 done
630 local netfile
631 for netfile in "${source[@]}"; do
632 local file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
633 local sum="$(openssl dgst -${integ} "$file")"
634 sum=${sum##* }
635 (( ct )) && echo -n "$indent"
636 echo -n "'$sum'"
637 ct=$(($ct+1))
638 (( $ct < $numsrc )) && echo
639 done
641 echo ")"
642 done
645 check_checksums() {
646 (( SKIPCHECKSUMS )) && return 0
647 (( ! ${#source[@]} )) && return 0
649 local correlation=0
650 local integ required
651 for integ in md5 sha1 sha256 sha384 sha512; do
652 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
653 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
654 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
655 correlation=1
656 local errors=0
657 local idx=0
658 local file
659 for file in "${source[@]}"; do
660 local found=1
661 file="$(get_filename "$file")"
662 echo -n " $file ... " >&2
664 if ! file="$(get_filepath "$file")"; then
665 echo "$(gettext "NOT FOUND")" >&2
666 errors=1
667 found=0
670 if (( $found )) ; then
671 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
672 local realsum="$(openssl dgst -${integ} "$file")"
673 realsum="${realsum##* }"
674 if [[ $expectedsum = $realsum ]]; then
675 echo "$(gettext "Passed")" >&2
676 else
677 echo "$(gettext "FAILED")" >&2
678 errors=1
682 idx=$((idx + 1))
683 done
685 if (( errors )); then
686 error "$(gettext "One or more files did not pass the validity check!")"
687 exit 1 # TODO: error code
689 elif (( ${#integrity_sums[@]} )); then
690 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
691 exit 1 # TODO: error code
693 done
695 if (( ! correlation )); then
696 error "$(gettext "Integrity checks are missing.")"
697 exit 1 # TODO: error code
701 check_pgpsigs() {
702 (( SKIPPGPCHECK )) && return 0
703 ! source_has_signatures && return 0
705 msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
707 local file pubkey
708 local warning=0
709 local errors=0
710 local statusfile=$(mktemp)
712 for file in "${source[@]}"; do
713 file="$(get_filename "$file")"
714 if [[ ! $file = *.@(sig|asc) ]]; then
715 continue
718 printf " %s ... " "${file%.*}" >&2
720 if ! file="$(get_filepath "$file")"; then
721 printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
722 errors=1
723 continue
726 if ! sourcefile="$(get_filepath "${file%.*}")"; then
727 printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
728 errors=1
729 continue
732 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
733 printf '%s' "$(gettext "FAILED")" >&2
734 if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
735 printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
736 warnings=1
737 else
738 errors=1
740 printf '\n' >&2
741 else
742 if grep -q "REVKEYSIG" "$statusfile"; then
743 printf '%s (%s)\n' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
744 errors=1
745 else
746 printf '%s' "$(gettext "Passed")" >&2
747 if grep -q "EXPSIG" "$statusfile"; then
748 printf ' (%s)\n' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
749 warnings=1
750 elif grep -q "EXPKEYSIG" "$statusfile"; then
751 printf ' (%s)\n' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
752 warnings=1
756 done
758 rm -f "$statusfile"
760 if (( errors )); then
761 error "$(gettext "One or more PGP signatures could not be verified!")"
762 exit 1
765 if (( warnings )); then
766 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
767 plain "$(gettext "Please make sure you really trust them.")"
771 check_source_integrity() {
772 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
773 warning "$(gettext "Skipping all source file integrity checks.")"
774 elif (( SKIPCHECKSUMS )); then
775 warning "$(gettext "Skipping verification of source file checksums.")"
776 check_pgpsigs
777 elif (( SKIPPGPCHECK )); then
778 warning "$(gettext "Skipping verification of source file PGP signatures.")"
779 check_checksums
780 else
781 check_checksums
782 check_pgpsigs
786 extract_sources() {
787 msg "$(gettext "Extracting Sources...")"
788 local netfile
789 for netfile in "${source[@]}"; do
790 local file=$(get_filename "$netfile")
791 if in_array "$file" "${noextract[@]}"; then
792 #skip source files in the noextract=() array
793 # these are marked explicitly to NOT be extracted
794 continue
798 # fix flyspray #6246
799 local file_type=$(file -bizL "$file")
800 local ext=${file##*.}
801 local cmd=''
802 case "$file_type" in
803 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
804 cmd="bsdtar" ;;
805 *application/x-gzip*)
806 case "$ext" in
807 gz|z|Z) cmd="gzip" ;;
808 *) continue;;
809 esac ;;
810 *application/x-bzip*)
811 case "$ext" in
812 bz2|bz) cmd="bzip2" ;;
813 *) continue;;
814 esac ;;
815 *application/x-xz*)
816 case "$ext" in
817 xz) cmd="xz" ;;
818 *) continue;;
819 esac ;;
821 # See if bsdtar can recognize the file
822 if bsdtar -tf "$file" -q '*' &>/dev/null; then
823 cmd="bsdtar"
824 else
825 continue
826 fi ;;
827 esac
829 local ret=0
830 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
831 if [[ $cmd = bsdtar ]]; then
832 $cmd -xf "$file" || ret=$?
833 else
834 rm -f "${file%.*}"
835 $cmd -dcf "$file" > "${file%.*}" || ret=$?
837 if (( ret )); then
838 error "$(gettext "Failed to extract %s")" "$file"
839 plain "$(gettext "Aborting...")"
840 exit 1
842 done
844 if (( EUID == 0 )); then
845 # change perms of all source files to root user & root group
846 chown -R 0:0 "$srcdir"
850 error_function() {
851 if [[ -p $logpipe ]]; then
852 rm "$logpipe"
854 # first exit all subshells, then print the error
855 if (( ! BASH_SUBSHELL )); then
856 error "$(gettext "A failure occurred in %s().")" "$1"
857 plain "$(gettext "Aborting...")"
858 remove_deps
860 exit 2 # $E_BUILD_FAILED
863 run_function() {
864 if [[ -z $1 ]]; then
865 return 1
867 local pkgfunc="$1"
869 # clear user-specified buildflags if requested
870 if [[ $(check_option buildflags) = "n" ]]; then
871 unset CFLAGS CXXFLAGS LDFLAGS
874 # clear user-specified makeflags if requested
875 if [[ $(check_option makeflags) = "n" ]]; then
876 unset MAKEFLAGS
879 msg "$(gettext "Starting %s()...")" "$pkgfunc"
880 cd "$srcdir"
882 # ensure all necessary build variables are exported
883 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
884 # save our shell options so pkgfunc() can't override what we need
885 local shellopts=$(shopt -p)
887 local ret=0
888 local restoretrap
889 if (( LOGGING )); then
890 local fullver=$(get_full_version)
891 local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log"
892 if [[ -f $BUILDLOG ]]; then
893 local i=1
894 while true; do
895 if [[ -f $BUILDLOG.$i ]]; then
896 i=$(($i +1))
897 else
898 break
900 done
901 mv "$BUILDLOG" "$BUILDLOG.$i"
904 # ensure overridden package variables survive tee with split packages
905 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
906 mkfifo "$logpipe"
907 tee "$BUILDLOG" < "$logpipe" &
908 local teepid=$!
910 restoretrap=$(trap -p ERR)
911 trap 'error_function $pkgfunc' ERR
912 $pkgfunc &>"$logpipe"
913 eval $restoretrap
915 wait $teepid
916 rm "$logpipe"
917 else
918 restoretrap=$(trap -p ERR)
919 trap 'error_function $pkgfunc' ERR
920 $pkgfunc 2>&1
921 eval $restoretrap
923 # reset our shell options
924 eval "$shellopts"
927 run_build() {
928 # use distcc if it is requested (check buildenv and PKGBUILD opts)
929 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
930 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
931 export DISTCC_HOSTS
934 # use ccache if it is requested (check buildenv and PKGBUILD opts)
935 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
936 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
939 run_function "build"
942 run_check() {
943 run_function "check"
946 run_package() {
947 local pkgfunc
948 if [[ -z $1 ]]; then
949 pkgfunc="package"
950 else
951 pkgfunc="package_$1"
954 run_function "$pkgfunc"
957 tidy_install() {
958 cd "$pkgdir"
959 msg "$(gettext "Tidying install...")"
961 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
962 msg2 "$(gettext "Removing doc files...")"
963 rm -rf ${DOC_DIRS[@]}
966 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
967 msg2 "$(gettext "Purging unwanted files...")"
968 local pt
969 for pt in "${PURGE_TARGETS[@]}"; do
970 if [[ ${pt} = ${pt//\/} ]]; then
971 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
972 else
973 rm -f ${pt}
975 done
978 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
979 msg2 "$(gettext "Compressing man and info pages...")"
980 local manpage ext file link hardlinks hl
981 find ${MAN_DIRS[@]} -type f 2>/dev/null |
982 while read manpage ; do
983 ext="${manpage##*.}"
984 file="${manpage##*/}"
985 if [[ $ext != gz && $ext != bz2 ]]; then
986 # update symlinks to this manpage
987 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
988 while read link ; do
989 rm -f "$link" "${link}.gz"
990 ln -s "${file}.gz" "${link}.gz"
991 done
993 # check file still exists (potentially already compressed due to hardlink)
994 if [[ -f ${manpage} ]]; then
995 # find hard links and remove them
996 # the '|| true' part keeps the script from bailing if find returned an
997 # error, such as when one of the man directories doesn't exist
998 find "${MAN_DIRS[@]}" \! -name "$file" -samefile "$manpage" \
999 -exec rm -f {} \; 2>/dev/null || true
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 file
1358 while read -r file; do
1359 # evaluate any bash variables used
1360 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1361 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1362 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1363 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1365 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1366 done
1368 local TAR_OPT
1369 case "$SRCEXT" in
1370 *tar.gz) TAR_OPT="z" ;;
1371 *tar.bz2) TAR_OPT="j" ;;
1372 *tar.xz) TAR_OPT="J" ;;
1373 *tar) TAR_OPT="" ;;
1374 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1375 "$SRCEXT" ;;
1376 esac
1378 local fullver=$(get_full_version)
1379 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
1381 # tar it up
1382 msg2 "$(gettext "Compressing source package...")"
1383 cd "${srclinks}"
1384 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1385 error "$(gettext "Failed to create source package file.")"
1386 exit 1 # TODO: error code
1389 if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1390 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
1391 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1392 ret=$?
1395 if (( ret )); then
1396 warning "$(gettext "Failed to create symlink to source package file.")"
1399 cd "${startdir}"
1400 rm -rf "${srclinks}"
1403 install_package() {
1404 (( ! INSTALL )) && return
1406 if (( ! SPLITPKG )); then
1407 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
1408 else
1409 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
1412 local fullver pkg pkglist
1413 for pkg in ${pkgname[@]}; do
1414 fullver=$(get_full_version $pkg)
1415 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then
1416 pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}"
1417 else
1418 pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}"
1420 done
1422 if ! run_pacman -U $pkglist; then
1423 warning "$(gettext "Failed to install built package(s).")"
1424 return 0
1428 check_sanity() {
1429 # check for no-no's in the build script
1430 local i
1431 local ret=0
1432 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1433 if [[ -z ${!i} ]]; then
1434 error "$(gettext "%s is not allowed to be empty.")" "$i"
1435 ret=1
1437 done
1439 for i in "${pkgname[@]}"; do
1440 if [[ ${i:0:1} = "-" ]]; then
1441 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1442 ret=1
1444 done
1446 if [[ ${pkgbase:0:1} = "-" ]]; then
1447 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1448 ret=1
1451 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" |
1452 while IFS='=' read -r _ i; do
1453 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1454 if [[ $i = *[[:space:]:-]* ]]; then
1455 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
1456 return 1
1458 done || ret=1
1460 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" |
1461 while IFS='=' read -r _ i; do
1462 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1463 if [[ $i = *[[:space:]-]* ]]; then
1464 error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel"
1465 return 1
1467 done || ret=1
1469 awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" |
1470 while IFS='=' read -r _ i; do
1471 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$i")\"
1472 if [[ $i != *([[:digit:]]) ]]; then
1473 error "$(gettext "%s must be an integer.")" "epoch"
1474 return 1
1476 done || ret=1
1478 if [[ $arch != 'any' ]]; then
1479 if ! in_array $CARCH ${arch[@]}; then
1480 if (( ! IGNOREARCH )); then
1481 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1482 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1483 plain "$(gettext "such as %s.")" "arch=('$CARCH')"
1484 ret=1
1489 if (( ${#pkgname[@]} > 1 )); then
1490 for i in ${pkgname[@]}; do
1491 local arch_list=""
1492 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p')
1493 if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then
1494 if ! in_array $CARCH ${arch_list[@]}; then
1495 if (( ! IGNOREARCH )); then
1496 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
1497 ret=1
1501 done
1504 local provides_list=()
1505 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
1506 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
1507 for i in ${provides_list[@]}; do
1508 if [[ $i != ${i//</} || $i != ${i//>/} ]]; then
1509 error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
1510 ret=1
1512 done
1514 local backup_list=()
1515 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
1516 sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//')
1517 for i in "${backup_list[@]}"; do
1518 if [[ ${i:0:1} = "/" ]]; then
1519 error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
1520 ret=1
1522 done
1524 local optdepends_list=()
1525 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \
1526 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
1527 for i in "${optdepends_list[@]}"; do
1528 local pkg=${i%%:*}
1529 if [[ $pkg != +([[:alnum:]><=.+_-]) ]]; then
1530 error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
1531 ret=1
1533 done
1535 for i in 'changelog' 'install'; do
1536 local file
1537 while read -r file; do
1538 # evaluate any bash variables used
1539 eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
1540 if [[ ! -f $file ]]; then
1541 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1542 ret=1
1544 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1545 done
1547 local valid_options=1
1548 local known kopt options_list
1549 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
1550 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
1551 for i in ${options_list[@]}; do
1552 known=0
1553 # check if option matches a known option or its inverse
1554 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1555 if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then
1556 known=1
1558 done
1559 if (( ! known )); then
1560 error "$(gettext "%s array contains unknown option '%s'")" "options" "$i"
1561 valid_options=0
1563 done
1564 if (( ! valid_options )); then
1565 ret=1
1568 if (( ${#pkgname[@]} > 1 )); then
1569 for i in ${pkgname[@]}; do
1570 if ! declare -f package_${i} >/dev/null; then
1571 error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
1572 ret=1
1574 done
1577 for i in ${PKGLIST[@]}; do
1578 if ! in_array $i ${pkgname[@]}; then
1579 error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1580 ret=1
1582 done
1584 return $ret
1587 check_software() {
1588 # check for needed software
1589 local ret=0
1591 # check for sudo if we will need it during makepkg execution
1592 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1593 if ! type -p sudo >/dev/null; then
1594 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1598 # fakeroot - building as non-root user
1599 if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1600 if ! type -p fakeroot >/dev/null; then
1601 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
1602 ret=1
1606 # gpg - package signing
1607 if [[ $SIGNPKG == 'y' || (-z "$SIGNPKG" && $(check_buildenv sign) == 'y') ]]; then
1608 if ! type -p gpg >/dev/null; then
1609 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
1610 ret=1
1614 # gpg - source verification
1615 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
1616 if ! type -p gpg >/dev/null; then
1617 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
1618 ret=1
1622 # openssl - checksum operations
1623 if (( ! SKIPCHECKSUMS )); then
1624 if ! type -p openssl >/dev/null; then
1625 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
1626 ret=1
1630 # upx - binary compression
1631 if [[ $(check_option upx) == 'y' ]]; then
1632 if ! type -p upx >/dev/null; then
1633 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
1634 ret=1
1638 # distcc - compilation with distcc
1639 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
1640 if ! type -p distcc >/dev/null; then
1641 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
1642 ret=1
1646 # ccache - compilation with ccache
1647 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
1648 if ! type -p ccache >/dev/null; then
1649 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
1650 ret=1
1654 # strip - strip symbols from binaries/libraries
1655 if [[ $(check_option strip) = "y" ]]; then
1656 if ! type -p strip >/dev/null; then
1657 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
1658 ret=1
1662 # gzip - compressig man and info pages
1663 if [[ $(check_option zipman) = "y" ]]; then
1664 if ! type -p gzip >/dev/null; then
1665 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
1666 ret=1
1670 return $ret
1673 devel_check() {
1674 newpkgver=""
1676 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1677 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1678 if (( HOLDVER || SOURCEONLY || REPKG )) ||
1679 [[ ! -f $BUILDFILE || ! -w $BUILDFILE || $BUILDFILE = /dev/stdin ]]; then
1680 return
1683 if [[ -z $FORCE_VER ]]; then
1684 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1685 # This will only be used on the first call to makepkg; subsequent
1686 # calls to makepkg via fakeroot will explicitly pass the version
1687 # number to avoid having to determine the version number twice.
1688 # Also do a check to make sure we have the VCS tool available.
1689 oldpkgver=$pkgver
1690 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1691 if ! type -p darcs >/dev/null; then
1692 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "darcs" "darcs"
1693 return 0
1695 msg "$(gettext "Determining latest %s revision...")" 'darcs'
1696 newpkgver=$(date +%Y%m%d)
1697 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1698 if ! type -p cvs >/dev/null; then
1699 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "cvs" "cvs"
1700 return 0
1702 msg "$(gettext "Determining latest %s revision...")" 'cvs'
1703 newpkgver=$(date +%Y%m%d)
1704 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1705 if ! type -p git >/dev/null; then
1706 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "git" "git"
1707 return 0
1709 msg "$(gettext "Determining latest %s revision...")" 'git'
1710 newpkgver=$(date +%Y%m%d)
1711 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1712 if ! type -p svn >/dev/null; then
1713 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "svn" "svn"
1714 return 0
1716 msg "$(gettext "Determining latest %s revision...")" 'svn'
1717 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1718 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1719 if ! type -p bzr >/dev/null; then
1720 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "bzr" "bzr"
1721 return 0
1723 msg "$(gettext "Determining latest %s revision...")" 'bzr'
1724 newpkgver=$(bzr revno ${_bzrtrunk})
1725 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1726 if ! type -p hg >/dev/null; then
1727 warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "hg" "hg"
1728 return 0
1730 msg "$(gettext "Determining latest %s revision...")" 'hg'
1731 if [[ -d ./src/$_hgrepo ]] ; then
1732 cd ./src/$_hgrepo
1733 hg pull
1734 hg update
1735 else
1736 [[ ! -d ./src/ ]] && mkdir ./src/
1737 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1738 cd ./src/$_hgrepo
1740 newpkgver=$(hg tip --template "{rev}")
1741 cd ../../
1744 if [[ -n $newpkgver ]]; then
1745 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1748 else
1749 # Version number retrieved from fakeroot->makepkg argument
1750 newpkgver=$FORCE_VER
1754 devel_update() {
1755 # This is lame, but if we're wanting to use an updated pkgver for
1756 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1757 # the new pkgver and then re-source it. This is the most robust
1758 # method for dealing with PKGBUILDs that use, e.g.:
1760 # pkgver=23
1761 # ...
1762 # _foo=pkgver
1764 if [[ -n $newpkgver ]]; then
1765 if [[ $newpkgver != $pkgver ]]; then
1766 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1767 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1768 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1769 source "$BUILDFILE"
1775 backup_package_variables() {
1776 local var
1777 for var in ${splitpkg_overrides[@]}; do
1778 local indirect="${var}_backup"
1779 eval "${indirect}=(\"\${$var[@]}\")"
1780 done
1783 restore_package_variables() {
1784 local var
1785 for var in ${splitpkg_overrides[@]}; do
1786 local indirect="${var}_backup"
1787 if [[ -n ${!indirect} ]]; then
1788 eval "${var}=(\"\${$indirect[@]}\")"
1789 else
1790 unset ${var}
1792 done
1795 run_split_packaging() {
1796 local pkgname_backup=${pkgname[@]}
1797 for pkgname in ${pkgname_backup[@]}; do
1798 pkgdir="$pkgdir/$pkgname"
1799 mkdir -p "$pkgdir"
1800 chmod a-s "$pkgdir"
1801 backup_package_variables
1802 run_package $pkgname
1803 tidy_install
1804 create_package $pkgname
1805 restore_package_variables
1806 pkgdir="${pkgdir%/*}"
1807 done
1808 pkgname=${pkgname_backup[@]}
1811 # Canonicalize a directory path if it exists
1812 canonicalize_path() {
1813 local path="$1";
1815 if [[ -d $path ]]; then
1817 cd "$path"
1818 pwd -P
1820 else
1821 echo "$path"
1825 m4_include(library/parse_options.sh)
1827 usage() {
1828 printf "makepkg (pacman) %s\n" "$myver"
1829 echo
1830 printf "$(gettext "Usage: %s [options]")\n" "$0"
1831 echo
1832 echo "$(gettext "Options:")"
1833 printf "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
1834 echo "$(gettext " -c, --clean Clean up work files after build")"
1835 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1836 printf "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
1837 echo "$(gettext " -f, --force Overwrite existing package")"
1838 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1839 echo "$(gettext " -h, --help Show this help message and exit")"
1840 echo "$(gettext " -i, --install Install package after successful build")"
1841 echo "$(gettext " -L, --log Log package build process")"
1842 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1843 echo "$(gettext " -o, --nobuild Download and extract files only")"
1844 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1845 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1846 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1847 printf "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
1848 echo "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")"
1849 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1850 printf "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
1851 printf "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1852 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1853 printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1854 printf "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
1855 printf "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
1856 echo "$(gettext " --nosign Do not create a signature for the package")"
1857 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1858 printf "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
1859 echo "$(gettext " --skipchecksums Do not verify checksums of the source files")"
1860 echo "$(gettext " --skipinteg Do not perform any verification checks on source files")"
1861 echo "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")"
1862 echo
1863 printf "$(gettext "These options can be passed to %s:")\n" "pacman"
1864 echo
1865 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1866 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1867 echo
1868 printf "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
1869 echo
1872 version() {
1873 printf "makepkg (pacman) %s\n" "$myver"
1874 printf "$(gettext "\
1875 Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1876 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1877 This is free software; see the source for copying conditions.\n\
1878 There is NO WARRANTY, to the extent permitted by law.\n")"
1881 # PROGRAM START
1883 # determine whether we have gettext; make it a no-op if we do not
1884 if ! type -p gettext >/dev/null; then
1885 gettext() {
1886 echo "$@"
1890 ARGLIST=("$@")
1892 # Parse Command Line Options.
1893 OPT_SHORT="AcdefFghiLmop:rRsSV"
1894 OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
1895 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck"
1896 OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
1897 OPT_LONG+=",repackage,skipchecksums,skipinteg,skippgpcheck,sign,source,syncdeps"
1898 OPT_LONG+=",version,config:"
1900 # Pacman Options
1901 OPT_LONG+=",noconfirm,noprogressbar"
1902 if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
1903 echo; usage; exit 1 # E_INVALID_OPTION;
1905 eval set -- "$OPT_TEMP"
1906 unset OPT_SHORT OPT_LONG OPT_TEMP
1908 while true; do
1909 case "$1" in
1910 # Pacman Options
1911 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1912 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1914 # Makepkg Options
1915 --allsource) SOURCEONLY=2 ;;
1916 --asroot) ASROOT=1 ;;
1917 -A|--ignorearch) IGNOREARCH=1 ;;
1918 -c|--clean) CLEANUP=1 ;;
1919 --check) RUN_CHECK='y' ;;
1920 --config) shift; MAKEPKG_CONF=$1 ;;
1921 -d|--nodeps) NODEPS=1 ;;
1922 -e|--noextract) NOEXTRACT=1 ;;
1923 -f|--force) FORCE=1 ;;
1924 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1925 --forcever) shift; FORCE_VER=$1;;
1926 -F) INFAKEROOT=1 ;;
1927 -g|--geninteg) GENINTEG=1 ;;
1928 --holdver) HOLDVER=1 ;;
1929 -i|--install) INSTALL=1 ;;
1930 --key) shift; GPGKEY=$1 ;;
1931 -L|--log) LOGGING=1 ;;
1932 -m|--nocolor) USE_COLOR='n' ;;
1933 --nocheck) RUN_CHECK='n' ;;
1934 --nosign) SIGNPKG='n' ;;
1935 -o|--nobuild) NOBUILD=1 ;;
1936 -p) shift; BUILDFILE=$1 ;;
1937 --pkg) shift; PKGLIST=($1) ;;
1938 -r|--rmdeps) RMDEPS=1 ;;
1939 -R|--repackage) REPKG=1 ;;
1940 --skipchecksums) SKIPCHECKSUMS=1 ;;
1941 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
1942 --skippgpcheck) SKIPPGPCHECK=1;;
1943 --sign) SIGNPKG='y' ;;
1944 -s|--syncdeps) DEP_BIN=1 ;;
1945 -S|--source) SOURCEONLY=1 ;;
1947 -h|--help) usage; exit 0 ;; # E_OK
1948 -V|--version) version; exit 0 ;; # E_OK
1950 --) OPT_IND=0; shift; break;;
1951 *) usage; exit 1 ;; # E_INVALID_OPTION
1952 esac
1953 shift
1954 done
1956 # preserve environment variables and canonicalize path
1957 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
1958 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
1959 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
1960 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
1961 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
1962 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
1963 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
1965 # default config is makepkg.conf
1966 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1968 # Source the config file; fail if it is not found
1969 if [[ -r $MAKEPKG_CONF ]]; then
1970 source "$MAKEPKG_CONF"
1971 else
1972 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1973 plain "$(gettext "Aborting...")"
1974 exit 1 # $E_CONFIG_ERROR
1977 # Source user-specific makepkg.conf overrides, but only if no override config
1978 # file was specified
1979 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
1980 source ~/.makepkg.conf
1983 # set pacman command if not already defined
1984 PACMAN=${PACMAN:-pacman}
1986 # check if messages are to be printed using color
1987 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1988 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1989 # prefer terminal safe colored and bold text when tput is supported
1990 if tput setaf 0 &>/dev/null; then
1991 ALL_OFF="$(tput sgr0)"
1992 BOLD="$(tput bold)"
1993 BLUE="${BOLD}$(tput setaf 4)"
1994 GREEN="${BOLD}$(tput setaf 2)"
1995 RED="${BOLD}$(tput setaf 1)"
1996 YELLOW="${BOLD}$(tput setaf 3)"
1997 else
1998 ALL_OFF="\e[1;0m"
1999 BOLD="\e[1;1m"
2000 BLUE="${BOLD}\e[1;34m"
2001 GREEN="${BOLD}\e[1;32m"
2002 RED="${BOLD}\e[1;31m"
2003 YELLOW="${BOLD}\e[1;33m"
2006 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2008 # override settings with an environment variable for batch processing
2009 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2010 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2011 if [[ ! -d $BUILDDIR ]]; then
2012 mkdir -p "$BUILDDIR" ||
2013 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2014 chmod a-s "$BUILDDIR"
2016 if [[ ! -w $BUILDDIR ]]; then
2017 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2018 plain "$(gettext "Aborting...")"
2019 exit 1
2021 srcdir="$BUILDDIR/src"
2022 pkgdir="$BUILDDIR/pkg"
2024 PKGDEST=${_PKGDEST:-$PKGDEST}
2025 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2026 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2027 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2028 plain "$(gettext "Aborting...")"
2029 exit 1
2032 SRCDEST=${_SRCDEST:-$SRCDEST}
2033 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2034 if [[ ! -w $SRCDEST ]] ; then
2035 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2036 plain "$(gettext "Aborting...")"
2037 exit 1
2040 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2041 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2043 PKGEXT=${_PKGEXT:-$PKGEXT}
2044 SRCEXT=${_SRCEXT:-$SRCEXT}
2045 GPGKEY=${_GPGKEY:-$GPGKEY}
2047 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
2048 # The '\\0' is here to prevent gettext from thinking --holdver is an option
2049 error "$(gettext "\\0%s and %s cannot both be specified" )" "--holdver" "--forcever"
2050 exit 1
2053 if (( ! INFAKEROOT )); then
2054 if (( EUID == 0 && ! ASROOT )); then
2055 # Warn those who like to live dangerously.
2056 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2057 catastrophic damage to your system. If you wish to run as root, please\n\
2058 use the %s option.")" "makepkg" "--asroot"
2059 exit 1 # $E_USER_ABORT
2060 elif (( EUID > 0 && ASROOT )); then
2061 # Warn those who try to use the --asroot option when they are not root
2062 error "$(gettext "The %s option is meant for the root user only. Please\n\
2063 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2064 exit 1 # $E_USER_ABORT
2065 elif (( EUID > 0 )) && [[ $(check_buildenv fakeroot) != "y" ]]; then
2066 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2067 ownership of the packaged files. Try using the %s environment by\n\
2068 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot'" "BUILDENV" "$MAKEPKG_CONF"
2069 sleep 1
2071 else
2072 if [[ -z $FAKEROOTKEY ]]; then
2073 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2074 exit 1 # TODO: error code
2078 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2079 unset md5sums replaces depends conflicts backup source install changelog build
2080 unset makedepends optdepends options noextract
2082 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2083 if [[ ! -f $BUILDFILE ]]; then
2084 if [[ -t 0 ]]; then
2085 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2086 exit 1
2087 else
2088 # PKGBUILD passed through a pipe
2089 BUILDFILE=/dev/stdin
2090 source "$BUILDFILE"
2092 else
2093 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2094 if [[ -n $crlftest ]]; then
2095 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2096 exit 1
2099 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2100 BUILDFILE="$startdir/$BUILDFILE"
2102 source "$BUILDFILE"
2105 # set defaults if they weren't specified in buildfile
2106 pkgbase=${pkgbase:-${pkgname[0]}}
2107 epoch=${epoch:-0}
2109 if (( GENINTEG )); then
2110 mkdir -p "$srcdir"
2111 chmod a-s "$srcdir"
2112 cd "$srcdir"
2113 download_sources
2114 generate_checksums
2115 exit 0 # $E_OK
2118 # check the PKGBUILD for some basic requirements
2119 check_sanity || exit 1
2121 # check we have the software required to process the PKGBUILD
2122 check_software || exit 1
2124 # We need to run devel_update regardless of whether we are in the fakeroot
2125 # build process so that if the user runs makepkg --forcever manually, we
2126 # 1) output the correct pkgver, and 2) use the correct filename when
2127 # checking if the package file already exists - fixes FS #9194
2128 devel_check
2129 devel_update
2131 if (( ${#pkgname[@]} > 1 )); then
2132 SPLITPKG=1
2135 # test for available PKGBUILD functions
2136 if declare -f build >/dev/null; then
2137 BUILDFUNC=1
2139 if declare -f check >/dev/null; then
2140 # "Hide" check() function if not going to be run
2141 if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then
2142 CHECKFUNC=1
2145 if declare -f package >/dev/null; then
2146 PKGFUNC=1
2147 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
2148 SPLITPKG=1
2151 if [[ -n "${PKGLIST[@]}" ]]; then
2152 unset pkgname
2153 pkgname=("${PKGLIST[@]}")
2156 # check if gpg signature is to be created and if signing key is valid
2157 [[ -z $SIGNPKG ]] && SIGNPKG=$(check_buildenv sign)
2158 if [[ $SIGNPKG == 'y' ]]; then
2159 if ! gpg --list-key ${GPGKEY} &>/dev/null; then
2160 if [[ ! -z $GPGKEY ]]; then
2161 error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2162 else
2163 error "$(gettext "There is no key in your keyring.")"
2165 exit 1
2170 if (( ! SPLITPKG )); then
2171 fullver=$(get_full_version)
2172 if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \
2173 || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \
2174 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2175 if (( INSTALL )); then
2176 warning "$(gettext "A package has already been built, installing existing package...")"
2177 install_package
2178 exit $?
2179 else
2180 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2181 exit 1
2184 else
2185 allpkgbuilt=1
2186 somepkgbuilt=0
2187 for pkg in ${pkgname[@]}; do
2188 fullver=$(get_full_version $pkg)
2189 if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \
2190 || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then
2191 somepkgbuilt=1
2192 else
2193 allpkgbuilt=0
2195 done
2196 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2197 if (( allpkgbuilt )); then
2198 if (( INSTALL )); then
2199 warning "$(gettext "The package group has already been built, installing existing packages...")"
2200 install_package
2201 exit $?
2202 else
2203 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2204 exit 1
2207 if (( somepkgbuilt )); then
2208 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2209 exit 1
2212 unset allpkgbuilt somepkgbuilt
2215 # Run the bare minimum in fakeroot
2216 if (( INFAKEROOT )); then
2217 if (( SOURCEONLY )); then
2218 create_srcpackage
2219 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2220 exit 0 # $E_OK
2223 if (( ! SPLITPKG )); then
2224 if (( ! PKGFUNC )); then
2225 if (( ! REPKG )); then
2226 if (( BUILDFUNC )); then
2227 run_build
2228 (( CHECKFUNC )) && run_check
2229 tidy_install
2231 else
2232 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2233 plain "$(gettext "File permissions may not be preserved.")"
2235 else
2236 run_package
2237 tidy_install
2239 create_package
2240 else
2241 run_split_packaging
2244 msg "$(gettext "Leaving %s environment.")" "fakeroot"
2245 exit 0 # $E_OK
2248 fullver=$(get_full_version)
2249 msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2251 # if we are creating a source-only package, go no further
2252 if (( SOURCEONLY )); then
2253 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2254 && (( ! FORCE )); then
2255 error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2256 exit 1
2259 # Get back to our src directory so we can begin with sources.
2260 mkdir -p "$srcdir"
2261 chmod a-s "$srcdir"
2262 cd "$srcdir"
2263 if ( (( ! SKIPCHECKSUMS )) || \
2264 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ) || \
2265 (( SOURCEONLY == 2 )); then
2266 download_sources
2268 check_source_integrity
2269 cd "$startdir"
2271 # if we are root or if fakeroot is not enabled, then we don't use it
2272 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2273 create_srcpackage
2274 else
2275 enter_fakeroot
2278 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2279 exit 0
2282 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
2283 # no warning message needed for nobuild, repkg
2284 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
2285 warning "$(gettext "Skipping dependency checks.")"
2287 elif type -p "${PACMAN%% *}" >/dev/null; then
2288 if (( RMDEPS )); then
2289 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2291 deperr=0
2293 msg "$(gettext "Checking runtime dependencies...")"
2294 resolve_deps ${depends[@]} || deperr=1
2296 msg "$(gettext "Checking buildtime dependencies...")"
2297 resolve_deps ${makedepends[@]} || deperr=1
2299 if (( CHECKFUNC )); then
2300 resolve_deps ${checkdepends[@]} || deperr=1
2303 if (( RMDEPS )); then
2304 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2307 if (( deperr )); then
2308 error "$(gettext "Could not resolve all dependencies.")"
2309 exit 1
2311 else
2312 warning "$(gettext "%s was not found in %s; skipping dependency checks.")" "${PACMAN%% *}" "PATH"
2315 # ensure we have a sane umask set
2316 umask 0022
2318 # get back to our src directory so we can begin with sources
2319 mkdir -p "$srcdir"
2320 chmod a-s "$srcdir"
2321 cd "$srcdir"
2323 if (( NOEXTRACT )); then
2324 warning "$(gettext "Skipping source retrieval -- using existing %s tree")" "src/"
2325 warning "$(gettext "Skipping source integrity checks -- using existing %s tree")" "src/"
2326 warning "$(gettext "Skipping source extraction -- using existing %s tree")" "src/"
2328 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
2329 error "$(gettext "The source directory is empty, there is nothing to build!")"
2330 plain "$(gettext "Aborting...")"
2331 exit 1
2333 elif (( REPKG )); then
2334 if (( ! PKGFUNC && ! SPLITPKG )) \
2335 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
2336 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2337 plain "$(gettext "Aborting...")"
2338 exit 1
2340 else
2341 download_sources
2342 check_source_integrity
2343 extract_sources
2346 if (( NOBUILD )); then
2347 msg "$(gettext "Sources are ready.")"
2348 exit 0 #E_OK
2349 else
2350 # check for existing pkg directory; don't remove if we are repackaging
2351 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2352 msg "$(gettext "Removing existing %s directory...")" "pkg/"
2353 rm -rf "$pkgdir"
2355 mkdir -p "$pkgdir"
2356 chmod a-s "$pkgdir"
2357 cd "$startdir"
2359 # if we are root or if fakeroot is not enabled, then we don't use it
2360 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2361 if (( ! REPKG )); then
2362 devel_update
2363 (( BUILDFUNC )) && run_build
2364 (( CHECKFUNC )) && run_check
2366 if (( ! SPLITPKG )); then
2367 if (( PKGFUNC )); then
2368 run_package
2369 tidy_install
2370 else
2371 if (( ! REPKG )); then
2372 tidy_install
2373 else
2374 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2375 plain "$(gettext "File permissions may not be preserved.")"
2378 create_package
2379 else
2380 run_split_packaging
2382 else
2383 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2384 devel_update
2385 (( BUILDFUNC )) && run_build
2386 (( CHECKFUNC )) && run_check
2387 cd "$startdir"
2390 enter_fakeroot
2394 fullver=$(get_full_version)
2395 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
2397 install_package
2399 exit 0 #E_OK
2401 # vim: set ts=2 sw=2 noet: