makepkg: use BUILDFILE rather than BUILDSCRIPT
[pacman-ng.git] / scripts / makepkg.sh.in
blobd9867016d8c4dc641f5f860537cc139af0b11a81
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)" ] && 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) ]; 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) ]; 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 # Don't know what to use to extract this file,
686 # skip to the next file
687 continue;;
688 esac
690 local ret=0
691 msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
692 if [[ $cmd = bsdtar ]]; then
693 $cmd -xf "$file" || ret=$?
694 else
695 rm -f "${file%.*}"
696 $cmd -dcf "$file" > "${file%.*}" || ret=$?
698 if (( ret )); then
699 error "$(gettext "Failed to extract %s")" "$file"
700 plain "$(gettext "Aborting...")"
701 exit 1
703 done
705 if (( EUID == 0 )); then
706 # change perms of all source files to root user & root group
707 chown -R 0:0 "$srcdir"
711 error_function() {
712 if [[ -p $logpipe ]]; then
713 rm "$logpipe"
715 # first exit all subshells, then print the error
716 if (( ! BASH_SUBSHELL )); then
717 plain "$(gettext "Aborting...")"
718 remove_deps
720 exit 2 # $E_BUILD_FAILED
723 run_function() {
724 if [[ -z $1 ]]; then
725 return 1
727 pkgfunc="$1"
729 # clear user-specified makeflags if requested
730 if [[ $(check_option makeflags) = "n" ]]; then
731 MAKEFLAGS=""
734 msg "$(gettext "Starting %s()...")" "$pkgfunc"
735 cd "$srcdir"
737 # ensure all necessary build variables are exported
738 export CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
739 # save our shell options so pkgfunc() can't override what we need
740 local shellopts=$(shopt -p)
742 local ret=0
743 if (( LOGGING )); then
744 BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log"
745 if [[ -f $BUILDLOG ]]; then
746 local i=1
747 while true; do
748 if [[ -f $BUILDLOG.$i ]]; then
749 i=$(($i +1))
750 else
751 break
753 done
754 mv "$BUILDLOG" "$BUILDLOG.$i"
757 # ensure overridden package variables survive tee with split packages
758 logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX")
759 mknod "$logpipe" p
760 exec 3>&1
761 tee "$BUILDLOG" < "$logpipe" &
762 exec 1>"$logpipe" 2>"$logpipe"
763 restoretrap=$(trap -p ERR)
764 trap 'error_function' ERR
765 $pkgfunc 2>&1
766 eval $restoretrap
767 sync
768 exec 1>&3 2>&3 3>&-
769 rm "$logpipe"
770 else
771 restoretrap=$(trap -p ERR)
772 trap 'error_function' ERR
773 $pkgfunc 2>&1
774 eval $restoretrap
776 # reset our shell options
777 eval "$shellopts"
780 run_build() {
781 # use distcc if it is requested (check buildenv and PKGBUILD opts)
782 if [[ $(check_buildenv distcc) = "y" && $(check_option distcc) != "n" ]]; then
783 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr/lib/distcc/bin:$PATH"
784 export DISTCC_HOSTS
785 elif [[ $(check_option distcc) = "n" ]]; then
786 # if it is not wanted, clear the makeflags too
787 MAKEFLAGS=""
790 # use ccache if it is requested (check buildenv and PKGBUILD opts)
791 if [[ $(check_buildenv ccache) = "y" && $(check_option ccache) != "n" ]]; then
792 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr/lib/ccache/bin:$PATH"
795 run_function "build"
798 run_package() {
799 if [[ -z $1 ]]; then
800 pkgfunc="package"
801 else
802 pkgfunc="package_$1"
805 run_function "$pkgfunc"
808 tidy_install() {
809 cd "$pkgdir"
810 msg "$(gettext "Tidying install...")"
812 if [[ $(check_option docs) = "n" && -n ${DOC_DIRS[*]} ]]; then
813 msg2 "$(gettext "Removing doc files...")"
814 rm -rf ${DOC_DIRS[@]}
817 if [[ $(check_option purge) = "y" && -n ${PURGE_TARGETS[*]} ]]; then
818 msg2 "$(gettext "Purging other files...")"
819 local pt
820 for pt in "${PURGE_TARGETS[@]}"; do
821 if [[ ${pt} = ${pt//\/} ]]; then
822 find . -type f -name "${pt}" -exec rm -f -- '{}' \;
823 else
824 rm -f ${pt}
826 done
829 if [[ $(check_option zipman) = "y" && -n ${MAN_DIRS[*]} ]]; then
830 msg2 "$(gettext "Compressing man and info pages...")"
831 local manpage ext file link hardlinks hl
832 find ${MAN_DIRS[@]} -type f 2>/dev/null |
833 while read manpage ; do
834 ext="${manpage##*.}"
835 file="${manpage##*/}"
836 if [[ $ext != gz && $ext != bz2 ]]; then
837 # update symlinks to this manpage
838 find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null |
839 while read link ; do
840 rm -f "$link"
841 ln -sf "${file}.gz" "${link}.gz"
842 done
844 # check file still exists (potentially already compressed due to hardlink)
845 if [[ -f ${manpage} ]]; then
846 # find hard links and remove them
847 # the '|| true' part keeps the script from bailing if find returned an
848 # error, such as when one of the man directories doesn't exist
849 hardlinks="$(find ${MAN_DIRS[@]} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
850 for hl in ${hardlinks}; do
851 rm -f "${hl}";
852 done
853 # compress the original
854 gzip -9 "$manpage"
855 # recreate hard links removed earlier
856 for hl in ${hardlinks}; do
857 ln "${manpage}.gz" "${hl}.gz"
858 chmod 644 ${hl}.gz
859 done
862 done
865 if [[ $(check_option strip) = y && -n ${STRIP_DIRS[*]} ]]; then
866 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
867 local binary
868 find ${STRIP_DIRS[@]} -type f -perm -u+w 2>/dev/null | while read binary ; do
869 case "$(file -bi "$binary")" in
870 *application/x-sharedlib*) # Libraries (.so)
871 /usr/bin/strip $STRIP_SHARED "$binary";;
872 *application/x-archive*) # Libraries (.a)
873 /usr/bin/strip $STRIP_STATIC "$binary";;
874 *application/x-executable*) # Binaries
875 /usr/bin/strip $STRIP_BINARIES "$binary";;
876 esac
877 done
880 if [[ $(check_option libtool) = "n" ]]; then
881 msg2 "$(gettext "Removing libtool .la files...")"
882 find . ! -type d -name "*.la" -exec rm -f -- '{}' \;
885 if [[ $(check_option emptydirs) = "n" ]]; then
886 msg2 "$(gettext "Removing empty directories...")"
887 find . -depth -type d -empty -delete
891 write_pkginfo() {
892 local builddate=$(date -u "+%s")
893 if [[ -n $PACKAGER ]]; then
894 local packager="$PACKAGER"
895 else
896 local packager="Unknown Packager"
898 local size="$(du -sk)"
899 size="$(( ${size%%[^0-9]*} * 1024 ))"
901 msg2 "$(gettext "Generating .PKGINFO file...")"
902 echo "# Generated by makepkg $myver" >.PKGINFO
903 if (( INFAKEROOT )); then
904 echo "# using $(fakeroot -v)" >>.PKGINFO
906 echo "# $(LC_ALL=C date -u)" >>.PKGINFO
907 echo "pkgname = $1" >>.PKGINFO
908 (( SPLITPKG )) && echo pkgbase = $pkgbase >>.PKGINFO
909 echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
910 echo "pkgdesc = $pkgdesc" >>.PKGINFO
911 echo "url = $url" >>.PKGINFO
912 echo "builddate = $builddate" >>.PKGINFO
913 echo "packager = $packager" >>.PKGINFO
914 echo "size = $size" >>.PKGINFO
915 echo "arch = $PKGARCH" >>.PKGINFO
916 if [[ $(check_option force) = "y" ]]; then
917 echo "force = true" >> .PKGINFO
920 local it
921 for it in "${license[@]}"; do
922 echo "license = $it" >>.PKGINFO
923 done
924 for it in "${replaces[@]}"; do
925 echo "replaces = $it" >>.PKGINFO
926 done
927 for it in "${groups[@]}"; do
928 echo "group = $it" >>.PKGINFO
929 done
930 for it in "${depends[@]}"; do
931 echo "depend = $it" >>.PKGINFO
932 done
933 for it in "${optdepends[@]}"; do
934 echo "optdepend = $it" >>.PKGINFO
935 done
936 for it in "${conflicts[@]}"; do
937 echo "conflict = $it" >>.PKGINFO
938 done
939 for it in "${provides[@]}"; do
940 echo "provides = $it" >>.PKGINFO
941 done
942 for it in "${backup[@]}"; do
943 echo "backup = $it" >>.PKGINFO
944 done
945 for it in "${packaging_options[@]}"; do
946 local ret="$(check_option $it)"
947 if [[ $ret != "?" ]]; then
948 if [[ $ret = y ]]; then
949 echo "makepkgopt = $it" >>.PKGINFO
950 else
951 echo "makepkgopt = !$it" >>.PKGINFO
954 done
956 # TODO maybe remove this at some point
957 # warn if license array is not present or empty
958 if [[ -z $license ]]; then
959 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
960 plain "$(gettext "Example for GPL\'ed software: license=('GPL').")"
964 check_package() {
965 cd "$pkgdir"
967 # check existence of backup files
968 local file
969 for file in "${backup[@]}"; do
970 if [[ ! -f $file ]]; then
971 warning "$(gettext "Invalid backup entry : %s")" "$file"
973 done
975 # check for references to the build directory
976 if grep -R "${srcdir}" "${pkgdir}" &>/dev/null; then
977 warning "$(gettext "Package contains reference to %s")" "\$srcdir"
981 create_package() {
982 if [[ ! -d $pkgdir ]]; then
983 error "$(gettext "Missing pkg/ directory.")"
984 plain "$(gettext "Aborting...")"
985 exit 1 # $E_MISSING_PKGDIR
988 check_package
990 cd "$pkgdir"
991 msg "$(gettext "Creating package...")"
993 if [[ -z $1 ]]; then
994 nameofpkg="$pkgname"
995 else
996 nameofpkg="$1"
999 if [[ $arch = "any" ]]; then
1000 PKGARCH="any"
1001 else
1002 PKGARCH=$CARCH
1005 write_pkginfo $nameofpkg
1007 local comp_files=".PKGINFO"
1009 # check for an install script
1010 if [[ -n $install ]]; then
1011 msg2 "$(gettext "Adding install script...")"
1012 cp "$startdir/$install" .INSTALL
1013 chmod 644 .INSTALL
1014 comp_files="$comp_files .INSTALL"
1017 # do we have a changelog?
1018 if [[ -n $changelog ]]; then
1019 msg2 "$(gettext "Adding package changelog...")"
1020 cp "$startdir/$changelog" .CHANGELOG
1021 chmod 644 .CHANGELOG
1022 comp_files="$comp_files .CHANGELOG"
1025 # tar it up
1026 msg2 "$(gettext "Compressing package...")"
1028 case "$PKGEXT" in
1029 *tar.gz) EXT=${PKGEXT%.gz} ;;
1030 *tar.bz2) EXT=${PKGEXT%.bz2} ;;
1031 *tar.xz) EXT=${PKGEXT%.xz} ;;
1032 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1033 "$PKGEXT" ; EXT=$PKGEXT ;;
1034 esac
1035 local tar_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${EXT}"
1036 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 bsdtar -cf - $comp_files * > "$tar_file" || ret=$?
1044 shopt -u nullglob
1046 if (( ! ret )); then
1047 case "$PKGEXT" in
1048 *tar.gz) gzip -f -n "$tar_file" ;;
1049 *tar.bz2) bzip2 -f "$tar_file" ;;
1050 *tar.xz) xz -z -f "$tar_file" ;;
1051 esac
1052 ret=$?
1055 if (( ret )); then
1056 error "$(gettext "Failed to create package file.")"
1057 exit 1 # TODO: error code
1060 if (( ! ret )) && [[ "$PKGDEST" != "${startdir}" ]]; then
1061 ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1062 ret=$?
1065 if (( ret )); then
1066 warning "$(gettext "Failed to create symlink to package file.")"
1070 create_srcpackage() {
1071 cd "$startdir"
1073 # Get back to our src directory so we can begin with sources.
1074 mkdir -p "$srcdir"
1075 chmod a-s "$srcdir"
1076 cd "$srcdir"
1077 if (( ! SKIPINTEG || SOURCEONLY == 2 )); then
1078 download_sources
1080 if (( ! SKIPINTEG )); then
1081 # We can only check checksums if we have all files.
1082 check_checksums
1083 else
1084 warning "$(gettext "Skipping integrity checks.")"
1086 cd "$startdir"
1088 msg "$(gettext "Creating source package...")"
1089 local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
1090 mkdir "${srclinks}"/${pkgbase}
1092 msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
1093 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
1095 local file
1096 for file in "${source[@]}"; do
1097 if [[ -f $file ]]; then
1098 msg2 "$(gettext "Adding %s...")" "$file"
1099 ln -s "${startdir}/$file" "$srclinks/$pkgbase"
1100 elif (( SOURCEONLY == 2 )); then
1101 local absfile=$(get_filepath "$file") || missing_source_file "$file"
1102 msg2 "$(gettext "Adding %s...")" "${absfile##*/}"
1103 ln -s "$absfile" "$srclinks/$pkgbase"
1105 done
1107 local i
1108 for i in 'changelog' 'install'; do
1109 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDSCRIPT")
1110 local file
1111 for file in $filelist; do
1112 # evaluate any bash variables used
1113 eval file=${file}
1114 if [[ ! -f "${srclinks}/${pkgbase}/$file" ]]; then
1115 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
1116 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
1118 done
1119 done
1121 local TAR_OPT
1122 case "$SRCEXT" in
1123 *tar.gz) TAR_OPT="z" ;;
1124 *tar.bz2) TAR_OPT="j" ;;
1125 *tar.xz) TAR_OPT="J" ;;
1126 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
1127 "$SRCEXT" ;;
1128 esac
1130 local pkg_file="$SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT}"
1132 # tar it up
1133 msg2 "$(gettext "Compressing source package...")"
1134 cd "${srclinks}"
1135 if ! bsdtar -c${TAR_OPT}Lf "$pkg_file" ${pkgbase}; then
1136 error "$(gettext "Failed to create source package file.")"
1137 exit 1 # TODO: error code
1139 cd "${startdir}"
1140 rm -rf "${srclinks}"
1143 install_package() {
1144 (( ! INSTALL )) && return
1146 if (( ! SPLITPKG )); then
1147 msg "$(gettext "Installing package %s with %s -U...")" "$pkgname" "$PACMAN"
1148 else
1149 msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN"
1152 local pkglist
1153 for pkg in ${pkgname[@]}; do
1154 if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then
1155 pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"
1156 else
1157 pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}"
1159 done
1161 if ! run_pacman -U $pkglist; then
1162 warning "$(gettext "Failed to install built package(s).")"
1163 return 0
1167 check_sanity() {
1168 # check for no-no's in the build script
1169 if [[ -z $pkgname ]]; then
1170 error "$(gettext "%s is not allowed to be empty.")" "pkgname"
1171 return 1
1173 if [[ -z $pkgver ]]; then
1174 error "$(gettext "%s is not allowed to be empty.")" "pkgver"
1175 return 1
1177 if [[ -z $pkgrel ]]; then
1178 error "$(gettext "%s is not allowed to be empty.")" "pkgrel"
1179 return 1
1182 local name
1183 for name in "${pkgname[@]}"; do
1184 if [[ ${name:0:1} = "-" ]]; then
1185 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
1186 return 1
1188 done
1190 if [[ ${pkgbase:0:1} = "-" ]]; then
1191 error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
1192 return 1
1194 if [[ $pkgver != ${pkgver//-/} ]]; then
1195 error "$(gettext "%s is not allowed to contain hyphens.")" "pkgver"
1196 return 1
1198 if [[ $pkgrel != ${pkgrel//-/} ]]; then
1199 error "$(gettext "%s is not allowed to contain hyphens.")" "pkgrel"
1200 return 1
1203 if [[ $arch != 'any' ]]; then
1204 if ! in_array $CARCH ${arch[@]}; then
1205 if (( ! IGNOREARCH )); then
1206 error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
1207 plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
1208 plain "$(gettext "such as arch=('%s').")" "$CARCH"
1209 return 1
1214 local provide
1215 for provide in ${provides[@]}; do
1216 if [[ $provide != ${provide//</} || $provide != ${provide//>/} ]]; then
1217 error "$(gettext "Provides array cannot contain comparison (< or >) operators.")"
1218 return 1
1220 done
1222 local file
1223 for file in "${backup[@]}"; do
1224 if [[ ${file:0:1} = "/" ]]; then
1225 error "$(gettext "Invalid backup entry : %s")" "$file"
1226 return 1
1228 done
1230 local optdepend
1231 for optdepend in "${optdepends[@]}"; do
1232 pkg=${optdepend%%:*}
1233 if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]*$ ]]; then
1234 error "$(gettext "Invalid syntax for optdepend : '%s'")" "$optdepend"
1236 done
1238 local i
1239 for i in 'changelog' 'install'; do
1240 local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
1241 local file
1242 for file in $filelist; do
1243 # evaluate any bash variables used
1244 eval file=${file}
1245 if [[ ! -f $file ]]; then
1246 error "$(gettext "%s file (%s) does not exist.")" "${i^}" "$file"
1247 return 1
1249 done
1250 done
1252 local valid_options=1
1253 local opt known kopt
1254 for opt in ${options[@]}; do
1255 known=0
1256 # check if option matches a known option or its inverse
1257 for kopt in ${packaging_options[@]} ${other_options[@]}; do
1258 if [[ ${opt} = ${kopt} || ${opt} = "!${kopt}" ]]; then
1259 known=1
1261 done
1262 if (( ! known )); then
1263 error "$(gettext "options array contains unknown option '%s'")" "$opt"
1264 valid_options=0
1266 done
1267 if (( ! valid_options )); then
1268 return 1
1271 if (( ${#pkgname[@]} > 1 )); then
1272 for pkg in ${pkgname[@]}; do
1273 if [ "$(type -t package_${pkg})" != "function" ]; then
1274 error "$(gettext "missing package function for split package '%s'")" "$pkg"
1275 return 1
1277 done
1280 if [[ -n "${PKGLIST[@]}" ]]; then
1281 for pkg in ${PKGLIST[@]}; do
1282 if ! in_array $pkg ${pkgname[@]}; then
1283 error "$(gettext "requested package %s is not provided in %s")" "$pkg" "$BUILDFILE"
1284 return 1
1286 done
1289 return 0
1292 devel_check() {
1293 newpkgver=""
1295 # Do not update pkgver if --holdver is set, when building a source package, repackaging,
1296 # reading PKGBUILD from pipe (-f), or if we cannot write to the file (-w)
1297 if (( HOLDVER || SOURCEONLY || REPKG )) \
1298 || [[ ! -f $BUILDFILE || ! -w $BUILDFILE ]]; then
1299 return
1302 if [[ -z $FORCE_VER ]]; then
1303 # Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
1304 # This will only be used on the first call to makepkg; subsequent
1305 # calls to makepkg via fakeroot will explicitly pass the version
1306 # number to avoid having to determine the version number twice.
1307 # Also do a brief check to make sure we have the VCS tool available.
1308 oldpkgver=$pkgver
1309 if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then
1310 [ $(type -p darcs) ] || return 0
1311 msg "$(gettext "Determining latest darcs revision...")"
1312 newpkgver=$(date +%Y%m%d)
1313 elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then
1314 [ $(type -p cvs) ] || return 0
1315 msg "$(gettext "Determining latest cvs revision...")"
1316 newpkgver=$(date +%Y%m%d)
1317 elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then
1318 [ $(type -p git) ] || return 0
1319 msg "$(gettext "Determining latest git revision...")"
1320 newpkgver=$(date +%Y%m%d)
1321 elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then
1322 [ $(type -p svn) ] || return 0
1323 msg "$(gettext "Determining latest svn revision...")"
1324 newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')
1325 elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then
1326 [ $(type -p bzr) ] || return 0
1327 msg "$(gettext "Determining latest bzr revision...")"
1328 newpkgver=$(bzr revno ${_bzrtrunk})
1329 elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then
1330 [ $(type -p hg) ] || return 0
1331 msg "$(gettext "Determining latest hg revision...")"
1332 if [[ -d ./src/$_hgrepo ]] ; then
1333 cd ./src/$_hgrepo
1334 hg pull
1335 hg update
1336 else
1337 [[ ! -d ./src/ ]] && mkdir ./src/
1338 hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
1339 cd ./src/$_hgrepo
1341 newpkgver=$(hg tip --template "{rev}")
1342 cd ../../
1345 if [[ -n $newpkgver ]]; then
1346 msg2 "$(gettext "Version found: %s")" "$newpkgver"
1349 else
1350 # Version number retrieved from fakeroot->makepkg argument
1351 newpkgver=$FORCE_VER
1355 devel_update() {
1356 # This is lame, but if we're wanting to use an updated pkgver for
1357 # retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
1358 # the new pkgver and then re-source it. This is the most robust
1359 # method for dealing with PKGBUILDs that use, e.g.:
1361 # pkgver=23
1362 # ...
1363 # _foo=pkgver
1365 if [[ -n $newpkgver ]]; then
1366 if [[ $newpkgver != $pkgver ]]; then
1367 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
1368 @SEDINPLACE@ "s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
1369 @SEDINPLACE@ "s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
1370 source "$BUILDFILE"
1376 backup_package_variables() {
1377 for var in ${splitpkg_overrides[@]}; do
1378 indirect="${var}_backup"
1379 eval "${indirect}=(\"\${$var[@]}\")"
1380 done
1383 restore_package_variables() {
1384 for var in ${splitpkg_overrides[@]}; do
1385 indirect="${var}_backup"
1386 if [[ -n ${!indirect} ]]; then
1387 eval "${var}=(\"\${$indirect[@]}\")"
1388 else
1389 unset ${var}
1391 done
1394 # getopt like parser
1395 parse_options() {
1396 local short_options=$1; shift;
1397 local long_options=$1; shift;
1398 local ret=0;
1399 local unused_options=""
1401 while [[ -n $1 ]]; do
1402 if [[ ${1:0:2} = '--' ]]; then
1403 if [[ -n ${1:2} ]]; then
1404 local match=""
1405 for i in ${long_options//,/ }; do
1406 if [[ ${1:2} = ${i//:} ]]; then
1407 match=$i
1408 break
1410 done
1411 if [[ -n $match ]]; then
1412 if [[ ${1:2} = $match ]]; then
1413 printf ' %s' "$1"
1414 else
1415 if [[ -n $2 ]]; then
1416 printf ' %s' "$1"
1417 shift
1418 printf " '%s'" "$1"
1419 else
1420 echo "makepkg: option '$1' $(gettext "requires an argument")" >&2
1421 ret=1
1424 else
1425 echo "makepkg: $(gettext "unrecognized option") '$1'" >&2
1426 ret=1
1428 else
1429 shift
1430 break
1432 elif [[ ${1:0:1} = '-' ]]; then
1433 for ((i=1; i<${#1}; i++)); do
1434 if [[ $short_options =~ ${1:i:1} ]]; then
1435 if [[ $short_options =~ "${1:i:1}:" ]]; then
1436 if [[ -n ${1:$i+1} ]]; then
1437 printf ' -%s' "${1:i:1}"
1438 printf " '%s'" "${1:$i+1}"
1439 else
1440 if [[ -n $2 ]]; then
1441 printf ' -%s' "${1:i:1}"
1442 shift
1443 printf " '%s'" "${1}"
1444 else
1445 echo "makepkg: option $(gettext "requires an argument") -- '${1:i:1}'" >&2
1446 ret=1
1449 break
1450 else
1451 printf ' -%s' "${1:i:1}"
1453 else
1454 echo "makepkg: $(gettext "invalid option") -- '${1:i:1}'" >&2
1455 ret=1
1457 done
1458 else
1459 unused_options="${unused_options} '$1'"
1461 shift
1462 done
1464 printf " --"
1465 if [[ -n $unused_options ]]; then
1466 for i in ${unused_options[@]}; do
1467 printf ' %s' "$i"
1468 done
1470 if [[ -n $1 ]]; then
1471 while [[ -n $1 ]]; do
1472 printf " '%s'" "${1}"
1473 shift
1474 done
1476 printf "\n"
1478 return $ret
1481 usage() {
1482 printf "makepkg (pacman) %s\n" "$myver"
1483 echo
1484 printf "$(gettext "Usage: %s [options]")\n" "$0"
1485 echo
1486 echo "$(gettext "Options:")"
1487 printf "$(gettext " -A, --ignorearch Ignore incomplete arch field in %s")\n" "$BUILDSCRIPT"
1488 echo "$(gettext " -c, --clean Clean up work files after build")"
1489 echo "$(gettext " -C, --cleancache Clean up source files from the cache")"
1490 echo "$(gettext " -d, --nodeps Skip all dependency checks")"
1491 echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")"
1492 echo "$(gettext " -f, --force Overwrite existing package")"
1493 echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
1494 echo "$(gettext " -h, --help This help")"
1495 echo "$(gettext " -i, --install Install package after successful build")"
1496 echo "$(gettext " -L, --log Log package build process")"
1497 echo "$(gettext " -m, --nocolor Disable colorized output messages")"
1498 echo "$(gettext " -o, --nobuild Download and extract files only")"
1499 printf "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
1500 echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
1501 echo "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")"
1502 echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")"
1503 echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")"
1504 echo "$(gettext " --asroot Allow makepkg to run as root user")"
1505 printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
1506 echo "$(gettext " --holdver Prevent automatic version bumping for development PKGBUILDs")"
1507 echo "$(gettext " --pkg <list> Only build listed packages from a split package")"
1508 echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")"
1509 echo "$(gettext " --source Generate a source-only tarball without downloaded sources")"
1510 echo
1511 echo "$(gettext "These options can be passed to pacman:")"
1512 echo
1513 echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
1514 echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
1515 echo
1516 printf "$(gettext "If -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT"
1517 echo
1520 version() {
1521 printf "makepkg (pacman) %s\n" "$myver"
1522 printf "$(gettext "\
1523 Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\
1524 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
1525 This is free software; see the source for copying conditions.\n\
1526 There is NO WARRANTY, to the extent permitted by law.\n")"
1529 # PROGRAM START
1531 # determine whether we have gettext; make it a no-op if we do not
1532 if [ ! $(type -t gettext) ]; then
1533 gettext() {
1534 echo "$@"
1538 ARGLIST=("$@")
1540 # Parse Command Line Options.
1541 OPT_SHORT="AcCdefFghiLmop:rRsV"
1542 OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps"
1543 OPT_LONG="$OPT_LONG,noextract,force,forcever:,geninteg,help,holdver"
1544 OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg"
1545 OPT_LONG="$OPT_LONG,source,syncdeps,version,config:"
1546 # Pacman Options
1547 OPT_LONG="$OPT_LONG,noconfirm,noprogressbar"
1548 OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
1549 if [[ $OPT_TEMP = *'PARSE_OPTIONS FAILED'* ]]; then
1550 # This is a small hack to stop the script bailing with 'set -e'
1551 echo; usage; exit 1 # E_INVALID_OPTION;
1553 eval set -- "$OPT_TEMP"
1554 unset OPT_SHORT OPT_LONG OPT_TEMP
1556 while true; do
1557 case "$1" in
1558 # Pacman Options
1559 --noconfirm) PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;;
1560 --noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;;
1562 # Makepkg Options
1563 --allsource) SOURCEONLY=2 ;;
1564 --asroot) ASROOT=1 ;;
1565 -A|--ignorearch) IGNOREARCH=1 ;;
1566 -c|--clean) CLEANUP=1 ;;
1567 -C|--cleancache) CLEANCACHE=1 ;;
1568 --config) shift; MAKEPKG_CONF=$1 ;;
1569 -d|--nodeps) NODEPS=1 ;;
1570 -e|--noextract) NOEXTRACT=1 ;;
1571 -f|--force) FORCE=1 ;;
1572 #hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
1573 --forcever) shift; FORCE_VER=$1;;
1574 -F) INFAKEROOT=1 ;;
1575 -g|--geninteg) GENINTEG=1 ;;
1576 --holdver) HOLDVER=1 ;;
1577 -i|--install) INSTALL=1 ;;
1578 -L|--log) LOGGING=1 ;;
1579 -m|--nocolor) USE_COLOR='n' ;;
1580 -o|--nobuild) NOBUILD=1 ;;
1581 -p) shift; BUILDFILE=$1 ;;
1582 --pkg) shift; PKGLIST=$1 ;;
1583 -r|--rmdeps) RMDEPS=1 ;;
1584 -R|--repackage) REPKG=1 ;;
1585 --skipinteg) SKIPINTEG=1 ;;
1586 --source) SOURCEONLY=1 ;;
1587 -s|--syncdeps) DEP_BIN=1 ;;
1589 -h|--help) usage; exit 0 ;; # E_OK
1590 -V|--version) version; exit 0 ;; # E_OK
1592 --) OPT_IND=0; shift; break;;
1593 *) usage; exit 1 ;; # E_INVALID_OPTION
1594 esac
1595 shift
1596 done
1598 #preserve environment variables
1599 _PKGDEST=${PKGDEST}
1600 _SRCDEST=${SRCDEST}
1601 _SRCPKGDEST=${SRCPKGDEST}
1603 # default config is makepkg.conf
1604 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
1606 # Source the config file; fail if it is not found
1607 if [[ -r $MAKEPKG_CONF ]]; then
1608 source "$MAKEPKG_CONF"
1609 else
1610 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
1611 plain "$(gettext "Aborting...")"
1612 exit 1 # $E_CONFIG_ERROR
1615 # Source user-specific makepkg.conf overrides
1616 if [[ -r ~/.makepkg.conf ]]; then
1617 source ~/.makepkg.conf
1620 # set pacman command if not already defined
1621 PACMAN=${PACMAN:-pacman}
1623 # check if messages are to be printed using color
1624 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
1625 if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then
1626 ALL_OFF="$(tput sgr0)"
1627 BOLD="$(tput bold)"
1628 BLUE="${BOLD}$(tput setaf 4)"
1629 GREEN="${BOLD}$(tput setaf 2)"
1630 RED="${BOLD}$(tput setaf 1)"
1631 YELLOW="${BOLD}$(tput setaf 3)"
1633 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
1635 # override settings with an environment variable for batch processing
1636 PKGDEST=${_PKGDEST:-$PKGDEST}
1637 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
1638 if [[ ! -w $PKGDEST ]]; then
1639 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
1640 plain "$(gettext "Aborting...")"
1641 exit 1
1644 SRCDEST=${_SRCDEST:-$SRCDEST}
1645 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
1646 if [[ ! -w $SRCDEST ]] ; then
1647 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
1648 plain "$(gettext "Aborting...")"
1649 exit 1
1652 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
1653 SRCPKGDEST=${SRCPKGDEST:-$PKGDEST} #default to $PKGDEST if undefined
1656 if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
1657 # The '\\0' is here to prevent gettext from thinking --holdver is an option
1658 error "$(gettext "\\0--holdver and --forcever cannot both be specified" )"
1659 exit 1
1662 if (( CLEANCACHE )); then
1663 #fix flyspray feature request #5223
1664 if [[ -n $SRCDEST && $SRCDEST != $startdir ]]; then
1665 msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST"
1666 echo -n "$(gettext " Are you sure you wish to do this? ")"
1667 echo -n "$(gettext "[y/N]")"
1668 read answer
1669 answer="${answer^^}"
1670 if [[ $answer = $(gettext YES) || $answer = $(gettext Y) ]]; then
1671 rm "$SRCDEST"/*
1672 if (( $? )); then
1673 error "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST"
1674 exit 1
1675 else
1676 # removal worked
1677 msg "$(gettext "Source cache cleaned.")"
1678 exit 0
1680 else
1681 # answer = no
1682 msg "$(gettext "No files have been removed.")"
1683 exit 0
1685 else
1686 # $SRCDEST is $startdir, two possibilities
1687 error "$(gettext "Source destination must be defined in %s.")" "$MAKEPKG_CONF"
1688 plain "$(gettext "In addition, please run makepkg -C outside of your cache directory.")"
1689 exit 1
1693 if (( ! INFAKEROOT )); then
1694 if (( EUID == 0 && ! ASROOT )); then
1695 # Warn those who like to live dangerously.
1696 error "$(gettext "Running makepkg as root is a BAD idea and can cause")"
1697 plain "$(gettext "permanent, catastrophic damage to your system. If you")"
1698 plain "$(gettext "wish to run as root, please use the --asroot option.")"
1699 exit 1 # $E_USER_ABORT
1700 elif (( EUID > 0 && ASROOT )); then
1701 # Warn those who try to use the --asroot option when they are not root
1702 error "$(gettext "The --asroot option is meant for the root user only.")"
1703 plain "$(gettext "Please rerun makepkg without the --asroot flag.")"
1704 exit 1 # $E_USER_ABORT
1705 elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then
1706 if [ ! $(type -p fakeroot) ]; then
1707 error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")"
1708 plain "$(gettext "in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
1709 exit 1
1711 elif (( EUID > 0 )); then
1712 warning "$(gettext "Running makepkg as an unprivileged user will result in non-root")"
1713 plain "$(gettext "ownership of the packaged files. Try using the fakeroot environment by")"
1714 plain "$(gettext "placing 'fakeroot' in the BUILDENV array in %s.")" "$MAKEPKG_CONF"
1715 sleep 1
1717 else
1718 if [[ -z $FAKEROOTKEY ]]; then
1719 error "$(gettext "Do not use the '-F' option. This option is only for use by makepkg.")"
1720 exit 1 # TODO: error code
1724 # check for sudo if we will need it during makepkg execution
1725 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
1726 if [ ! "$(type -p sudo)" ]; then
1727 warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"
1731 unset pkgname pkgbase pkgver pkgrel pkgdesc url license groups provides
1732 unset md5sums replaces depends conflicts backup source install changelog build
1733 unset makedepends optdepends options noextract
1735 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
1736 if [[ ! -f $BUILDFILE ]]; then
1737 if [[ -t 0 ]]; then
1738 error "$(gettext "%s does not exist.")" "$BUILDFILE"
1739 exit 1
1740 else
1741 # PKGBUILD passed through a pipe
1742 BUILDFILE=/dev/stdin
1743 source "$BUILDFILE"
1745 else
1746 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
1747 if [[ -n $crlftest ]]; then
1748 error "$(gettext "%s contains CRLF characters and cannot be sourced.")" "$BUILDFILE"
1749 exit 1
1752 if [[ ${BUILDFILE:0:1} != "/" ]]; then
1753 BUILDFILE="$startdir/$BUILDFILE"
1755 source "$BUILDFILE"
1758 if (( GENINTEG )); then
1759 mkdir -p "$srcdir"
1760 chmod a-s "$srcdir"
1761 cd "$srcdir"
1762 download_sources
1763 generate_checksums
1764 exit 0 # $E_OK
1767 # check the PKGBUILD for some basic requirements
1768 check_sanity || exit 1
1770 # We need to run devel_update regardless of whether we are in the fakeroot
1771 # build process so that if the user runs makepkg --forcever manually, we
1772 # 1) output the correct pkgver, and 2) use the correct filename when
1773 # checking if the package file already exists - fixes FS #9194
1774 devel_check
1775 devel_update
1777 if (( ${#pkgname[@]} > 1 )); then
1778 SPLITPKG=1
1781 # test for available PKGBUILD functions
1782 # The exclamation mark is required here to avoid triggering the ERR trap when
1783 # a tested function does not exist.
1784 if [[ $(! type -t build) = "function" ]]; then
1785 BUILDFUNC=1
1787 if [ "$(type -t package)" = "function" ]; then
1788 PKGFUNC=1
1789 elif [ $SPLITPKG -eq 0 -a "$(type -t package_${pkgname})" = "function" ]; then
1790 SPLITPKG=1
1793 pkgbase=${pkgbase:-${pkgname[0]}}
1795 if [[ -n "${PKGLIST[@]}" ]]; then
1796 unset pkgname
1797 pkgname="${PKGLIST[@]}"
1800 if (( ! SPLITPKG )); then
1801 if [[ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
1802 || -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-any${PKGEXT} ]] \
1803 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
1804 if (( INSTALL )); then
1805 warning "$(gettext "A package has already been built, installing existing package...")"
1806 install_package
1807 exit $?
1808 else
1809 error "$(gettext "A package has already been built. (use -f to overwrite)")"
1810 exit 1
1813 else
1814 allpkgbuilt=1
1815 somepkgbuilt=0
1816 for pkg in ${pkgname[@]}; do
1817 if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \
1818 || -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT} ]]; then
1819 somepkgbuilt=1
1820 else
1821 allpkgbuilt=0
1823 done
1824 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
1825 if (( allpkgbuilt )); then
1826 if (( INSTALL )); then
1827 warning "$(gettext "The package group has already been built, installing existing packages...")"
1828 install_package
1829 exit $?
1830 else
1831 error "$(gettext "The package group has already been built. (use -f to overwrite)")"
1832 exit 1
1835 if (( somepkgbuilt )); then
1836 error "$(gettext "Part of the package group has already been built. (use -f to overwrite)")"
1837 exit 1
1840 unset allpkgbuilt somepkgbuilt
1843 # Run the bare minimum in fakeroot
1844 if (( INFAKEROOT )); then
1845 if (( ! SPLITPKG )); then
1846 if (( ! PKGFUNC )); then
1847 if (( ! REPKG )); then
1848 if (( BUILDFUNC )); then
1849 run_build
1850 tidy_install
1852 else
1853 warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
1854 plain "$(gettext "File permissions may not be preserved.")"
1856 else
1857 run_package
1858 tidy_install
1860 create_package
1861 else
1862 for pkg in ${pkgname[@]}; do
1863 pkgdir="$pkgdir/$pkg"
1864 mkdir -p "$pkgdir"
1865 chmod a-s "$pkgdir"
1866 backup_package_variables
1867 run_package $pkg
1868 tidy_install
1869 create_package $pkg
1870 restore_package_variables
1871 pkgdir="${pkgdir%/*}"
1872 done
1875 msg "$(gettext "Leaving fakeroot environment.")"
1876 exit 0 # $E_OK
1879 msg "$(gettext "Making package: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
1881 # if we are creating a source-only package, go no further
1882 if (( SOURCEONLY )); then
1883 if [[ -f $SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT} ]] \
1884 && (( ! FORCE )); then
1885 error "$(gettext "A source package has already been built. (use -f to overwrite)")"
1886 exit 1
1888 create_srcpackage
1889 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
1890 exit 0
1893 if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then
1894 # no warning message needed for nobuild, repkg
1895 if (( NODEPS || ( REPKG && PKGFUNC ) )); then
1896 warning "$(gettext "Skipping dependency checks.")"
1898 elif [ $(type -p "${PACMAN%% *}") ]; then
1899 if (( RMDEPS )); then
1900 original_pkglist=($(run_pacman -Qq | sort)) # required by remove_dep
1902 deperr=0
1904 msg "$(gettext "Checking Runtime Dependencies...")"
1905 resolve_deps ${depends[@]} || deperr=1
1907 msg "$(gettext "Checking Buildtime Dependencies...")"
1908 resolve_deps ${makedepends[@]} || deperr=1
1910 if (( RMDEPS )); then
1911 current_pkglist=($(run_pacman -Qq | sort)) # required by remove_deps
1914 if (( deperr )); then
1915 error "$(gettext "Could not resolve all dependencies.")"
1916 exit 1
1918 else
1919 warning "$(gettext "%s was not found in PATH; skipping dependency checks.")" "${PACMAN%% *}"
1922 # ensure we have a sane umask set
1923 umask 0022
1925 # get back to our src directory so we can begin with sources
1926 mkdir -p "$srcdir"
1927 chmod a-s "$srcdir"
1928 cd "$srcdir"
1930 if (( NOEXTRACT )); then
1931 warning "$(gettext "Skipping source retrieval -- using existing src/ tree")"
1932 warning "$(gettext "Skipping source integrity checks -- using existing src/ tree")"
1933 warning "$(gettext "Skipping source extraction -- using existing src/ tree")"
1935 if (( NOEXTRACT )) && [[ -z $(ls "$srcdir" 2>/dev/null) ]]; then
1936 error "$(gettext "The source directory is empty, there is nothing to build!")"
1937 plain "$(gettext "Aborting...")"
1938 exit 1
1940 elif (( REPKG )); then
1941 if (( ! PKGFUNC && ! SPLITPKG )) \
1942 && [[ ! -d $pkgdir || -z $(ls "$pkgdir" 2>/dev/null) ]]; then
1943 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
1944 plain "$(gettext "Aborting...")"
1945 exit 1
1947 else
1948 download_sources
1949 if (( ! SKIPINTEG )); then
1950 check_checksums
1951 else
1952 warning "$(gettext "Skipping integrity checks.")"
1954 extract_sources
1957 if (( NOBUILD )); then
1958 msg "$(gettext "Sources are ready.")"
1959 exit 0 #E_OK
1960 else
1961 # check for existing pkg directory; don't remove if we are repackaging
1962 if [[ -d $pkgdir ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
1963 msg "$(gettext "Removing existing pkg/ directory...")"
1964 rm -rf "$pkgdir"
1966 mkdir -p "$pkgdir"
1967 chmod a-s "$pkgdir"
1968 cd "$startdir"
1970 # if we are root or if fakeroot is not enabled, then we don't use it
1971 if [[ $(check_buildenv fakeroot) != "y" ]] || (( EUID == 0 )); then
1972 if (( ! REPKG )); then
1973 devel_update
1974 (( BUILDFUNC )) && run_build
1976 if (( ! SPLITPKG )); then
1977 if (( PKGFUNC )); then
1978 run_package
1979 tidy_install
1980 else
1981 if (( ! REPKG )); then
1982 tidy_install
1983 else
1984 warning "$(gettext "Repackaging without the use of a package() function is deprecated.")"
1985 plain "$(gettext "File permissions may not be preserved.")"
1988 create_package
1989 else
1990 for pkg in ${pkgname[@]}; do
1991 pkgdir="$pkgdir/$pkg"
1992 mkdir -p "$pkgdir"
1993 chmod a-s "$pkgdir"
1994 backup_package_variables
1995 run_package $pkg
1996 tidy_install
1997 create_package $pkg
1998 restore_package_variables
1999 pkgdir="${pkgdir%/*}"
2000 done
2002 else
2003 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
2004 devel_update
2005 (( BUILDFUNC )) && run_build
2006 cd "$startdir"
2009 msg "$(gettext "Entering fakeroot environment...")"
2011 if [[ -n $newpkgver ]]; then
2012 fakeroot -- $0 --forcever $newpkgver -F "${ARGLIST[@]}" || exit $?
2013 else
2014 fakeroot -- $0 -F "${ARGLIST[@]}" || exit $?
2019 msg "$(gettext "Finished making: %s")" "$pkgbase $pkgver-$pkgrel ($(date))"
2021 install_package
2023 exit 0 #E_OK
2025 # vim: set ts=2 sw=2 noet: