makepkg: allow pkgname usage in split package functions
[pacman-ng.git] / scripts / makepkg.sh.in
blob79b307aa8ee95334e4814b2e93a8c11dc662b464
1 #!@BASH_SHELL@ -e
3 # makepkg - make packages compatible for use with pacman
4 # @configure_input@
6 # Copyright (c) 2006-2010 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, grep, gzip, openssl, sed, tput (ncurses), xz
33 # gettext initialization
34 export TEXTDOMAIN='pacman'
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"
44 srcdir="$startdir/src"
45 pkgdir="$startdir/pkg"
47 packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge')
48 other_options=('ccache' 'distcc' 'makeflags')
49 splitpkg_overrides=('pkgver' 'pkgrel' 'pkgdesc' 'arch' 'license' 'groups' \
50 'depends' 'optdepends' 'provides' 'conflicts' 'replaces' \
51 'backup' 'options' 'install' 'changelog')
52 readonly -a packaging_options other_options splitpkg_overrides
54 # Options
55 ASROOT=0
56 CLEANUP=0
57 CLEANCACHE=0
58 DEP_BIN=0
59 FORCE=0
60 INFAKEROOT=0
61 GENINTEG=0
62 SKIPINTEG=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 PKGFUNC=0
75 SPLITPKG=0
76 PKGLIST=()
78 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
79 # when dealing with svn/cvs/etc PKGBUILDs.
80 FORCE_VER=""
82 PACMAN_OPTS=
84 ### SUBROUTINES ###
86 plain() {
87 local mesg=$1; shift
88 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
91 msg() {
92 local mesg=$1; shift
93 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
96 msg2() {
97 local mesg=$1; shift
98 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
101 warning() {
102 local mesg=$1; shift
103 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
106 error() {
107 local mesg=$1; shift
108 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
113 # Special exit call for traps, Don't print any error messages when inside,
114 # the fakeroot call, the error message will be printed by the main call.
116 trap_exit() {
117 if (( ! INFAKEROOT )); then
118 echo
119 error "$@"
121 [[ -n $srclinks ]] && rm -rf "$srclinks"
122 exit 1
127 # Clean up function. Called automatically when the script exits.
129 clean_up() {
130 local EXIT_CODE=$?
132 if (( INFAKEROOT )); then
133 # Don't clean up when leaving fakeroot, we're not done yet.
134 return
137 if (( ! EXIT_CODE && CLEANUP )); then
138 local pkg file
140 # If it's a clean exit and -c/--clean has been passed...
141 msg "$(gettext "Cleaning up...")"
142 rm -rf "$pkgdir" "$srcdir"
143 if [[ -n $pkgbase ]]; then
144 # Can't do this unless the BUILDSCRIPT has been sourced.
145 if (( BUILDFUNC )); then
146 rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-build.log"*
148 if (( PKGFUNC )); then
149 rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package.log"*
150 elif (( SPLITPKG )); then
151 for pkg in ${pkgname[@]}; do
152 rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package_${pkg}.log"*
153 done
156 # clean up dangling symlinks to packages
157 for pkg in ${pkgname[@]}; do
158 for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do
159 if [[ -h $file && ! -e $file ]]; then
160 rm -f $file
162 done
163 done
167 remove_deps
172 # Signal Traps
174 set -E
175 trap 'clean_up' 0
176 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
177 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
178 trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
180 # a source entry can have two forms :
181 # 1) "filename::http://path/to/file"
182 # 2) "http://path/to/file"
184 # Return the absolute filename of a source entry
186 # This function accepts a source entry or the already extracted filename of a
187 # source entry as input
188 get_filepath() {
189 local file="$(get_filename "$1")"
191 if [[ -f "$startdir/$file" ]]; then
192 file="$startdir/$file"
193 elif [[ -f "$SRCDEST/$file" ]]; then
194 file="$SRCDEST/$file"
195 else
196 return 1
199 echo "$file"
202 # Print 'source not found' error message and exit makepkg
203 missing_source_file() {
204 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
205 plain "$(gettext "Aborting...")"
206 exit 1 # $E_MISSING_FILE
209 # extract the filename from a source entry
210 get_filename() {
211 # if a filename is specified, use it
212 local filename="${1%%::*}"
213 # if it is just an URL, we only keep the last component
214 echo "${filename##*/}"
217 # extract the URL from a source entry
218 get_url() {
219 # strip an eventual filename
220 echo "${1#*::}"
224 # Checks to see if options are present in makepkg.conf or PKGBUILD;
225 # PKGBUILD options always take precedence.
227 # usage : check_option( $option )
228 # return : y - enabled
229 # n - disabled
230 # ? - not found
232 check_option() {
233 local ret=$(in_opt_array "$1" ${options[@]})
234 if [[ $ret != '?' ]]; then
235 echo $ret
236 return
239 # fall back to makepkg.conf options
240 ret=$(in_opt_array "$1" ${OPTIONS[@]})
241 if [[ $ret != '?' ]]; then
242 echo $ret
243 return
246 echo '?' # Not Found
251 # Check if option is present in BUILDENV
253 # usage : check_buildenv( $option )
254 # return : y - enabled
255 # n - disabled
256 # ? - not found
258 check_buildenv() {
259 echo $(in_opt_array "$1" ${BUILDENV[@]})
264 # usage : in_opt_array( $needle, $haystack )
265 # return : y - enabled
266 # n - disabled
267 # ? - not found
269 in_opt_array() {
270 local needle=$(tr '[:upper:]' '[:lower:]' <<< $1); shift
272 local opt
273 for opt in "$@"; do
274 opt=$(tr '[:upper:]' '[:lower:]' <<< $opt)
275 if [[ $opt = $needle ]]; then
276 echo 'y' # Enabled
277 return
278 elif [[ $opt = "!$needle" ]]; then
279 echo 'n' # Disabled
280 return
282 done
284 echo '?' # Not Found
289 # usage : in_array( $needle, $haystack )
290 # return : 0 - found
291 # 1 - not found
293 in_array() {
294 local needle=$1; shift
295 [[ -z $1 ]] && return 1 # Not Found
296 local item
297 for item in "$@"; do
298 [[ $item = $needle ]] && return 0 # Found
299 done
300 return 1 # Not Found
303 get_downloadclient() {
304 # $1 = URL with valid protocol prefix
305 local url=$1
306 local proto="${url%%://*}"
308 # loop through DOWNLOAD_AGENTS variable looking for protocol
309 local i
310 for i in "${DLAGENTS[@]}"; do
311 local handler="${i%%::*}"
312 if [[ $proto = $handler ]]; then
313 local agent="${i##*::}"
314 break
316 done
318 # if we didn't find an agent, return an error
319 if [[ -z $agent ]]; then
320 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
321 plain "$(gettext "Aborting...")"
322 exit 1 # $E_CONFIG_ERROR
325 # ensure specified program is installed
326 local program="${agent%% *}"
327 if [[ ! -x $program ]]; then
328 local baseprog="${program##*/}"
329 error "$(gettext "The download program %s is not installed.")" "$baseprog"
330 plain "$(gettext "Aborting...")"
331 exit 1 # $E_MISSING_PROGRAM
334 echo "$agent"
337 download_file() {
338 # download command
339 local dlcmd=$1
340 # URL of the file
341 local url=$2
342 # destination file
343 local file=$3
344 # temporary download file, default to last component of the URL
345 local dlfile="${url##*/}"
347 # replace %o by the temporary dlfile if it exists
348 if [[ $dlcmd = *%o* ]]; then
349 dlcmd=${dlcmd//\%o/\"$file.part\"}
350 dlfile="$file.part"
352 # add the URL, either in place of %u or at the end
353 if [[ $dlcmd = *%u* ]]; then
354 dlcmd=${dlcmd//\%u/\"$url\"}
355 else
356 dlcmd="$dlcmd \"$url\""
359 local ret=0
360 eval "$dlcmd || ret=\$?"
361 if (( ret )); then
362 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
363 return $ret
366 # rename the temporary download file to the final destination
367 if [[ $dlfile != $file ]]; then
368 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
372 run_pacman() {
373 local cmd
374 printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
375 if (( ! ASROOT )) && [[ ! $1 =~ ^-(T|Qq)$ ]]; then
376 if [ "$(type -p sudo)" ]; then
377 cmd="sudo $cmd"
378 else
379 cmd="su -c '$cmd'"
382 eval "$cmd"
385 check_deps() {
386 (( $# > 0 )) || return 0
388 # Disable error trap in pacman subshell call as this breaks bash-3.2 compatibility
389 # Also, a non-zero return value is not unexpected and we are manually dealing them
390 set +E
391 local ret=0
392 local pmout
393 pmout=$(run_pacman -T "$@") || ret=$?
394 set -E
396 if (( ret == 127 )); then #unresolved deps
397 echo "$pmout"
398 elif (( ret )); then
399 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
400 return "$ret"
404 handle_deps() {
405 local R_DEPS_SATISFIED=0
406 local R_DEPS_MISSING=1
408 (( $# == 0 )) && return $R_DEPS_SATISFIED
410 local deplist="$*"
412 if (( ! DEP_BIN )); then
413 return $R_DEPS_MISSING
416 if (( DEP_BIN )); then
417 # install missing deps from binary packages (using pacman -S)
418 msg "$(gettext "Installing missing dependencies...")"
420 if ! run_pacman -S --asdeps $deplist; then
421 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
422 exit 1 # TODO: error code
426 # we might need the new system environment
427 # avoid triggering the ERR trap
428 local restoretrap=$(trap -p ERR)
429 trap - ERR
430 source /etc/profile &>/dev/null
431 eval $restoretrap
433 return $R_DEPS_SATISFIED
436 resolve_deps() {
437 local R_DEPS_SATISFIED=0
438 local R_DEPS_MISSING=1
440 # deplist cannot be declared like this: local deplist=$(foo)
441 # Otherwise, the return value will depend on the assignment.
442 local deplist
443 deplist="$(set +E; check_deps $*)" || exit 1
444 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
446 if handle_deps $deplist; then
447 # check deps again to make sure they were resolved
448 deplist="$(set +E; check_deps $*)" || exit 1
449 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
452 msg "$(gettext "Missing Dependencies:")"
453 local dep
454 for dep in $deplist; do
455 msg2 "$dep"
456 done
458 return $R_DEPS_MISSING
461 remove_deps() {
462 (( ! RMDEPS )) && return
464 # check for packages removed during dependency install (e.g. due to conflicts)
465 # removing all installed packages is risky in this case
466 if [[ -n $(comm -23 <(printf "%s\n" "${original_pkglist[@]}") \
467 <(printf "%s\n" "${current_pkglist[@]}")) ]]; then
468 warning "$(gettext "Failed to remove installed dependencies.")"
469 return 0
472 local deplist=($(comm -13 <(printf "%s\n" "${original_pkglist[@]}") \
473 <(printf "%s\n" "${current_pkglist[@]}")))
474 (( ${#deplist[@]} == 0 )) && return
476 msg "Removing installed dependencies..."
477 # exit cleanly on failure to remove deps as package has been built successfully
478 if ! run_pacman -Rn ${deplist[@]}; then
479 warning "$(gettext "Failed to remove installed dependencies.")"
480 return 0
484 download_sources() {
485 msg "$(gettext "Retrieving Sources...")"
487 pushd "$SRCDEST" &>/dev/null
489 local netfile
490 for netfile in "${source[@]}"; do
491 local file
492 if file=$(get_filepath "$netfile"); then
493 msg2 "$(gettext "Found %s")" "${file##*/}"
494 ln -sf "$file" "$srcdir/"
495 continue
498 file=$(get_filename "$netfile")
499 local url=$(get_url "$netfile")
501 # if we get here, check to make sure it was a URL, else fail
502 if [[ $file = $url ]]; then
503 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
504 exit 1 # $E_MISSING_FILE
507 # find the client we should use for this URL
508 local dlclient=$(get_downloadclient "$url") || exit $?
510 msg2 "$(gettext "Downloading %s...")" "$file"
511 # fix flyspray bug #3289
512 local ret=0
513 download_file "$dlclient" "$url" "$file" || ret=$?
514 if (( ret )); then
515 error "$(gettext "Failure while downloading %s")" "$file"
516 plain "$(gettext "Aborting...")"
517 exit 1
519 rm -f "$srcdir/$file"
520 ln -s "$SRCDEST/$file" "$srcdir/"
521 done
523 popd &>/dev/null
526 get_integlist() {
527 local integ
528 local integlist=()
530 for integ in md5 sha1 sha256 sha384 sha512; do
531 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
532 if [[ -n "$integrity_sums" ]]; then
533 integlist=(${integlist[@]} $integ)
535 done
537 if (( ${#integlist[@]} > 0 )); then
538 echo ${integlist[@]}
539 else
540 echo ${INTEGRITY_CHECK[@]}
544 generate_checksums() {
545 msg "$(gettext "Generating checksums for source files...")"
546 plain ""
548 if ! type -p openssl >/dev/null; then
549 error "$(gettext "Cannot find openssl.")"
550 exit 1 # $E_MISSING_PROGRAM
553 local integlist
554 if (( $# == 0 )); then
555 integlist=$(get_integlist)
556 else
557 integlist=$@
560 local integ
561 for integ in ${integlist[@]}; do
562 integ=$(tr '[:upper:]' '[:lower:]' <<< "$integ")
563 case "$integ" in
564 md5|sha1|sha256|sha384|sha512) : ;;
566 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
567 exit 1;; # $E_CONFIG_ERROR
568 esac
570 local ct=0
571 local numsrc=${#source[@]}
572 echo -n "${integ}sums=("
574 local i
575 local indent=''
576 for (( i = 0; i < ${#integ} + 6; i++ )); do
577 indent="$indent "
578 done
580 local netfile
581 for netfile in "${source[@]}"; do
582 local file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
583 local sum="$(openssl dgst -${integ} "$file")"
584 sum=${sum##* }
585 (( ct )) && echo -n "$indent"
586 echo -n "'$sum'"
587 ct=$(($ct+1))
588 (( $ct < $numsrc )) && echo
589 done
591 echo ")"
592 done
595 check_checksums() {
596 (( ! ${#source[@]} )) && return 0
598 if ! type -p openssl >/dev/null; then
599 error "$(gettext "Cannot find openssl.")"
600 exit 1 # $E_MISSING_PROGRAM
603 local correlation=0
604 local integ required
605 for integ in md5 sha1 sha256 sha384 sha512; do
606 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
607 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
608 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
609 correlation=1
610 local errors=0
611 local idx=0
612 local file
613 for file in "${source[@]}"; do
614 local found=1
615 file="$(get_filename "$file")"
616 echo -n " $file ... " >&2
618 if ! file="$(get_filepath "$file")"; then
619 echo "$(gettext "NOT FOUND")" >&2
620 errors=1
621 found=0
624 if (( $found )) ; then
625 local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
626 local realsum="$(openssl dgst -${integ} "$file")"
627 realsum="${realsum##* }"
628 if [[ $expectedsum = $realsum ]]; then
629 echo "$(gettext "Passed")" >&2
630 else
631 echo "$(gettext "FAILED")" >&2
632 errors=1
636 idx=$((idx + 1))
637 done
639 if (( errors )); then
640 error "$(gettext "One or more files did not pass the validity check!")"
641 exit 1 # TODO: error code
643 elif (( ${#integrity_sums[@]} )); then
644 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
645 exit 1 # TODO: error code
647 done
649 if (( ! correlation )); then
650 error "$(gettext "Integrity checks are missing.")"
651 exit 1 # TODO: error code
655 extract_sources() {
656 msg "$(gettext "Extracting Sources...")"
657 local netfile
658 for netfile in "${source[@]}"; do
659 local file=$(get_filename "$netfile")
660 if in_array "$file" ${noextract[@]}; then
661 #skip source files in the noextract=() array
662 # these are marked explicitly to NOT be extracted
663 continue
667 # fix flyspray #6246
668 local file_type=$(file -bizL "$file")
669 local ext=${file##*.}
670 local cmd=''
671 case "$file_type" in
672 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
673 cmd="bsdtar" ;;
674 *application/x-gzip*)
675 case "$ext" in
676 gz|z|Z) cmd="gzip" ;;
677 *) continue;;
678 esac ;;
679 *application/x-bzip*)
680 case "$ext" in
681 bz2|bz) cmd="bzip2" ;;
682 *) continue;;
683 esac ;;
684 *application/x-xz*)
685 case "$ext" in
686 xz) cmd="xz" ;;
687 *) continue;;
688 esac ;;
690 # See if bsdtar can recognize the file
691 if bsdtar -tf "$file" -q '*' &>/dev/null; then
692 cmd="bsdtar"
693 else
694 continue
695 fi ;;
696 esac
698 local ret=0
699 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
700 if [[ $cmd = bsdtar ]]; then
701 $cmd -xf "$file" || ret=$?
702 else
703 rm -f "${file%.*}"
704 $cmd -dcf "$file" > "${file%.*}" || ret=$?
706 if (( ret )); then
707 error "$(gettext "Failed to extract %s")" "$file"
708 plain "$(gettext "Aborting...")"
709 exit 1
711 done
713 if (( EUID == 0 )); then
714 # change perms of all source files to root user & root group
715 chown -R 0:0 "$srcdir"
719 error_function() {
720 if [[ -p $logpipe ]]; then
721 rm "$logpipe"
723 # first exit all subshells, then print the error
724 if (( ! BASH_SUBSHELL )); then
725 error "$(gettext "A failure occurred in %s().")" "$1"
726 plain "$(gettext "Aborting...")"
727 remove_deps
729 exit 2 # $E_BUILD_FAILED
732 run_function() {
733 if [[ -z $1 ]]; then
734 return 1
736 local pkgfunc="$1"
738 # clear user-specified makeflags if requested
739 if [[ $(check_option makeflags) = "n" ]]; then
740 MAKEFLAGS=""
743 msg "$(gettext "Starting %s()...")" "$pkgfunc"
744 cd "$srcdir"
746 # ensure all necessary build variables are exported
747 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
748 # save our shell options so pkgfunc() can't override what we need
749 local shellopts=$(shopt -p)
751 local ret=0
752 local restoretrap
753 if (( LOGGING )); then
754 local BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log"
755 if [[ -f $BUILDLOG ]]; then
756 local i=1
757 while true; do
758 if [[ -f $BUILDLOG.$i ]]; then
759 i=$(($i +1))
760 else
761 break
763 done
764 mv "$BUILDLOG" "$BUILDLOG.$i"
767 # ensure overridden package variables survive tee with split packages
768 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
769 mkfifo "$logpipe"
770 exec 3>&1
771 tee "$BUILDLOG" < "$logpipe" &
772 exec 1>"$logpipe" 2>"$logpipe"
773 restoretrap=$(trap -p ERR)
774 trap 'error_function $pkgfunc' ERR
775 $pkgfunc 2>&1
776 eval $restoretrap
777 sync
778 exec 1>&3 2>&3 3>&-
779 rm "$logpipe"
780 else
781 restoretrap=$(trap -p ERR)
782 trap 'error_function $pkgfunc' ERR
783 $pkgfunc 2>&1
784 eval $restoretrap
786 # reset our shell options
787 eval "$shellopts"
790 run_build() {
791 # use distcc if it is requested (check buildenv and PKGBUILD opts)
792 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
793 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
794 export DISTCC_HOSTS
795 elif [[ $(check_option distcc) = "n" ]]; then
796 # if it is not wanted, clear the makeflags too
797 MAKEFLAGS=""
800 # use ccache if it is requested (check buildenv and PKGBUILD opts)
801 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
802 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
805 run_function "build"
808 run_package() {
809 local pkgfunc
810 if [[ -z $1 ]]; then
811 pkgfunc="package"
812 else
813 pkgfunc="package_$1"
816 run_function "$pkgfunc"
819 tidy_install() {
820 cd "$pkgdir"
821 msg "$(gettext "Tidying install...")"
823 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
824 msg2 "$(gettext "Removing doc files...")"
825 rm -rf ${DOC_DIRS[@]}
828 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
829 msg2 "$(gettext "Purging other files...")"
830 local pt
831 for pt in "${PURGE_TARGETS[@]}"; do
832 if [[ ${pt} = ${pt//\/} ]]; then
833 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
834 else
835 rm -f ${pt}
837 done
840 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
841 msg2 "$(gettext "Compressing man and info pages...")"
842 local manpage ext file link hardlinks hl
843 find ${MAN_DIRS[@]} -type f 2>/dev/null |
844 while read manpage ; do
845 ext="${manpage##*.}"
846 file="${manpage##*/}"
847 if [[ $ext != gz && $ext != bz2 ]]; then
848 # update symlinks to this manpage
849 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
850 while read link ; do
851 rm -f "$link"
852 ln -sf "${file}.gz" "${link}.gz"
853 done
855 # check file still exists (potentially already compressed due to hardlink)
856 if [[ -f ${manpage} ]]; then
857 # find hard links and remove them
858 # the '|| true' part keeps the script from bailing if find returned an
859 # error, such as when one of the man directories doesn't exist
860 hardlinks="$(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
861 for hl in ${hardlinks}; do
862 rm -f "${hl}";
863 done
864 # compress the original
865 gzip -9 "$manpage"
866 # recreate hard links removed earlier
867 for hl in ${hardlinks}; do
868 ln "${manpage}.gz" "${hl}.gz"
869 chmod 644 ${hl}.gz
870 done
873 done
876 if [[ $(check_option strip) = y ]]; then
877 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
878 # make sure library stripping variables are defined to prevent excess stripping
879 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
880 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
881 local binary
882 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
883 case "$(file -bi "$binary")" in
884 *application/x-sharedlib*) # Libraries (.so)
885 /usr/bin/strip $STRIP_SHARED "$binary";;
886 *application/x-archive*) # Libraries (.a)
887 /usr/bin/strip $STRIP_STATIC "$binary";;
888 *application/x-executable*) # Binaries
889 /usr/bin/strip $STRIP_BINARIES "$binary";;
890 esac
891 done
894 if [[ $(check_option libtool) = "n" ]]; then
895 msg2 "$(gettext "Removing libtool .la files...")"
896 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
899 if [[ $(check_option emptydirs) = "n" ]]; then
900 msg2 "$(gettext "Removing empty directories...")"
901 find . -depth -type d -empty -delete
905 write_pkginfo() {
906 local builddate=$(date -u "+%s")
907 if [[ -n $PACKAGER ]]; then
908 local packager="$PACKAGER"
909 else
910 local packager="Unknown Packager"
912 local size="$(@DUPATH@ -sk)"
913 size="$(( ${size%%[^0-9]*} * 1024 ))"
915 msg2 "$(gettext "Generating .PKGINFO file...")"
916 echo "# Generated by makepkg $myver"
917 if (( INFAKEROOT )); then
918 echo "# using $(fakeroot -v)"
920 echo "# $(LC_ALL=C date -u)"
921 echo "pkgname = $1"
922 (( SPLITPKG )) && echo pkgbase = $pkgbase
923 echo "pkgver = $pkgver-$pkgrel"
924 echo "pkgdesc = $pkgdesc"
925 [[ $epoch ]] && echo "epoch = $epoch"
926 echo "url = $url"
927 echo "builddate = $builddate"
928 echo "packager = $packager"
929 echo "size = $size"
930 echo "arch = $PKGARCH"
932 [[ $license ]] && printf "license = %s\n" "${license[@]}"
933 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
934 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
935 [[ $depends ]] && printf "depend = %s\n" "${depends[@]}"
936 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}"
937 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
938 [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
939 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
941 local it
942 for it in "${packaging_options[@]}"; do
943 local ret="$(check_option $it)"
944 if [[ $ret != "?" ]]; then
945 if [[ $ret = y ]]; then
946 echo "makepkgopt = $it"
947 else
948 echo "makepkgopt = !$it"
951 done
953 # TODO maybe remove this at some point
954 # warn if license array is not present or empty
955 if [[ -z $license ]]; then
956 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
957 plain "$(gettext "Example for GPL\'ed software: license=('GPL').")"
961 check_package() {
962 cd "$pkgdir"
964 # check existence of backup files
965 local file
966 for file in "${backup[@]}"; do
967 if [[ ! -f $file ]]; then
968 warning "$(gettext "Backup entry file not in package : %s")" "$file"
970 done
972 # check for references to the build and package directory
973 if find "${pkgdir}" -type f -exec grep -q -I "${srcdir}" {} +; then
974 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
976 if find "${pkgdir}" -type f -exec grep -q -I "${pkgdir}" {} +; then
977 warning "$(gettext "Package contains reference to %s")" "\$pkgdir"
982 create_package() {
983 if [[ ! -d $pkgdir ]]; then
984 error "$(gettext "Missing pkg/ directory.")"
985 plain "$(gettext "Aborting...")"
986 exit 1 # $E_MISSING_PKGDIR
989 check_package
991 cd "$pkgdir"
992 msg "$(gettext "Creating package...")"
994 local nameofpkg
995 if [[ -z $1 ]]; then
996 nameofpkg="$pkgname"
997 else
998 nameofpkg="$1"
1001 if [[ $arch = "any" ]]; then
1002 PKGARCH="any"
1003 else
1004 PKGARCH=$CARCH
1007 write_pkginfo $nameofpkg > .PKGINFO
1009 local comp_files=".PKGINFO"
1011 # check for changelog/install files
1012 for i in 'changelog' 'install'; do
1013 orig=${!i}
1014 dest=$(tr '[:lower:]' '[:upper:]' <<<".$i")
1016 if [[ -n $orig ]]; then
1017 msg2 "$(gettext "Adding %s file...")" "$i"
1018 cp "$startdir/$orig" "$dest"
1019 chmod 644 "$dest"
1020 comp_files+=" $dest"
1022 done
1024 # tar it up
1025 msg2 "$(gettext "Compressing package...")"
1027 local EXT
1028 case "$PKGEXT" in
1029 *tar.gz) EXT=${PKGEXT%.gz} ;;
1030 *tar.bz2) EXT=${PKGEXT%.bz2} ;;
1031 *tar.xz) EXT=${PKGEXT%.xz} ;;
1032 *tar) EXT=${PKGEXT} ;;
1033 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1034 "$PKGEXT" ; EXT=$PKGEXT ;;
1035 esac
1037 local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}"
1038 local ret=0
1040 # when fileglobbing, we want * in an empty directory to expand to
1041 # the null string rather than itself
1042 shopt -s nullglob
1043 # TODO: Maybe this can be set globally for robustness
1044 shopt -s -o pipefail
1045 bsdtar -cf - $comp_files * |
1046 case "$PKGEXT" in
1047 *tar.gz) gzip -c -f -n ;;
1048 *tar.bz2) bzip2 -c -f ;;
1049 *tar.xz) xz -c -z - ;;
1050 *tar) cat ;;
1051 esac > ${pkg_file} || ret=$?
1053 shopt -u nullglob
1054 shopt -u -o pipefail
1056 if (( ret )); then
1057 error "$(gettext "Failed to create package file.")"
1058 exit 1 # TODO: error code
1061 if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1062 ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1063 ret=$?
1066 if (( ret )); then
1067 warning "$(gettext "Failed to create symlink to package file.")"
1071 create_srcpackage() {
1072 cd "$startdir"
1074 # Get back to our src directory so we can begin with sources.
1075 mkdir -p "$srcdir"
1076 chmod a-s "$srcdir"
1077 cd "$srcdir"
1078 if (( ! SKIPINTEG || SOURCEONLY == 2 )); then
1079 download_sources
1081 if (( ! SKIPINTEG )); then
1082 # We can only check checksums if we have all files.
1083 check_checksums
1084 else
1085 warning "$(gettext "Skipping integrity checks.")"
1087 cd "$startdir"
1089 msg "$(gettext "Creating source package...")"
1090 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1091 mkdir "${srclinks}"/${pkgbase}
1093 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1094 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1096 local file
1097 for file in "${source[@]}"; do
1098 if [[ -f $file ]]; then
1099 msg2 "$(gettext "Adding %s...")" "$file"
1100 ln -s "${startdir}/$file" "$srclinks/$pkgbase"
1101 elif (( SOURCEONLY == 2 )); then
1102 local absfile=$(get_filepath "$file") || missing_source_file "$file"
1103 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1104 ln -s "$absfile" "$srclinks/$pkgbase"
1106 done
1108 local i
1109 for i in 'changelog' 'install'; do
1110 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDSCRIPT")
1111 local file
1112 for file in $filelist; do
1113 # evaluate any bash variables used
1114 eval file=${file}
1115 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1116 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1117 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1119 done
1120 done
1122 local TAR_OPT
1123 case "$SRCEXT" in
1124 *tar.gz) TAR_OPT="z" ;;
1125 *tar.bz2) TAR_OPT="j" ;;
1126 *tar.xz) TAR_OPT="J" ;;
1127 *tar) TAR_OPT="" ;;
1128 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1129 "$SRCEXT" ;;
1130 esac
1132 local pkg_file="$SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT}"
1134 # tar it up
1135 msg2 "$(gettext "Compressing source package...")"
1136 cd "${srclinks}"
1137 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1138 error "$(gettext "Failed to create source package file.")"
1139 exit 1 # TODO: error code
1142 if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
1143 ln -sf "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
1144 ret=$?
1147 if (( ret )); then
1148 warning "$(gettext "Failed to create symlink to source package file.")"
1151 cd "${startdir}"
1152 rm -rf "${srclinks}"
1155 install_package() {
1156 (( ! INSTALL )) && return
1158 if (( ! SPLITPKG )); then
1159 msg "$(gettext "Installing package %s with %s -U...")" "$pkgname" "$PACMAN"
1160 else
1161 msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN"
1164 local pkg pkglist
1165 for pkg in ${pkgname[@]}; do
1166 if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then
1167 pkglist+=" $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"
1168 else
1169 pkglist+=" $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}"
1171 done
1173 if ! run_pacman -U $pkglist; then
1174 warning "$(gettext "Failed to install built package(s).")"
1175 return 0
1179 check_sanity() {
1180 # check for no-no's in the build script
1181 local i
1182 for i in 'pkgname' 'pkgrel' 'pkgver'; do
1183 if [[ -z ${!i} ]]; then
1184 error "$(gettext "%s is not allowed to be empty.")" "$i"
1185 return 1
1187 done
1189 for i in "${pkgname[@]}"; do
1190 if [[ ${i:0:1} = "-" ]]; then
1191 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1192 return 1
1194 done
1196 if [[ ${pkgbase:0:1} = "-" ]]; then
1197 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1198 return 1
1200 if [[ $pkgver != ${pkgver//-/} ]]; then
1201 error "$(gettext "%s is not allowed to contain hyphens.")" "pkgver"
1202 return 1
1204 if [[ $pkgrel != ${pkgrel//-/} ]]; then
1205 error "$(gettext "%s is not allowed to contain hyphens.")" "pkgrel"
1206 return 1
1209 if [[ ! $epoch =~ ^[0-9]*$ ]]; then
1210 error "$(gettext "%s must be an integer.")" "epoch"
1211 return 1
1214 if [[ $arch != 'any' ]]; then
1215 if ! in_array $CARCH ${arch[@]}; then
1216 if (( ! IGNOREARCH )); then
1217 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1218 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1219 plain "$(gettext "such as arch=('%s').")" "$CARCH"
1220 return 1
1225 local provides_list
1226 eval $(awk '/^[[:space:]]*provides=/,/)/' "$BUILDFILE" | sed "s/provides=/provides_list+=/")
1227 for i in ${provides_list[@]}; do
1228 if [[ $i != ${i//</} || $i != ${i//>/} ]]; then
1229 error "$(gettext "Provides array cannot contain comparison (< or >) operators.")"
1230 return 1
1232 done
1234 local backup_list
1235 eval $(awk '/^[[:space:]]*backup=/,/)/' "$BUILDFILE" | sed "s/backup=/backup_list+=/")
1236 for i in "${backup_list[@]}"; do
1237 if [[ ${i:0:1} = "/" ]]; then
1238 error "$(gettext "Backup entry should not contain leading slash : %s")" "$i"
1239 return 1
1241 done
1243 local optdepends_list
1244 eval $(awk '/^[[:space:]]*optdepends=/,/)/' "$BUILDFILE" | sed "s/optdepends=/optdepends_list+=/")
1245 for i in "${optdepends_list[@]}"; do
1246 local pkg=${i%%:*}
1247 if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]+$ ]]; then
1248 error "$(gettext "Invalid syntax for optdepend : '%s'")" "$i"
1250 done
1252 for i in 'changelog' 'install'; do
1253 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1254 local file
1255 for file in $filelist; do
1256 # evaluate any bash variables used
1257 eval file=${file}
1258 if [[ ! -f $file ]]; then
1259 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
1260 return 1
1262 done
1263 done
1265 local valid_options=1
1266 local known kopt options_list
1267 eval $(awk '/^[[:space:]]*options=/,/)/' "$BUILDFILE" | sed "s/options=/options_list+=/")
1268 for i in ${options_list[@]}; do
1269 known=0
1270 # check if option matches a known option or its inverse
1271 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1272 if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then
1273 known=1
1275 done
1276 if (( ! known )); then
1277 error "$(gettext "options array contains unknown option '%s'")" "$i"
1278 valid_options=0
1280 done
1281 if (( ! valid_options )); then
1282 return 1
1285 if (( ${#pkgname[@]} > 1 )); then
1286 for i in ${pkgname[@]}; do
1287 if ! declare -f package_${i} >/dev/null; then
1288 error "$(gettext "missing package function for split package '%s'")" "$i"
1289 return 1
1291 done
1294 for i in ${PKGLIST[@]}; do
1295 if ! in_array $i ${pkgname[@]}; then
1296 error "$(gettext "requested package %s is not provided in %s")" "$i" "$BUILDFILE"
1297 return 1
1299 done
1301 return 0
1304 devel_check() {
1305 newpkgver=""
1307 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1308 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1309 if (( HOLDVER || SOURCEONLY || REPKG )) \
1310 || [[ ! -f $BUILDFILE || ! -w $BUILDFILE ]]; then
1311 return
1314 if [[ -z $FORCE_VER ]]; then
1315 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1316 # This will only be used on the first call to makepkg; subsequent
1317 # calls to makepkg via fakeroot will explicitly pass the version
1318 # number to avoid having to determine the version number twice.
1319 # Also do a brief check to make sure we have the VCS tool available.
1320 oldpkgver=$pkgver
1321 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1322 type -p darcs >/dev/null || return 0
1323 msg "$(gettext "Determining latest darcs revision...")"
1324 newpkgver=$(date +%Y%m%d)
1325 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1326 type -p cvs >/dev/null || return 0
1327 msg "$(gettext "Determining latest cvs revision...")"
1328 newpkgver=$(date +%Y%m%d)
1329 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1330 type -p git >/dev/null || return 0
1331 msg "$(gettext "Determining latest git revision...")"
1332 newpkgver=$(date +%Y%m%d)
1333 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1334 type -p svn >/dev/null || return 0
1335 msg "$(gettext "Determining latest svn revision...")"
1336 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1337 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1338 type -p bzr >/dev/null || return 0
1339 msg "$(gettext "Determining latest bzr revision...")"
1340 newpkgver=$(bzr revno ${_bzrtrunk})
1341 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1342 type -p hg >/dev/null || return 0
1343 msg "$(gettext "Determining latest hg revision...")"
1344 if [[ -d ./src/$_hgrepo ]] ; then
1345 cd ./src/$_hgrepo
1346 hg pull
1347 hg update
1348 else
1349 [[ ! -d ./src/ ]] && mkdir ./src/
1350 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1351 cd ./src/$_hgrepo
1353 newpkgver=$(hg tip --template "{rev}")
1354 cd ../../
1357 if [[ -n $newpkgver ]]; then
1358 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1361 else
1362 # Version number retrieved from fakeroot->makepkg argument
1363 newpkgver=$FORCE_VER
1367 devel_update() {
1368 # This is lame, but if we're wanting to use an updated pkgver for
1369 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1370 # the new pkgver and then re-source it. This is the most robust
1371 # method for dealing with PKGBUILDs that use, e.g.:
1373 # pkgver=23
1374 # ...
1375 # _foo=pkgver
1377 if [[ -n $newpkgver ]]; then
1378 if [[ $newpkgver != $pkgver ]]; then
1379 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1380 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1381 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1382 source "$BUILDFILE"
1388 backup_package_variables() {
1389 local var
1390 for var in ${splitpkg_overrides[@]}; do
1391 local indirect="${var}_backup"
1392 eval "${indirect}=(\"\${$var[@]}\")"
1393 done
1396 restore_package_variables() {
1397 local var
1398 for var in ${splitpkg_overrides[@]}; do
1399 local indirect="${var}_backup"
1400 if [[ -n ${!indirect} ]]; then
1401 eval "${var}=(\"\${$indirect[@]}\")"
1402 else
1403 unset ${var}
1405 done
1408 run_split_packaging() {
1409 local pkgname_backup=${pkgname[@]}
1410 for pkgname in ${pkgname_backup[@]}; do
1411 pkgdir="$pkgdir/$pkgname"
1412 mkdir -p "$pkgdir"
1413 chmod a-s "$pkgdir"
1414 backup_package_variables
1415 run_package $pkgname
1416 tidy_install
1417 create_package $pkgname
1418 restore_package_variables
1419 pkgdir="${pkgdir%/*}"
1420 done
1421 pkgname=${pkgname_backup[@]}
1424 # Canonicalize a directory path if it exists
1425 canonicalize_path() {
1426 local path="$1";
1428 if [[ -d $path ]]; then
1430 cd "$path"
1431 pwd -P
1433 else
1434 echo "$path"
1438 # getopt like parser
1439 parse_options() {
1440 local short_options=$1; shift;
1441 local long_options=$1; shift;
1442 local ret=0;
1443 local unused_options=""
1444 local i
1446 while [[ -n $1 ]]; do
1447 if [[ ${1:0:2} = '--' ]]; then
1448 if [[ -n ${1:2} ]]; then
1449 local match=""
1450 for i in ${long_options//,/ }; do
1451 if [[ ${1:2} = ${i//:} ]]; then
1452 match=$i
1453 break
1455 done
1456 if [[ -n $match ]]; then
1457 if [[ ${1:2} = $match ]]; then
1458 printf ' %s' "$1"
1459 else
1460 if [[ -n $2 ]]; then
1461 printf ' %s' "$1"
1462 shift
1463 printf " '%s'" "$1"
1464 else
1465 echo "makepkg: option '$1' $(gettext "requires an argument")" >&2
1466 ret=1
1469 else
1470 echo "makepkg: $(gettext "unrecognized option") '$1'" >&2
1471 ret=1
1473 else
1474 shift
1475 break
1477 elif [[ ${1:0:1} = '-' ]]; then
1478 for ((i=1; i<${#1}; i++)); do
1479 if [[ $short_options =~ ${1:i:1} ]]; then
1480 if [[ $short_options =~ ${1:i:1}: ]]; then
1481 if [[ -n ${1:$i+1} ]]; then
1482 printf ' -%s' "${1:i:1}"
1483 printf " '%s'" "${1:$i+1}"
1484 else
1485 if [[ -n $2 ]]; then
1486 printf ' -%s' "${1:i:1}"
1487 shift
1488 printf " '%s'" "${1}"
1489 else
1490 echo "makepkg: option $(gettext "requires an argument") -- '${1:i:1}'" >&2
1491 ret=1
1494 break
1495 else
1496 printf ' -%s' "${1:i:1}"
1498 else
1499 echo "makepkg: $(gettext "invalid option") -- '${1:i:1}'" >&2
1500 ret=1
1502 done
1503 else
1504 unused_options="${unused_options} '$1'"
1506 shift
1507 done
1509 printf " --"
1510 if [[ -n $unused_options ]]; then
1511 for i in ${unused_options[@]}; do
1512 printf ' %s' "$i"
1513 done
1515 if [[ -n $1 ]]; then
1516 while [[ -n $1 ]]; do
1517 printf " '%s'" "${1}"
1518 shift
1519 done
1521 printf "\n"
1523 return $ret
1526 usage() {
1527 printf "makepkg (pacman) %s\n" "$myver"
1528 echo
1529 printf "$(gettext "Usage: %s [options]")\n" "$0"
1530 echo
1531 echo "$(gettext "Options:")"
1532 printf "$(gettext " -A, --ignorearch Ignore incomplete arch field in %s")\n" "$BUILDSCRIPT"
1533 echo "$(gettext " -c, --clean Clean up work files after build")"
1534 echo "$(gettext " -C, --cleancache Clean up source files from the cache")"
1535 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1536 echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")"
1537 echo "$(gettext " -f, --force Overwrite existing package")"
1538 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1539 echo "$(gettext " -h, --help This help")"
1540 echo "$(gettext " -i, --install Install package after successful build")"
1541 echo "$(gettext " -L, --log Log package build process")"
1542 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1543 echo "$(gettext " -o, --nobuild Download and extract files only")"
1544 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1545 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1546 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1547 echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")"
1548 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1549 echo "$(gettext " --asroot Allow makepkg to run as root user")"
1550 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1551 printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT"
1552 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1553 echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")"
1554 echo "$(gettext " --source Generate a source-only tarball without downloaded sources")"
1555 echo
1556 echo "$(gettext "These options can be passed to pacman:")"
1557 echo
1558 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1559 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1560 echo
1561 printf "$(gettext "If -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT"
1562 echo
1565 version() {
1566 printf "makepkg (pacman) %s\n" "$myver"
1567 printf "$(gettext "\
1568 Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1569 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1570 This is free software; see the source for copying conditions.\n\
1571 There is NO WARRANTY, to the extent permitted by law.\n")"
1574 # PROGRAM START
1576 # determine whether we have gettext; make it a no-op if we do not
1577 if ! type -p gettext >/dev/null; then
1578 gettext() {
1579 echo "$@"
1583 ARGLIST=("$@")
1585 # Parse Command Line Options.
1586 OPT_SHORT="AcCdefFghiLmop:rRsV"
1587 OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps"
1588 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver"
1589 OPT_LONG+=",install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg"
1590 OPT_LONG+=",source,syncdeps,version,config:"
1591 # Pacman Options
1592 OPT_LONG+=",noconfirm,noprogressbar"
1593 OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
1594 if [[ $OPT_TEMP = *'PARSE_OPTIONS FAILED'* ]]; then
1595 # This is a small hack to stop the script bailing with 'set -e'
1596 echo; usage; exit 1 # E_INVALID_OPTION;
1598 eval set -- "$OPT_TEMP"
1599 unset OPT_SHORT OPT_LONG OPT_TEMP
1601 while true; do
1602 case "$1" in
1603 # Pacman Options
1604 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
1605 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
1607 # Makepkg Options
1608 --allsource) SOURCEONLY=2 ;;
1609 --asroot) ASROOT=1 ;;
1610 -A|--ignorearch) IGNOREARCH=1 ;;
1611 -c|--clean) CLEANUP=1 ;;
1612 -C|--cleancache) CLEANCACHE=1 ;;
1613 --config) shift; MAKEPKG_CONF=$1 ;;
1614 -d|--nodeps) NODEPS=1 ;;
1615 -e|--noextract) NOEXTRACT=1 ;;
1616 -f|--force) FORCE=1 ;;
1617 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1618 --forcever) shift; FORCE_VER=$1;;
1619 -F) INFAKEROOT=1 ;;
1620 -g|--geninteg) GENINTEG=1 ;;
1621 --holdver) HOLDVER=1 ;;
1622 -i|--install) INSTALL=1 ;;
1623 -L|--log) LOGGING=1 ;;
1624 -m|--nocolor) USE_COLOR='n' ;;
1625 -o|--nobuild) NOBUILD=1 ;;
1626 -p) shift; BUILDFILE=$1 ;;
1627 --pkg) shift; PKGLIST=($1) ;;
1628 -r|--rmdeps) RMDEPS=1 ;;
1629 -R|--repackage) REPKG=1 ;;
1630 --skipinteg) SKIPINTEG=1 ;;
1631 --source) SOURCEONLY=1 ;;
1632 -s|--syncdeps) DEP_BIN=1 ;;
1634 -h|--help) usage; exit 0 ;; # E_OK
1635 -V|--version) version; exit 0 ;; # E_OK
1637 --) OPT_IND=0; shift; break;;
1638 *) usage; exit 1 ;; # E_INVALID_OPTION
1639 esac
1640 shift
1641 done
1643 # preserve environment variables and canonicalize path
1644 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
1645 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
1646 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
1648 # default config is makepkg.conf
1649 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1651 # Source the config file; fail if it is not found
1652 if [[ -r $MAKEPKG_CONF ]]; then
1653 source "$MAKEPKG_CONF"
1654 else
1655 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1656 plain "$(gettext "Aborting...")"
1657 exit 1 # $E_CONFIG_ERROR
1660 # Source user-specific makepkg.conf overrides
1661 if [[ -r ~/.makepkg.conf ]]; then
1662 source ~/.makepkg.conf
1665 # set pacman command if not already defined
1666 PACMAN=${PACMAN:-pacman}
1668 # check if messages are to be printed using color
1669 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1670 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1671 # prefer terminal safe colored and bold text when tput is supported
1672 if tput setaf 0 &>/dev/null; then
1673 ALL_OFF="$(tput sgr0)"
1674 BOLD="$(tput bold)"
1675 BLUE="${BOLD}$(tput setaf 4)"
1676 GREEN="${BOLD}$(tput setaf 2)"
1677 RED="${BOLD}$(tput setaf 1)"
1678 YELLOW="${BOLD}$(tput setaf 3)"
1679 else
1680 ALL_OFF="\e[1;0m"
1681 BOLD="\e[1;1m"
1682 BLUE="${BOLD}\e[1;34m"
1683 GREEN="${BOLD}\e[1;32m"
1684 RED="${BOLD}\e[1;31m"
1685 YELLOW="${BOLD}\e[1;33m"
1688 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
1690 # override settings with an environment variable for batch processing
1691 PKGDEST=${_PKGDEST:-$PKGDEST}
1692 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
1693 if [[ ! -w $PKGDEST ]]; then
1694 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
1695 plain "$(gettext "Aborting...")"
1696 exit 1
1699 SRCDEST=${_SRCDEST:-$SRCDEST}
1700 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
1701 if [[ ! -w $SRCDEST ]] ; then
1702 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
1703 plain "$(gettext "Aborting...")"
1704 exit 1
1707 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
1708 SRCPKGDEST=${SRCPKGDEST:-$PKGDEST} #default to $PKGDEST if undefined
1711 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
1712 # The '\\0' is here to prevent gettext from thinking --holdver is an option
1713 error "$(gettext "\\0--holdver and --forcever cannot both be specified" )"
1714 exit 1
1717 if (( CLEANCACHE )); then
1718 #fix flyspray feature request #5223
1719 if [[ -n $SRCDEST && ! $SRCDEST -ef "${startdir}" ]]; then
1720 msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST"
1721 echo -n "$(gettext " Are you sure you wish to do this? ")"
1722 echo -n "$(gettext "[y/N]")"
1723 read answer
1724 answer=$(tr '[:lower:]' '[:upper:]' <<< "$answer")
1725 if [[ $answer = $(gettext YES) || $answer = $(gettext Y) ]]; then
1726 rm "$SRCDEST"/*
1727 if (( $? )); then
1728 error "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST"
1729 exit 1
1730 else
1731 # removal worked
1732 msg "$(gettext "Source cache cleaned.")"
1733 exit 0
1735 else
1736 # answer = no
1737 msg "$(gettext "No files have been removed.")"
1738 exit 0
1740 else
1741 # $SRCDEST is $startdir, two possibilities
1742 error "$(gettext "Source destination must be defined in %s.")" "$MAKEPKG_CONF"
1743 plain "$(gettext "In addition, please run makepkg -C outside of your cache directory.")"
1744 exit 1
1748 if (( ! INFAKEROOT )); then
1749 if (( EUID == 0 && ! ASROOT )); then
1750 # Warn those who like to live dangerously.
1751 error "$(gettext "Running makepkg as root is a BAD idea and can cause")"
1752 plain "$(gettext "permanent, catastrophic damage to your system. If you")"
1753 plain "$(gettext "wish to run as root, please use the --asroot option.")"
1754 exit 1 # $E_USER_ABORT
1755 elif (( EUID > 0 && ASROOT )); then
1756 # Warn those who try to use the --asroot option when they are not root
1757 error "$(gettext "The --asroot option is meant for the root user only.")"
1758 plain "$(gettext "Please rerun makepkg without the --asroot flag.")"
1759 exit 1 # $E_USER_ABORT
1760 elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1761 if ! type -p fakeroot >/dev/null; then
1762 error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")"
1763 plain "$(gettext "in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
1764 exit 1
1766 elif (( EUID > 0 )); then
1767 warning "$(gettext "Running makepkg as an unprivileged user will result in non-root")"
1768 plain "$(gettext "ownership of the packaged files. Try using the fakeroot environment by")"
1769 plain "$(gettext "placing 'fakeroot' in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
1770 sleep 1
1772 else
1773 if [[ -z $FAKEROOTKEY ]]; then
1774 error "$(gettext "Do not use the '-F' option. This option is only for use by makepkg.")"
1775 exit 1 # TODO: error code
1779 # check for sudo if we will need it during makepkg execution
1780 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1781 if ! type -p sudo >/dev/null; then
1782 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1786 unset pkgname pkgbase pkgver pkgrel pkgdesc url license groups provides
1787 unset md5sums replaces depends conflicts backup source install changelog build
1788 unset makedepends optdepends options noextract
1790 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
1791 if [[ ! -f $BUILDFILE ]]; then
1792 if [[ -t 0 ]]; then
1793 error "$(gettext "%s does not exist.")" "$BUILDFILE"
1794 exit 1
1795 else
1796 # PKGBUILD passed through a pipe
1797 BUILDFILE=/dev/stdin
1798 source "$BUILDFILE"
1800 else
1801 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
1802 if [[ -n $crlftest ]]; then
1803 error "$(gettext "%s contains CRLF characters and cannot be sourced.")" "$BUILDFILE"
1804 exit 1
1807 if [[ ${BUILDFILE:0:1} != "/" ]]; then
1808 BUILDFILE="$startdir/$BUILDFILE"
1810 source "$BUILDFILE"
1813 if (( GENINTEG )); then
1814 mkdir -p "$srcdir"
1815 chmod a-s "$srcdir"
1816 cd "$srcdir"
1817 download_sources
1818 generate_checksums
1819 exit 0 # $E_OK
1822 # check the PKGBUILD for some basic requirements
1823 check_sanity || exit 1
1825 # We need to run devel_update regardless of whether we are in the fakeroot
1826 # build process so that if the user runs makepkg --forcever manually, we
1827 # 1) output the correct pkgver, and 2) use the correct filename when
1828 # checking if the package file already exists - fixes FS #9194
1829 devel_check
1830 devel_update
1832 if (( ${#pkgname[@]} > 1 )); then
1833 SPLITPKG=1
1836 # test for available PKGBUILD functions
1837 if declare -f build >/dev/null; then
1838 BUILDFUNC=1
1840 if declare -f package >/dev/null; then
1841 PKGFUNC=1
1842 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
1843 SPLITPKG=1
1846 pkgbase=${pkgbase:-${pkgname[0]}}
1848 if [[ -n "${PKGLIST[@]}" ]]; then
1849 unset pkgname
1850 pkgname=("${PKGLIST[@]}")
1853 if (( ! SPLITPKG )); then
1854 if [[ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
1855 || -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-any${PKGEXT} ]] \
1856 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
1857 if (( INSTALL )); then
1858 warning "$(gettext "A package has already been built, installing existing package...")"
1859 install_package
1860 exit $?
1861 else
1862 error "$(gettext "A package has already been built. (use -f to overwrite)")"
1863 exit 1
1866 else
1867 allpkgbuilt=1
1868 somepkgbuilt=0
1869 for pkg in ${pkgname[@]}; do
1870 if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
1871 || -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT} ]]; then
1872 somepkgbuilt=1
1873 else
1874 allpkgbuilt=0
1876 done
1877 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
1878 if (( allpkgbuilt )); then
1879 if (( INSTALL )); then
1880 warning "$(gettext "The package group has already been built, installing existing packages...")"
1881 install_package
1882 exit $?
1883 else
1884 error "$(gettext "The package group has already been built. (use -f to overwrite)")"
1885 exit 1
1888 if (( somepkgbuilt )); then
1889 error "$(gettext "Part of the package group has already been built. (use -f to overwrite)")"
1890 exit 1
1893 unset allpkgbuilt somepkgbuilt
1896 # Run the bare minimum in fakeroot
1897 if (( INFAKEROOT )); then
1898 if (( ! SPLITPKG )); then
1899 if (( ! PKGFUNC )); then
1900 if (( ! REPKG )); then
1901 if (( BUILDFUNC )); then
1902 run_build
1903 tidy_install
1905 else
1906 warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
1907 plain "$(gettext "File permissions may not be preserved.")"
1909 else
1910 run_package
1911 tidy_install
1913 create_package
1914 else
1915 run_split_packaging
1918 msg "$(gettext "Leaving fakeroot environment.")"
1919 exit 0 # $E_OK
1922 msg "$(gettext "Making package: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
1924 # if we are creating a source-only package, go no further
1925 if (( SOURCEONLY )); then
1926 if [[ -f $SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT} ]] \
1927 && (( ! FORCE )); then
1928 error "$(gettext "A source package has already been built. (use -f to overwrite)")"
1929 exit 1
1931 create_srcpackage
1932 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
1933 exit 0
1936 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
1937 # no warning message needed for nobuild, repkg
1938 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
1939 warning "$(gettext "Skipping dependency checks.")"
1941 elif type -p "${PACMAN%% *}" >/dev/null; then
1942 if (( RMDEPS )); then
1943 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
1945 deperr=0
1947 msg "$(gettext "Checking runtime dependencies...")"
1948 resolve_deps ${depends[@]} || deperr=1
1950 msg "$(gettext "Checking buildtime dependencies...")"
1951 resolve_deps ${makedepends[@]} || deperr=1
1953 if (( RMDEPS )); then
1954 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
1957 if (( deperr )); then
1958 error "$(gettext "Could not resolve all dependencies.")"
1959 exit 1
1961 else
1962 warning "$(gettext "%s was not found in PATH; skipping dependency checks.")" "${PACMAN%% *}"
1965 # ensure we have a sane umask set
1966 umask 0022
1968 # get back to our src directory so we can begin with sources
1969 mkdir -p "$srcdir"
1970 chmod a-s "$srcdir"
1971 cd "$srcdir"
1973 if (( NOEXTRACT )); then
1974 warning "$(gettext "Skipping source retrieval -- using existing src/ tree")"
1975 warning "$(gettext "Skipping source integrity checks -- using existing src/ tree")"
1976 warning "$(gettext "Skipping source extraction -- using existing src/ tree")"
1978 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
1979 error "$(gettext "The source directory is empty, there is nothing to build!")"
1980 plain "$(gettext "Aborting...")"
1981 exit 1
1983 elif (( REPKG )); then
1984 if (( ! PKGFUNC && ! SPLITPKG )) \
1985 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
1986 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
1987 plain "$(gettext "Aborting...")"
1988 exit 1
1990 else
1991 download_sources
1992 if (( ! SKIPINTEG )); then
1993 check_checksums
1994 else
1995 warning "$(gettext "Skipping integrity checks.")"
1997 extract_sources
2000 if (( NOBUILD )); then
2001 msg "$(gettext "Sources are ready.")"
2002 exit 0 #E_OK
2003 else
2004 # check for existing pkg directory; don't remove if we are repackaging
2005 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
2006 msg "$(gettext "Removing existing pkg/ directory...")"
2007 rm -rf "$pkgdir"
2009 mkdir -p "$pkgdir"
2010 chmod a-s "$pkgdir"
2011 cd "$startdir"
2013 # if we are root or if fakeroot is not enabled, then we don't use it
2014 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
2015 if (( ! REPKG )); then
2016 devel_update
2017 (( BUILDFUNC )) && run_build
2019 if (( ! SPLITPKG )); then
2020 if (( PKGFUNC )); then
2021 run_package
2022 tidy_install
2023 else
2024 if (( ! REPKG )); then
2025 tidy_install
2026 else
2027 warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
2028 plain "$(gettext "File permissions may not be preserved.")"
2031 create_package
2032 else
2033 run_split_packaging
2035 else
2036 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2037 devel_update
2038 (( BUILDFUNC )) && run_build
2039 cd "$startdir"
2042 msg "$(gettext "Entering fakeroot environment...")"
2044 if [[ -n $newpkgver ]]; then
2045 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
2046 else
2047 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
2052 msg "$(gettext "Finished making: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
2054 install_package
2056 exit 0 #E_OK
2058 # vim: set ts=2 sw=2 noet: