makepkg: use "declare -f" to test for function presence
[pacman-ng.git] / scripts / makepkg.sh.in
blob28c7879ea18a6dcb6269fb2216d8eca5fcb366a3
1 #!/bin/bash -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 # bsdtar (libarchive), bzip2, coreutils, fakeroot, 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' 'force')
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 # If it's a clean exit and -c/--clean has been passed...
139 msg "$(gettext "Cleaning up...")"
140 rm -rf "$pkgdir" "$srcdir"
141 if [[ -n $pkgbase ]]; then
142 # Can't do this unless the BUILDSCRIPT has been sourced.
143 if (( BUILDFUNC )); then
144 rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-build.log"*
146 if (( PKGFUNC )); then
147 rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package.log"*
148 elif (( SPLITPKG )); then
149 for pkg in ${pkgname[@]}; do
150 rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package_${pkg}.log"*
151 done
154 # clean up dangling symlinks to packages
155 for pkg in ${pkgname[@]}; do
156 for file in ${pkg}-*-*-${CARCH}${PKGEXT}; do
157 if [[ -h $file && ! -e $file ]]; then
158 rm -f $file
160 done
161 done
165 remove_deps
170 # Signal Traps
172 set -E
173 trap 'clean_up' 0
174 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
175 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
176 trap 'trap_exit "$(gettext "An unknown error has occurred. Exiting...")"' ERR
178 # a source entry can have two forms :
179 # 1) "filename::http://path/to/file"
180 # 2) "http://path/to/file"
182 # Return the absolute filename of a source entry
184 # This function accepts a source entry or the already extracted filename of a
185 # source entry as input
186 get_filepath() {
187 local file="$(get_filename "$1")"
189 if [[ -f "$startdir/$file" ]]; then
190 file="$startdir/$file"
191 elif [[ -f "$SRCDEST/$file" ]]; then
192 file="$SRCDEST/$file"
193 else
194 return 1
197 echo "$file"
200 # Print 'source not found' error message and exit makepkg
201 missing_source_file() {
202 error "$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
203 plain "$(gettext "Aborting...")"
204 exit 1 # $E_MISSING_FILE
207 # extract the filename from a source entry
208 get_filename() {
209 # if a filename is specified, use it
210 local filename="${1%%::*}"
211 # if it is just an URL, we only keep the last component
212 echo "${filename##*/}"
215 # extract the URL from a source entry
216 get_url() {
217 # strip an eventual filename
218 echo "${1#*::}"
222 # Checks to see if options are present in makepkg.conf or PKGBUILD;
223 # PKGBUILD options always take precedence.
225 # usage : check_option( $option )
226 # return : y - enabled
227 # n - disabled
228 # ? - not found
230 check_option() {
231 local ret=$(in_opt_array "$1" ${options[@]})
232 if [[ $ret != '?' ]]; then
233 echo $ret
234 return
237 # fall back to makepkg.conf options
238 ret=$(in_opt_array "$1" ${OPTIONS[@]})
239 if [[ $ret != '?' ]]; then
240 echo $ret
241 return
244 echo '?' # Not Found
249 # Check if option is present in BUILDENV
251 # usage : check_buildenv( $option )
252 # return : y - enabled
253 # n - disabled
254 # ? - not found
256 check_buildenv() {
257 echo $(in_opt_array "$1" ${BUILDENV[@]})
262 # usage : in_opt_array( $needle, $haystack )
263 # return : y - enabled
264 # n - disabled
265 # ? - not found
267 in_opt_array() {
268 local needle="${1,,}"; shift
270 local opt
271 for opt in "$@"; do
272 opt="${opt,,}"
273 if [[ $opt = $needle ]]; then
274 echo 'y' # Enabled
275 return
276 elif [[ $opt = "!$needle" ]]; then
277 echo 'n' # Disabled
278 return
280 done
282 echo '?' # Not Found
287 # usage : in_array( $needle, $haystack )
288 # return : 0 - found
289 # 1 - not found
291 in_array() {
292 local needle=$1; shift
293 [[ -z $1 ]] && return 1 # Not Found
294 local item
295 for item in "$@"; do
296 [[ $item = $needle ]] && return 0 # Found
297 done
298 return 1 # Not Found
301 get_downloadclient() {
302 # $1 = URL with valid protocol prefix
303 local url=$1
304 local proto="${url%%://*}"
306 # loop through DOWNLOAD_AGENTS variable looking for protocol
307 local i
308 for i in "${DLAGENTS[@]}"; do
309 local handler="${i%%::*}"
310 if [[ $proto = $handler ]]; then
311 agent="${i##*::}"
312 break
314 done
316 # if we didn't find an agent, return an error
317 if [[ -z $agent ]]; then
318 error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$MAKEPKG_CONF"
319 plain "$(gettext "Aborting...")"
320 exit 1 # $E_CONFIG_ERROR
323 # ensure specified program is installed
324 local program="${agent%% *}"
325 if [[ ! -x $program ]]; then
326 local baseprog=$(basename $program)
327 error "$(gettext "The download program %s is not installed.")" "$baseprog"
328 plain "$(gettext "Aborting...")"
329 exit 1 # $E_MISSING_PROGRAM
332 echo "$agent"
335 download_file() {
336 # download command
337 local dlcmd=$1
338 # URL of the file
339 local url=$2
340 # destination file
341 local file=$3
342 # temporary download file, default to last component of the URL
343 local dlfile="${url##*/}"
345 # replace %o by the temporary dlfile if it exists
346 if [[ $dlcmd = *%o* ]]; then
347 dlcmd=${dlcmd//\%o/\"$file.part\"}
348 dlfile="$file.part"
350 # add the URL, either in place of %u or at the end
351 if [[ $dlcmd = *%u* ]]; then
352 dlcmd=${dlcmd//\%u/\"$url\"}
353 else
354 dlcmd="$dlcmd \"$url\""
357 local ret=0
358 eval "$dlcmd || ret=\$?"
359 if (( ret )); then
360 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
361 return $ret
364 # rename the temporary download file to the final destination
365 if [[ $dlfile != $file ]]; then
366 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$file"
370 run_pacman() {
371 local ret=0
372 if (( ! ASROOT )) && [[ $1 != "-T" && $1 != "-Qq" ]]; then
373 if type -p sudo >/dev/null && sudo -l $PACMAN &>/dev/null; then
374 sudo $PACMAN $PACMAN_OPTS "$@" || ret=$?
375 else
376 su -c "$PACMAN $PACMAN_OPTS $*" || ret=$?
378 else
379 $PACMAN $PACMAN_OPTS "$@" || ret=$?
381 return $ret
384 check_deps() {
385 (( $# > 0 )) || return
387 local ret=0
388 pmout=$(run_pacman -T "$@")
389 ret=$?
390 if (( ret == 127 )); then #unresolved deps
391 echo "$pmout"
392 elif (( ret )); then
393 error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout"
394 exit 1
398 handle_deps() {
399 local R_DEPS_SATISFIED=0
400 local R_DEPS_MISSING=1
402 (( $# == 0 )) && return $R_DEPS_SATISFIED
404 local deplist="$*"
406 if (( ! DEP_BIN )); then
407 return $R_DEPS_MISSING
410 if (( DEP_BIN )); then
411 # install missing deps from binary packages (using pacman -S)
412 msg "$(gettext "Installing missing dependencies...")"
414 if ! run_pacman -S --asdeps $deplist; then
415 error "$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
416 exit 1 # TODO: error code
420 # we might need the new system environment
421 # avoid triggering the ERR trap
422 local restoretrap=$(trap -p ERR)
423 trap - ERR
424 source /etc/profile &>/dev/null
425 eval $restoretrap
427 return $R_DEPS_SATISFIED
430 resolve_deps() {
431 local R_DEPS_SATISFIED=0
432 local R_DEPS_MISSING=1
434 local deplist="$(check_deps $*)"
435 if [[ -z $deplist ]]; then
436 return $R_DEPS_SATISFIED
439 if handle_deps $deplist; then
440 # check deps again to make sure they were resolved
441 deplist="$(check_deps $*)"
442 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
443 elif (( DEP_BIN )); then
444 error "$(gettext "Failed to install all missing dependencies.")"
447 msg "$(gettext "Missing Dependencies:")"
448 local dep
449 for dep in $deplist; do
450 msg2 "$dep"
451 done
453 return $R_DEPS_MISSING
456 remove_deps() {
457 (( ! RMDEPS )) && return
459 # check for packages removed during dependency install (e.g. due to conflicts)
460 # removing all installed packages is risky in this case
461 if [[ -n $(comm -23 <(printf "%s\n" "${original_pkglist[@]}") \
462 <(printf "%s\n" "${current_pkglist[@]}")) ]]; then
463 warning "$(gettext "Failed to remove installed dependencies.")"
464 return 0
467 local deplist=($(comm -13 <(printf "%s\n" "${original_pkglist[@]}") \
468 <(printf "%s\n" "${current_pkglist[@]}")))
469 (( ${#deplist[@]} == 0 )) && return
471 msg "Removing installed dependencies..."
472 # exit cleanly on failure to remove deps as package has been built successfully
473 if ! run_pacman -Rn ${deplist[@]}; then
474 warning "$(gettext "Failed to remove installed dependencies.")"
475 return 0
479 download_sources() {
480 msg "$(gettext "Retrieving Sources...")"
482 pushd "$SRCDEST" &>/dev/null
484 local netfile
485 for netfile in "${source[@]}"; do
486 local file
487 if file=$(get_filepath "$netfile"); then
488 msg2 "$(gettext "Found %s")" "${file##*/}"
489 ln -sf "$file" "$srcdir/"
490 continue
493 file=$(get_filename "$netfile")
494 local url=$(get_url "$netfile")
496 # if we get here, check to make sure it was a URL, else fail
497 if [[ $file = $url ]]; then
498 error "$(gettext "%s was not found in the build directory and is not a URL.")" "$file"
499 exit 1 # $E_MISSING_FILE
502 # find the client we should use for this URL
503 local dlclient=$(get_downloadclient "$url") || exit $?
505 msg2 "$(gettext "Downloading %s...")" "$file"
506 # fix flyspray bug #3289
507 local ret=0
508 download_file "$dlclient" "$url" "$file" || ret=$?
509 if (( ret )); then
510 error "$(gettext "Failure while downloading %s")" "$file"
511 plain "$(gettext "Aborting...")"
512 exit 1
514 rm -f "$srcdir/$file"
515 ln -s "$SRCDEST/$file" "$srcdir/"
516 done
518 popd &>/dev/null
521 get_integlist() {
522 local integ
523 local integlist=()
525 for integ in md5 sha1 sha256 sha384 sha512; do
526 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
527 if [[ -n "$integrity_sums" ]]; then
528 integlist=(${integlist[@]} $integ)
530 done
532 if (( ${#integlist[@]} > 0 )); then
533 echo ${integlist[@]}
534 else
535 echo ${INTEGRITY_CHECK[@]}
539 generate_checksums() {
540 msg "$(gettext "Generating checksums for source files...")"
541 plain ""
543 if ! type -p openssl >/dev/null; then
544 error "$(gettext "Cannot find openssl.")"
545 exit 1 # $E_MISSING_PROGRAM
548 local integlist
549 if (( $# == 0 )); then
550 integlist=$(get_integlist)
551 else
552 integlist=$@
555 local integ
556 for integ in ${integlist[@]}; do
557 integ="${integ,,}"
558 case "$integ" in
559 md5|sha1|sha256|sha384|sha512) : ;;
561 error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
562 exit 1;; # $E_CONFIG_ERROR
563 esac
565 local ct=0
566 local numsrc=${#source[@]}
567 echo -n "${integ}sums=("
569 local i
570 local indent=''
571 for (( i = 0; i < ${#integ} + 6; i++ )); do
572 indent="$indent "
573 done
575 local netfile
576 for netfile in "${source[@]}"; do
577 local file="$(get_filepath "$netfile")" || missing_source_file "$netfile"
578 local sum="$(openssl dgst -${integ} "$file")"
579 sum=${sum##* }
580 (( ct )) && echo -n "$indent"
581 echo -n "'$sum'"
582 ct=$(($ct+1))
583 (( $ct < $numsrc )) && echo
584 done
586 echo ")"
587 done
590 check_checksums() {
591 (( ! ${#source[@]} )) && return 0
593 if ! type -p openssl >/dev/null; then
594 error "$(gettext "Cannot find openssl.")"
595 exit 1 # $E_MISSING_PROGRAM
598 local correlation=0
599 local integ required
600 for integ in md5 sha1 sha256 sha384 sha512; do
601 local integrity_sums=($(eval echo "\${${integ}sums[@]}"))
602 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
603 msg "$(gettext "Validating source files with %s...")" "${integ}sums"
604 correlation=1
605 local errors=0
606 local idx=0
607 local file
608 for file in "${source[@]}"; do
609 local found=1
610 file="$(get_filename "$file")"
611 echo -n " $file ... " >&2
613 if ! file="$(get_filepath "$file")"; then
614 echo "$(gettext "NOT FOUND")" >&2
615 errors=1
616 found=0
619 if (( $found )) ; then
620 local expectedsum="${integrity_sums[$idx],,}"
621 local realsum="$(openssl dgst -${integ} "$file")"
622 realsum="${realsum##* }"
623 if [[ $expectedsum = $realsum ]]; then
624 echo "$(gettext "Passed")" >&2
625 else
626 echo "$(gettext "FAILED")" >&2
627 errors=1
631 idx=$((idx + 1))
632 done
634 if (( errors )); then
635 error "$(gettext "One or more files did not pass the validity check!")"
636 exit 1 # TODO: error code
638 elif (( ${#integrity_sums[@]} )); then
639 error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
640 exit 1 # TODO: error code
642 done
644 if (( ! correlation )); then
645 error "$(gettext "Integrity checks are missing.")"
646 exit 1 # TODO: error code
650 extract_sources() {
651 msg "$(gettext "Extracting Sources...")"
652 local netfile
653 for netfile in "${source[@]}"; do
654 file=$(get_filename "$netfile")
655 if in_array "$file" ${noextract[@]}; then
656 #skip source files in the noextract=() array
657 # these are marked explicitly to NOT be extracted
658 continue
662 # fix flyspray #6246
663 local file_type=$(file -bizL "$file")
664 local ext=${file##*.}
665 local cmd=''
666 case "$file_type" in
667 *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
668 cmd="bsdtar" ;;
669 *application/x-gzip*)
670 case "$ext" in
671 gz|z|Z) cmd="gzip" ;;
672 *) continue;;
673 esac ;;
674 *application/x-bzip*)
675 case "$ext" in
676 bz2|bz) cmd="bzip2" ;;
677 *) continue;;
678 esac ;;
679 *application/x-xz*)
680 case "$ext" in
681 xz) cmd="xz" ;;
682 *) continue;;
683 esac ;;
685 # See if bsdtar can recognize the file
686 if bsdtar -tf "$file" -q '*' &>/dev/null; then
687 cmd="bsdtar"
688 else
689 continue
690 fi ;;
691 esac
693 local ret=0
694 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
695 if [[ $cmd = bsdtar ]]; then
696 $cmd -xf "$file" || ret=$?
697 else
698 rm -f "${file%.*}"
699 $cmd -dcf "$file" > "${file%.*}" || ret=$?
701 if (( ret )); then
702 error "$(gettext "Failed to extract %s")" "$file"
703 plain "$(gettext "Aborting...")"
704 exit 1
706 done
708 if (( EUID == 0 )); then
709 # change perms of all source files to root user & root group
710 chown -R 0:0 "$srcdir"
714 error_function() {
715 if [[ -p $logpipe ]]; then
716 rm "$logpipe"
718 # first exit all subshells, then print the error
719 if (( ! BASH_SUBSHELL )); then
720 plain "$(gettext "Aborting...")"
721 remove_deps
723 exit 2 # $E_BUILD_FAILED
726 run_function() {
727 if [[ -z $1 ]]; then
728 return 1
730 pkgfunc="$1"
732 # clear user-specified makeflags if requested
733 if [[ $(check_option makeflags) = "n" ]]; then
734 MAKEFLAGS=""
737 msg "$(gettext "Starting %s()...")" "$pkgfunc"
738 cd "$srcdir"
740 # ensure all necessary build variables are exported
741 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
742 # save our shell options so pkgfunc() can't override what we need
743 local shellopts=$(shopt -p)
745 local ret=0
746 if (( LOGGING )); then
747 BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log"
748 if [[ -f $BUILDLOG ]]; then
749 local i=1
750 while true; do
751 if [[ -f $BUILDLOG.$i ]]; then
752 i=$(($i +1))
753 else
754 break
756 done
757 mv "$BUILDLOG" "$BUILDLOG.$i"
760 # ensure overridden package variables survive tee with split packages
761 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
762 mknod "$logpipe" p
763 exec 3>&1
764 tee "$BUILDLOG" < "$logpipe" &
765 exec 1>"$logpipe" 2>"$logpipe"
766 restoretrap=$(trap -p ERR)
767 trap 'error_function' ERR
768 $pkgfunc 2>&1
769 eval $restoretrap
770 sync
771 exec 1>&3 2>&3 3>&-
772 rm "$logpipe"
773 else
774 restoretrap=$(trap -p ERR)
775 trap 'error_function' ERR
776 $pkgfunc 2>&1
777 eval $restoretrap
779 # reset our shell options
780 eval "$shellopts"
783 run_build() {
784 # use distcc if it is requested (check buildenv and PKGBUILD opts)
785 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
786 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
787 export DISTCC_HOSTS
788 elif [[ $(check_option distcc) = "n" ]]; then
789 # if it is not wanted, clear the makeflags too
790 MAKEFLAGS=""
793 # use ccache if it is requested (check buildenv and PKGBUILD opts)
794 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
795 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
798 run_function "build"
801 run_package() {
802 if [[ -z $1 ]]; then
803 pkgfunc="package"
804 else
805 pkgfunc="package_$1"
808 run_function "$pkgfunc"
811 tidy_install() {
812 cd "$pkgdir"
813 msg "$(gettext "Tidying install...")"
815 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
816 msg2 "$(gettext "Removing doc files...")"
817 rm -rf ${DOC_DIRS[@]}
820 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
821 msg2 "$(gettext "Purging other files...")"
822 local pt
823 for pt in "${PURGE_TARGETS[@]}"; do
824 if [[ ${pt} = ${pt//\/} ]]; then
825 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
826 else
827 rm -f ${pt}
829 done
832 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
833 msg2 "$(gettext "Compressing man and info pages...")"
834 local manpage ext file link hardlinks hl
835 find ${MAN_DIRS[@]} -type f 2>/dev/null |
836 while read manpage ; do
837 ext="${manpage##*.}"
838 file="${manpage##*/}"
839 if [[ $ext != gz && $ext != bz2 ]]; then
840 # update symlinks to this manpage
841 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
842 while read link ; do
843 rm -f "$link"
844 ln -sf "${file}.gz" "${link}.gz"
845 done
847 # check file still exists (potentially already compressed due to hardlink)
848 if [[ -f ${manpage} ]]; then
849 # find hard links and remove them
850 # the '|| true' part keeps the script from bailing if find returned an
851 # error, such as when one of the man directories doesn't exist
852 hardlinks="$(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
853 for hl in ${hardlinks}; do
854 rm -f "${hl}";
855 done
856 # compress the original
857 gzip -9 "$manpage"
858 # recreate hard links removed earlier
859 for hl in ${hardlinks}; do
860 ln "${manpage}.gz" "${hl}.gz"
861 chmod 644 ${hl}.gz
862 done
865 done
868 if [[ $(check_option strip) = y && -n ${STRIP_DIRS[*]} ]]; then
869 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
870 # make sure library stripping variables are defined to prevent excess stripping
871 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
872 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
873 local binary
874 find ${STRIP_DIRS[@]} -type f -perm -u+w 2>/dev/null | while read binary ; do
875 case "$(file -bi "$binary")" in
876 *application/x-sharedlib*) # Libraries (.so)
877 /usr/bin/strip $STRIP_SHARED "$binary";;
878 *application/x-archive*) # Libraries (.a)
879 /usr/bin/strip $STRIP_STATIC "$binary";;
880 *application/x-executable*) # Binaries
881 /usr/bin/strip $STRIP_BINARIES "$binary";;
882 esac
883 done
886 if [[ $(check_option libtool) = "n" ]]; then
887 msg2 "$(gettext "Removing libtool .la files...")"
888 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
891 if [[ $(check_option emptydirs) = "n" ]]; then
892 msg2 "$(gettext "Removing empty directories...")"
893 find . -depth -type d -empty -delete
897 write_pkginfo() {
898 local builddate=$(date -u "+%s")
899 if [[ -n $PACKAGER ]]; then
900 local packager="$PACKAGER"
901 else
902 local packager="Unknown Packager"
904 local size="$(du -sk)"
905 size="$(( ${size%%[^0-9]*} * 1024 ))"
907 msg2 "$(gettext "Generating .PKGINFO file...")"
908 echo "# Generated by makepkg $myver"
909 if (( INFAKEROOT )); then
910 echo "# using $(fakeroot -v)"
912 echo "# $(LC_ALL=C date -u)"
913 echo "pkgname = $1"
914 (( SPLITPKG )) && echo pkgbase = $pkgbase
915 echo "pkgver = $pkgver-$pkgrel"
916 echo "pkgdesc = $pkgdesc"
917 echo "url = $url"
918 echo "builddate = $builddate"
919 echo "packager = $packager"
920 echo "size = $size"
921 echo "arch = $PKGARCH"
922 if [[ $(check_option force) = "y" ]]; then
923 echo "force = true"
926 [[ $license ]] && printf "license = %s\n" "${license[@]}"
927 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
928 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
929 [[ $depends ]] && printf "depend = %s\n" "${depends[@]}"
930 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}"
931 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
932 [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
933 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
935 for it in "${packaging_options[@]}"; do
936 local ret="$(check_option $it)"
937 if [[ $ret != "?" ]]; then
938 if [[ $ret = y ]]; then
939 echo "makepkgopt = $it"
940 else
941 echo "makepkgopt = !$it"
944 done
946 # TODO maybe remove this at some point
947 # warn if license array is not present or empty
948 if [[ -z $license ]]; then
949 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
950 plain "$(gettext "Example for GPL\'ed software: license=('GPL').")"
954 check_package() {
955 cd "$pkgdir"
957 # check existence of backup files
958 local file
959 for file in "${backup[@]}"; do
960 if [[ ! -f $file ]]; then
961 warning "$(gettext "Invalid backup entry : %s")" "$file"
963 done
965 # check for references to the build directory
966 if grep -R "${srcdir}" "${pkgdir}" &>/dev/null; then
967 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
971 create_package() {
972 if [[ ! -d $pkgdir ]]; then
973 error "$(gettext "Missing pkg/ directory.")"
974 plain "$(gettext "Aborting...")"
975 exit 1 # $E_MISSING_PKGDIR
978 check_package
980 cd "$pkgdir"
981 msg "$(gettext "Creating package...")"
983 if [[ -z $1 ]]; then
984 nameofpkg="$pkgname"
985 else
986 nameofpkg="$1"
989 if [[ $arch = "any" ]]; then
990 PKGARCH="any"
991 else
992 PKGARCH=$CARCH
995 write_pkginfo $nameofpkg > .PKGINFO
997 local comp_files=".PKGINFO"
999 # check for an install script
1000 if [[ -n $install ]]; then
1001 msg2 "$(gettext "Adding install script...")"
1002 cp "$startdir/$install" .INSTALL
1003 chmod 644 .INSTALL
1004 comp_files="$comp_files .INSTALL"
1007 # do we have a changelog?
1008 if [[ -n $changelog ]]; then
1009 msg2 "$(gettext "Adding package changelog...")"
1010 cp "$startdir/$changelog" .CHANGELOG
1011 chmod 644 .CHANGELOG
1012 comp_files="$comp_files .CHANGELOG"
1015 # tar it up
1016 msg2 "$(gettext "Compressing package...")"
1018 case "$PKGEXT" in
1019 *tar.gz) EXT=${PKGEXT%.gz} ;;
1020 *tar.bz2) EXT=${PKGEXT%.bz2} ;;
1021 *tar.xz) EXT=${PKGEXT%.xz} ;;
1022 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1023 "$PKGEXT" ; EXT=$PKGEXT ;;
1024 esac
1025 local tar_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${EXT}"
1026 local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}"
1028 local ret=0
1030 # when fileglobbing, we want * in an empty directory to expand to
1031 # the null string rather than itself
1032 shopt -s nullglob
1033 bsdtar -cf - $comp_files * > "$tar_file" || ret=$?
1034 shopt -u nullglob
1036 if (( ! ret )); then
1037 case "$PKGEXT" in
1038 *tar.gz) gzip -f -n "$tar_file" ;;
1039 *tar.bz2) bzip2 -f "$tar_file" ;;
1040 *tar.xz) xz -z -f "$tar_file" ;;
1041 esac
1042 ret=$?
1045 if (( ret )); then
1046 error "$(gettext "Failed to create package file.")"
1047 exit 1 # TODO: error code
1050 if (( ! ret )) && [[ "$PKGDEST" != "${startdir}" ]]; then
1051 ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1052 ret=$?
1055 if (( ret )); then
1056 warning "$(gettext "Failed to create symlink to package file.")"
1060 create_srcpackage() {
1061 cd "$startdir"
1063 # Get back to our src directory so we can begin with sources.
1064 mkdir -p "$srcdir"
1065 chmod a-s "$srcdir"
1066 cd "$srcdir"
1067 if (( ! SKIPINTEG || SOURCEONLY == 2 )); then
1068 download_sources
1070 if (( ! SKIPINTEG )); then
1071 # We can only check checksums if we have all files.
1072 check_checksums
1073 else
1074 warning "$(gettext "Skipping integrity checks.")"
1076 cd "$startdir"
1078 msg "$(gettext "Creating source package...")"
1079 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1080 mkdir "${srclinks}"/${pkgbase}
1082 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1083 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1085 local file
1086 for file in "${source[@]}"; do
1087 if [[ -f $file ]]; then
1088 msg2 "$(gettext "Adding %s...")" "$file"
1089 ln -s "${startdir}/$file" "$srclinks/$pkgbase"
1090 elif (( SOURCEONLY == 2 )); then
1091 local absfile=$(get_filepath "$file") || missing_source_file "$file"
1092 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1093 ln -s "$absfile" "$srclinks/$pkgbase"
1095 done
1097 local i
1098 for i in 'changelog' 'install'; do
1099 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDSCRIPT")
1100 local file
1101 for file in $filelist; do
1102 # evaluate any bash variables used
1103 eval file=${file}
1104 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1105 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1106 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1108 done
1109 done
1111 local TAR_OPT
1112 case "$SRCEXT" in
1113 *tar.gz) TAR_OPT="z" ;;
1114 *tar.bz2) TAR_OPT="j" ;;
1115 *tar.xz) TAR_OPT="J" ;;
1116 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1117 "$SRCEXT" ;;
1118 esac
1120 local pkg_file="$SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT}"
1122 # tar it up
1123 msg2 "$(gettext "Compressing source package...")"
1124 cd "${srclinks}"
1125 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1126 error "$(gettext "Failed to create source package file.")"
1127 exit 1 # TODO: error code
1129 cd "${startdir}"
1130 rm -rf "${srclinks}"
1133 install_package() {
1134 (( ! INSTALL )) && return
1136 if (( ! SPLITPKG )); then
1137 msg "$(gettext "Installing package %s with %s -U...")" "$pkgname" "$PACMAN"
1138 else
1139 msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN"
1142 local pkglist
1143 for pkg in ${pkgname[@]}; do
1144 if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then
1145 pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"
1146 else
1147 pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}"
1149 done
1151 if ! run_pacman -U $pkglist; then
1152 warning "$(gettext "Failed to install built package(s).")"
1153 return 0
1157 check_sanity() {
1158 # check for no-no's in the build script
1159 if [[ -z $pkgname ]]; then
1160 error "$(gettext "%s is not allowed to be empty.")" "pkgname"
1161 return 1
1163 if [[ -z $pkgver ]]; then
1164 error "$(gettext "%s is not allowed to be empty.")" "pkgver"
1165 return 1
1167 if [[ -z $pkgrel ]]; then
1168 error "$(gettext "%s is not allowed to be empty.")" "pkgrel"
1169 return 1
1172 local name
1173 for name in "${pkgname[@]}"; do
1174 if [[ ${name:0:1} = "-" ]]; then
1175 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1176 return 1
1178 done
1180 if [[ ${pkgbase:0:1} = "-" ]]; then
1181 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1182 return 1
1184 if [[ $pkgver != ${pkgver//-/} ]]; then
1185 error "$(gettext "%s is not allowed to contain hyphens.")" "pkgver"
1186 return 1
1188 if [[ $pkgrel != ${pkgrel//-/} ]]; then
1189 error "$(gettext "%s is not allowed to contain hyphens.")" "pkgrel"
1190 return 1
1193 if [[ $arch != 'any' ]]; then
1194 if ! in_array $CARCH ${arch[@]}; then
1195 if (( ! IGNOREARCH )); then
1196 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1197 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1198 plain "$(gettext "such as arch=('%s').")" "$CARCH"
1199 return 1
1204 local provide
1205 for provide in ${provides[@]}; do
1206 if [[ $provide != ${provide//</} || $provide != ${provide//>/} ]]; then
1207 error "$(gettext "Provides array cannot contain comparison (< or >) operators.")"
1208 return 1
1210 done
1212 local file
1213 for file in "${backup[@]}"; do
1214 if [[ ${file:0:1} = "/" ]]; then
1215 error "$(gettext "Invalid backup entry : %s")" "$file"
1216 return 1
1218 done
1220 local optdepend
1221 for optdepend in "${optdepends[@]}"; do
1222 pkg=${optdepend%%:*}
1223 if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]*$ ]]; then
1224 error "$(gettext "Invalid syntax for optdepend : '%s'")" "$optdepend"
1226 done
1228 local i
1229 for i in 'changelog' 'install'; do
1230 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1231 local file
1232 for file in $filelist; do
1233 # evaluate any bash variables used
1234 eval file=${file}
1235 if [[ ! -f $file ]]; then
1236 error "$(gettext "%s file (%s) does not exist.")" "${i^}" "$file"
1237 return 1
1239 done
1240 done
1242 local valid_options=1
1243 local opt known kopt
1244 for opt in ${options[@]}; do
1245 known=0
1246 # check if option matches a known option or its inverse
1247 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1248 if [[ ${opt} = ${kopt} || ${opt} = "!${kopt}" ]]; then
1249 known=1
1251 done
1252 if (( ! known )); then
1253 error "$(gettext "options array contains unknown option '%s'")" "$opt"
1254 valid_options=0
1256 done
1257 if (( ! valid_options )); then
1258 return 1
1261 if (( ${#pkgname[@]} > 1 )); then
1262 for pkg in ${pkgname[@]}; do
1263 if declare -f package_${pkg} >/dev/null; then
1264 error "$(gettext "missing package function for split package '%s'")" "$pkg"
1265 return 1
1267 done
1270 if [[ -n "${PKGLIST[@]}" ]]; then
1271 for pkg in ${PKGLIST[@]}; do
1272 if ! in_array $pkg ${pkgname[@]}; then
1273 error "$(gettext "requested package %s is not provided in %s")" "$pkg" "$BUILDFILE"
1274 return 1
1276 done
1279 return 0
1282 devel_check() {
1283 newpkgver=""
1285 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1286 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1287 if (( HOLDVER || SOURCEONLY || REPKG )) \
1288 || [[ ! -f $BUILDFILE || ! -w $BUILDFILE ]]; then
1289 return
1292 if [[ -z $FORCE_VER ]]; then
1293 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1294 # This will only be used on the first call to makepkg; subsequent
1295 # calls to makepkg via fakeroot will explicitly pass the version
1296 # number to avoid having to determine the version number twice.
1297 # Also do a brief check to make sure we have the VCS tool available.
1298 oldpkgver=$pkgver
1299 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1300 type -p darcs >/dev/null || return 0
1301 msg "$(gettext "Determining latest darcs revision...")"
1302 newpkgver=$(date +%Y%m%d)
1303 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1304 type -p cvs >/dev/null || return 0
1305 msg "$(gettext "Determining latest cvs revision...")"
1306 newpkgver=$(date +%Y%m%d)
1307 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1308 type -p git >/dev/null || return 0
1309 msg "$(gettext "Determining latest git revision...")"
1310 newpkgver=$(date +%Y%m%d)
1311 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1312 type -p svn >/dev/null || return 0
1313 msg "$(gettext "Determining latest svn revision...")"
1314 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1315 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1316 type -p bzr >/dev/null || return 0
1317 msg "$(gettext "Determining latest bzr revision...")"
1318 newpkgver=$(bzr revno ${_bzrtrunk})
1319 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1320 type -p hg >/dev/null || return 0
1321 msg "$(gettext "Determining latest hg revision...")"
1322 if [[ -d ./src/$_hgrepo ]] ; then
1323 cd ./src/$_hgrepo
1324 hg pull
1325 hg update
1326 else
1327 [[ ! -d ./src/ ]] && mkdir ./src/
1328 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1329 cd ./src/$_hgrepo
1331 newpkgver=$(hg tip --template "{rev}")
1332 cd ../../
1335 if [[ -n $newpkgver ]]; then
1336 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1339 else
1340 # Version number retrieved from fakeroot->makepkg argument
1341 newpkgver=$FORCE_VER
1345 devel_update() {
1346 # This is lame, but if we're wanting to use an updated pkgver for
1347 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1348 # the new pkgver and then re-source it. This is the most robust
1349 # method for dealing with PKGBUILDs that use, e.g.:
1351 # pkgver=23
1352 # ...
1353 # _foo=pkgver
1355 if [[ -n $newpkgver ]]; then
1356 if [[ $newpkgver != $pkgver ]]; then
1357 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1358 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1359 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1360 source "$BUILDFILE"
1366 backup_package_variables() {
1367 for var in ${splitpkg_overrides[@]}; do
1368 indirect="${var}_backup"
1369 eval "${indirect}=(\"\${$var[@]}\")"
1370 done
1373 restore_package_variables() {
1374 for var in ${splitpkg_overrides[@]}; do
1375 indirect="${var}_backup"
1376 if [[ -n ${!indirect} ]]; then
1377 eval "${var}=(\"\${$indirect[@]}\")"
1378 else
1379 unset ${var}
1381 done
1384 # getopt like parser
1385 parse_options() {
1386 local short_options=$1; shift;
1387 local long_options=$1; shift;
1388 local ret=0;
1389 local unused_options=""
1391 while [[ -n $1 ]]; do
1392 if [[ ${1:0:2} = '--' ]]; then
1393 if [[ -n ${1:2} ]]; then
1394 local match=""
1395 for i in ${long_options//,/ }; do
1396 if [[ ${1:2} = ${i//:} ]]; then
1397 match=$i
1398 break
1400 done
1401 if [[ -n $match ]]; then
1402 if [[ ${1:2} = $match ]]; then
1403 printf ' %s' "$1"
1404 else
1405 if [[ -n $2 ]]; then
1406 printf ' %s' "$1"
1407 shift
1408 printf " '%s'" "$1"
1409 else
1410 echo "makepkg: option '$1' $(gettext "requires an argument")" >&2
1411 ret=1
1414 else
1415 echo "makepkg: $(gettext "unrecognized option") '$1'" >&2
1416 ret=1
1418 else
1419 shift
1420 break
1422 elif [[ ${1:0:1} = '-' ]]; then
1423 for ((i=1; i<${#1}; i++)); do
1424 if [[ $short_options =~ ${1:i:1} ]]; then
1425 if [[ $short_options =~ "${1:i:1}:" ]]; then
1426 if [[ -n ${1:$i+1} ]]; then
1427 printf ' -%s' "${1:i:1}"
1428 printf " '%s'" "${1:$i+1}"
1429 else
1430 if [[ -n $2 ]]; then
1431 printf ' -%s' "${1:i:1}"
1432 shift
1433 printf " '%s'" "${1}"
1434 else
1435 echo "makepkg: option $(gettext "requires an argument") -- '${1:i:1}'" >&2
1436 ret=1
1439 break
1440 else
1441 printf ' -%s' "${1:i:1}"
1443 else
1444 echo "makepkg: $(gettext "invalid option") -- '${1:i:1}'" >&2
1445 ret=1
1447 done
1448 else
1449 unused_options="${unused_options} '$1'"
1451 shift
1452 done
1454 printf " --"
1455 if [[ -n $unused_options ]]; then
1456 for i in ${unused_options[@]}; do
1457 printf ' %s' "$i"
1458 done
1460 if [[ -n $1 ]]; then
1461 while [[ -n $1 ]]; do
1462 printf " '%s'" "${1}"
1463 shift
1464 done
1466 printf "\n"
1468 return $ret
1471 usage() {
1472 printf "makepkg (pacman) %s\n" "$myver"
1473 echo
1474 printf "$(gettext "Usage: %s [options]")\n" "$0"
1475 echo
1476 echo "$(gettext "Options:")"
1477 printf "$(gettext " -A, --ignorearch Ignore incomplete arch field in %s")\n" "$BUILDSCRIPT"
1478 echo "$(gettext " -c, --clean Clean up work files after build")"
1479 echo "$(gettext " -C, --cleancache Clean up source files from the cache")"
1480 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1481 echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")"
1482 echo "$(gettext " -f, --force Overwrite existing package")"
1483 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1484 echo "$(gettext " -h, --help This help")"
1485 echo "$(gettext " -i, --install Install package after successful build")"
1486 echo "$(gettext " -L, --log Log package build process")"
1487 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1488 echo "$(gettext " -o, --nobuild Download and extract files only")"
1489 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1490 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1491 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1492 echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")"
1493 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1494 echo "$(gettext " --asroot Allow makepkg to run as root user")"
1495 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1496 echo "$(gettext " --holdver Prevent automatic version bumping for development PKGBUILDs")"
1497 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1498 echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")"
1499 echo "$(gettext " --source Generate a source-only tarball without downloaded sources")"
1500 echo
1501 echo "$(gettext "These options can be passed to pacman:")"
1502 echo
1503 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1504 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1505 echo
1506 printf "$(gettext "If -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT"
1507 echo
1510 version() {
1511 printf "makepkg (pacman) %s\n" "$myver"
1512 printf "$(gettext "\
1513 Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1514 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1515 This is free software; see the source for copying conditions.\n\
1516 There is NO WARRANTY, to the extent permitted by law.\n")"
1519 # PROGRAM START
1521 # determine whether we have gettext; make it a no-op if we do not
1522 if ! type -p gettext >/dev/null; then
1523 gettext() {
1524 echo "$@"
1528 ARGLIST=("$@")
1530 # Parse Command Line Options.
1531 OPT_SHORT="AcCdefFghiLmop:rRsV"
1532 OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps"
1533 OPT_LONG="$OPT_LONG,noextract,force,forcever:,geninteg,help,holdver"
1534 OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg"
1535 OPT_LONG="$OPT_LONG,source,syncdeps,version,config:"
1536 # Pacman Options
1537 OPT_LONG="$OPT_LONG,noconfirm,noprogressbar"
1538 OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
1539 if [[ $OPT_TEMP = *'PARSE_OPTIONS FAILED'* ]]; then
1540 # This is a small hack to stop the script bailing with 'set -e'
1541 echo; usage; exit 1 # E_INVALID_OPTION;
1543 eval set -- "$OPT_TEMP"
1544 unset OPT_SHORT OPT_LONG OPT_TEMP
1546 while true; do
1547 case "$1" in
1548 # Pacman Options
1549 --noconfirm) PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;;
1550 --noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;;
1552 # Makepkg Options
1553 --allsource) SOURCEONLY=2 ;;
1554 --asroot) ASROOT=1 ;;
1555 -A|--ignorearch) IGNOREARCH=1 ;;
1556 -c|--clean) CLEANUP=1 ;;
1557 -C|--cleancache) CLEANCACHE=1 ;;
1558 --config) shift; MAKEPKG_CONF=$1 ;;
1559 -d|--nodeps) NODEPS=1 ;;
1560 -e|--noextract) NOEXTRACT=1 ;;
1561 -f|--force) FORCE=1 ;;
1562 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1563 --forcever) shift; FORCE_VER=$1;;
1564 -F) INFAKEROOT=1 ;;
1565 -g|--geninteg) GENINTEG=1 ;;
1566 --holdver) HOLDVER=1 ;;
1567 -i|--install) INSTALL=1 ;;
1568 -L|--log) LOGGING=1 ;;
1569 -m|--nocolor) USE_COLOR='n' ;;
1570 -o|--nobuild) NOBUILD=1 ;;
1571 -p) shift; BUILDFILE=$1 ;;
1572 --pkg) shift; PKGLIST=$1 ;;
1573 -r|--rmdeps) RMDEPS=1 ;;
1574 -R|--repackage) REPKG=1 ;;
1575 --skipinteg) SKIPINTEG=1 ;;
1576 --source) SOURCEONLY=1 ;;
1577 -s|--syncdeps) DEP_BIN=1 ;;
1579 -h|--help) usage; exit 0 ;; # E_OK
1580 -V|--version) version; exit 0 ;; # E_OK
1582 --) OPT_IND=0; shift; break;;
1583 *) usage; exit 1 ;; # E_INVALID_OPTION
1584 esac
1585 shift
1586 done
1588 #preserve environment variables
1589 _PKGDEST=${PKGDEST}
1590 _SRCDEST=${SRCDEST}
1591 _SRCPKGDEST=${SRCPKGDEST}
1593 # default config is makepkg.conf
1594 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1596 # Source the config file; fail if it is not found
1597 if [[ -r $MAKEPKG_CONF ]]; then
1598 source "$MAKEPKG_CONF"
1599 else
1600 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1601 plain "$(gettext "Aborting...")"
1602 exit 1 # $E_CONFIG_ERROR
1605 # Source user-specific makepkg.conf overrides
1606 if [[ -r ~/.makepkg.conf ]]; then
1607 source ~/.makepkg.conf
1610 # set pacman command if not already defined
1611 PACMAN=${PACMAN:-pacman}
1613 # check if messages are to be printed using color
1614 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1615 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1616 ALL_OFF="$(tput sgr0)"
1617 BOLD="$(tput bold)"
1618 BLUE="${BOLD}$(tput setaf 4)"
1619 GREEN="${BOLD}$(tput setaf 2)"
1620 RED="${BOLD}$(tput setaf 1)"
1621 YELLOW="${BOLD}$(tput setaf 3)"
1623 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
1625 # override settings with an environment variable for batch processing
1626 PKGDEST=${_PKGDEST:-$PKGDEST}
1627 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
1628 if [[ ! -w $PKGDEST ]]; then
1629 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
1630 plain "$(gettext "Aborting...")"
1631 exit 1
1634 SRCDEST=${_SRCDEST:-$SRCDEST}
1635 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
1636 if [[ ! -w $SRCDEST ]] ; then
1637 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
1638 plain "$(gettext "Aborting...")"
1639 exit 1
1642 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
1643 SRCPKGDEST=${SRCPKGDEST:-$PKGDEST} #default to $PKGDEST if undefined
1646 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
1647 # The '\\0' is here to prevent gettext from thinking --holdver is an option
1648 error "$(gettext "\\0--holdver and --forcever cannot both be specified" )"
1649 exit 1
1652 if (( CLEANCACHE )); then
1653 #fix flyspray feature request #5223
1654 if [[ -n $SRCDEST && $SRCDEST != $startdir ]]; then
1655 msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST"
1656 echo -n "$(gettext " Are you sure you wish to do this? ")"
1657 echo -n "$(gettext "[y/N]")"
1658 read answer
1659 answer="${answer^^}"
1660 if [[ $answer = $(gettext YES) || $answer = $(gettext Y) ]]; then
1661 rm "$SRCDEST"/*
1662 if (( $? )); then
1663 error "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST"
1664 exit 1
1665 else
1666 # removal worked
1667 msg "$(gettext "Source cache cleaned.")"
1668 exit 0
1670 else
1671 # answer = no
1672 msg "$(gettext "No files have been removed.")"
1673 exit 0
1675 else
1676 # $SRCDEST is $startdir, two possibilities
1677 error "$(gettext "Source destination must be defined in %s.")" "$MAKEPKG_CONF"
1678 plain "$(gettext "In addition, please run makepkg -C outside of your cache directory.")"
1679 exit 1
1683 if (( ! INFAKEROOT )); then
1684 if (( EUID == 0 && ! ASROOT )); then
1685 # Warn those who like to live dangerously.
1686 error "$(gettext "Running makepkg as root is a BAD idea and can cause")"
1687 plain "$(gettext "permanent, catastrophic damage to your system. If you")"
1688 plain "$(gettext "wish to run as root, please use the --asroot option.")"
1689 exit 1 # $E_USER_ABORT
1690 elif (( EUID > 0 && ASROOT )); then
1691 # Warn those who try to use the --asroot option when they are not root
1692 error "$(gettext "The --asroot option is meant for the root user only.")"
1693 plain "$(gettext "Please rerun makepkg without the --asroot flag.")"
1694 exit 1 # $E_USER_ABORT
1695 elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1696 if ! type -p fakeroot >/dev/null; then
1697 error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")"
1698 plain "$(gettext "in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
1699 exit 1
1701 elif (( EUID > 0 )); then
1702 warning "$(gettext "Running makepkg as an unprivileged user will result in non-root")"
1703 plain "$(gettext "ownership of the packaged files. Try using the fakeroot environment by")"
1704 plain "$(gettext "placing 'fakeroot' in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
1705 sleep 1
1707 else
1708 if [[ -z $FAKEROOTKEY ]]; then
1709 error "$(gettext "Do not use the '-F' option. This option is only for use by makepkg.")"
1710 exit 1 # TODO: error code
1714 # check for sudo if we will need it during makepkg execution
1715 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1716 if ! type -p sudo >/dev/null; then
1717 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1721 unset pkgname pkgbase pkgver pkgrel pkgdesc url license groups provides
1722 unset md5sums replaces depends conflicts backup source install changelog build
1723 unset makedepends optdepends options noextract
1725 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
1726 if [[ ! -f $BUILDFILE ]]; then
1727 if [[ -t 0 ]]; then
1728 error "$(gettext "%s does not exist.")" "$BUILDFILE"
1729 exit 1
1730 else
1731 # PKGBUILD passed through a pipe
1732 BUILDFILE=/dev/stdin
1733 source "$BUILDFILE"
1735 else
1736 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
1737 if [[ -n $crlftest ]]; then
1738 error "$(gettext "%s contains CRLF characters and cannot be sourced.")" "$BUILDFILE"
1739 exit 1
1742 if [[ ${BUILDFILE:0:1} != "/" ]]; then
1743 BUILDFILE="$startdir/$BUILDFILE"
1745 source "$BUILDFILE"
1748 if (( GENINTEG )); then
1749 mkdir -p "$srcdir"
1750 chmod a-s "$srcdir"
1751 cd "$srcdir"
1752 download_sources
1753 generate_checksums
1754 exit 0 # $E_OK
1757 # check the PKGBUILD for some basic requirements
1758 check_sanity || exit 1
1760 # We need to run devel_update regardless of whether we are in the fakeroot
1761 # build process so that if the user runs makepkg --forcever manually, we
1762 # 1) output the correct pkgver, and 2) use the correct filename when
1763 # checking if the package file already exists - fixes FS #9194
1764 devel_check
1765 devel_update
1767 if (( ${#pkgname[@]} > 1 )); then
1768 SPLITPKG=1
1771 # test for available PKGBUILD functions
1772 if declare -f build >/dev/null; then
1773 BUILDFUNC=1
1775 if declare -f package >/dev/null; then
1776 PKGFUNC=1
1777 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
1778 SPLITPKG=1
1781 pkgbase=${pkgbase:-${pkgname[0]}}
1783 if [[ -n "${PKGLIST[@]}" ]]; then
1784 unset pkgname
1785 pkgname="${PKGLIST[@]}"
1788 if (( ! SPLITPKG )); then
1789 if [[ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
1790 || -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-any${PKGEXT} ]] \
1791 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
1792 if (( INSTALL )); then
1793 warning "$(gettext "A package has already been built, installing existing package...")"
1794 install_package
1795 exit $?
1796 else
1797 error "$(gettext "A package has already been built. (use -f to overwrite)")"
1798 exit 1
1801 else
1802 allpkgbuilt=1
1803 somepkgbuilt=0
1804 for pkg in ${pkgname[@]}; do
1805 if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
1806 || -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT} ]]; then
1807 somepkgbuilt=1
1808 else
1809 allpkgbuilt=0
1811 done
1812 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
1813 if (( allpkgbuilt )); then
1814 if (( INSTALL )); then
1815 warning "$(gettext "The package group has already been built, installing existing packages...")"
1816 install_package
1817 exit $?
1818 else
1819 error "$(gettext "The package group has already been built. (use -f to overwrite)")"
1820 exit 1
1823 if (( somepkgbuilt )); then
1824 error "$(gettext "Part of the package group has already been built. (use -f to overwrite)")"
1825 exit 1
1828 unset allpkgbuilt somepkgbuilt
1831 # Run the bare minimum in fakeroot
1832 if (( INFAKEROOT )); then
1833 if (( ! SPLITPKG )); then
1834 if (( ! PKGFUNC )); then
1835 if (( ! REPKG )); then
1836 if (( BUILDFUNC )); then
1837 run_build
1838 tidy_install
1840 else
1841 warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
1842 plain "$(gettext "File permissions may not be preserved.")"
1844 else
1845 run_package
1846 tidy_install
1848 create_package
1849 else
1850 for pkg in ${pkgname[@]}; do
1851 pkgdir="$pkgdir/$pkg"
1852 mkdir -p "$pkgdir"
1853 chmod a-s "$pkgdir"
1854 backup_package_variables
1855 run_package $pkg
1856 tidy_install
1857 create_package $pkg
1858 restore_package_variables
1859 pkgdir="${pkgdir%/*}"
1860 done
1863 msg "$(gettext "Leaving fakeroot environment.")"
1864 exit 0 # $E_OK
1867 msg "$(gettext "Making package: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
1869 # if we are creating a source-only package, go no further
1870 if (( SOURCEONLY )); then
1871 if [[ -f $SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT} ]] \
1872 && (( ! FORCE )); then
1873 error "$(gettext "A source package has already been built. (use -f to overwrite)")"
1874 exit 1
1876 create_srcpackage
1877 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
1878 exit 0
1881 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
1882 # no warning message needed for nobuild, repkg
1883 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
1884 warning "$(gettext "Skipping dependency checks.")"
1886 elif type -p "${PACMAN%% *}" >/dev/null; then
1887 if (( RMDEPS )); then
1888 original_pkglist=($(run_pacman -Qq | sort)) # required by remove_dep
1890 deperr=0
1892 msg "$(gettext "Checking Runtime Dependencies...")"
1893 resolve_deps ${depends[@]} || deperr=1
1895 msg "$(gettext "Checking Buildtime Dependencies...")"
1896 resolve_deps ${makedepends[@]} || deperr=1
1898 if (( RMDEPS )); then
1899 current_pkglist=($(run_pacman -Qq | sort)) # required by remove_deps
1902 if (( deperr )); then
1903 error "$(gettext "Could not resolve all dependencies.")"
1904 exit 1
1906 else
1907 warning "$(gettext "%s was not found in PATH; skipping dependency checks.")" "${PACMAN%% *}"
1910 # ensure we have a sane umask set
1911 umask 0022
1913 # get back to our src directory so we can begin with sources
1914 mkdir -p "$srcdir"
1915 chmod a-s "$srcdir"
1916 cd "$srcdir"
1918 if (( NOEXTRACT )); then
1919 warning "$(gettext "Skipping source retrieval -- using existing src/ tree")"
1920 warning "$(gettext "Skipping source integrity checks -- using existing src/ tree")"
1921 warning "$(gettext "Skipping source extraction -- using existing src/ tree")"
1923 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
1924 error "$(gettext "The source directory is empty, there is nothing to build!")"
1925 plain "$(gettext "Aborting...")"
1926 exit 1
1928 elif (( REPKG )); then
1929 if (( ! PKGFUNC && ! SPLITPKG )) \
1930 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
1931 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
1932 plain "$(gettext "Aborting...")"
1933 exit 1
1935 else
1936 download_sources
1937 if (( ! SKIPINTEG )); then
1938 check_checksums
1939 else
1940 warning "$(gettext "Skipping integrity checks.")"
1942 extract_sources
1945 if (( NOBUILD )); then
1946 msg "$(gettext "Sources are ready.")"
1947 exit 0 #E_OK
1948 else
1949 # check for existing pkg directory; don't remove if we are repackaging
1950 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
1951 msg "$(gettext "Removing existing pkg/ directory...")"
1952 rm -rf "$pkgdir"
1954 mkdir -p "$pkgdir"
1955 chmod a-s "$pkgdir"
1956 cd "$startdir"
1958 # if we are root or if fakeroot is not enabled, then we don't use it
1959 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
1960 if (( ! REPKG )); then
1961 devel_update
1962 (( BUILDFUNC )) && run_build
1964 if (( ! SPLITPKG )); then
1965 if (( PKGFUNC )); then
1966 run_package
1967 tidy_install
1968 else
1969 if (( ! REPKG )); then
1970 tidy_install
1971 else
1972 warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
1973 plain "$(gettext "File permissions may not be preserved.")"
1976 create_package
1977 else
1978 for pkg in ${pkgname[@]}; do
1979 pkgdir="$pkgdir/$pkg"
1980 mkdir -p "$pkgdir"
1981 chmod a-s "$pkgdir"
1982 backup_package_variables
1983 run_package $pkg
1984 tidy_install
1985 create_package $pkg
1986 restore_package_variables
1987 pkgdir="${pkgdir%/*}"
1988 done
1990 else
1991 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
1992 devel_update
1993 (( BUILDFUNC )) && run_build
1994 cd "$startdir"
1997 msg "$(gettext "Entering fakeroot environment...")"
1999 if [[ -n $newpkgver ]]; then
2000 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
2001 else
2002 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
2007 msg "$(gettext "Finished making: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
2009 install_package
2011 exit 0 #E_OK
2013 # vim: set ts=2 sw=2 noet: