3 # makepkg - make packages compatible for use with pacman
6 # Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
7 # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
8 # Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
9 # Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
10 # Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
11 # Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
12 # Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
28 # makepkg uses quite a few external programs during its execution. You
29 # need to have at least the following installed for makepkg to function:
30 # awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
31 # gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
33 # gettext initialization
34 export TEXTDOMAIN
='pacman-scripts'
35 export TEXTDOMAINDIR
='@localedir@'
37 # file -i does not work on Mac OSX unless legacy mode is set
38 export COMMAND_MODE
='legacy'
39 # Ensure CDPATH doesn't screw with our cd calls
41 # Ensure GREP_OPTIONS doesn't screw with our grep calls
44 declare -r makepkg_version
='@PACKAGE_VERSION@'
45 declare -r confdir
='@sysconfdir@'
46 declare -r BUILDSCRIPT
='@BUILDSCRIPT@'
47 declare -r startdir
="$PWD"
49 packaging_options
=('strip' 'docs' 'libtool' 'staticlibs' 'emptydirs' 'zipman' \
50 'purge' 'upx' 'debug')
51 other_options
=('ccache' 'distcc' 'buildflags' 'makeflags')
52 splitpkg_overrides
=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'url' 'license' \
53 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \
54 'replaces' 'backup' 'options' 'install' 'changelog')
55 readonly -a packaging_options other_options splitpkg_overrides
88 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
89 # when dealing with svn/cvs/etc PKGBUILDs.
100 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
105 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
110 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
115 printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
120 printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
125 # Special exit call for traps, Don't print any error messages when inside,
126 # the fakeroot call, the error message will be printed by the main call.
129 local signal
=$1; shift
131 if (( ! INFAKEROOT
)); then
135 [[ -n $srclinks ]] && rm -rf "$srclinks"
137 # unset the trap for this signal, and then call the default handler
144 # Clean up function. Called automatically when the script exits.
149 if (( INFAKEROOT
)); then
150 # Don't clean up when leaving fakeroot, we're not done yet.
154 if (( ! EXIT_CODE
&& CLEANUP
)); then
157 # If it's a clean exit and -c/--clean has been passed...
158 msg
"$(gettext "Cleaning up...")"
159 rm -rf "$pkgdirbase" "$srcdir"
160 if [[ -n $pkgbase ]]; then
161 local fullver
=$(get_full_version)
162 # Can't do this unless the BUILDSCRIPT has been sourced.
163 if (( BUILDFUNC
)); then
164 rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"*
166 if (( CHECKFUNC
)); then
167 rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"*
169 if (( PKGFUNC
)); then
170 rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"*
171 elif (( SPLITPKG
)); then
172 for pkg
in ${pkgname[@]}; do
173 rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"*
177 # clean up dangling symlinks to packages
178 for pkg
in ${pkgname[@]}; do
179 for file in ${pkg}-*-*-*{${PKGEXT},${SRCEXT}}; do
180 if [[ -h $file && ! -e $file ]]; then
193 msg
"$(gettext "Entering %s environment...")" "fakeroot"
194 fakeroot
-- $0 -F "${ARGLIST[@]}" || exit $?
198 # a source entry can have two forms :
199 # 1) "filename::http://path/to/file"
200 # 2) "http://path/to/file"
202 # Return the absolute filename of a source entry
204 local file="$(get_filename "$1")"
205 local proto
="$(get_protocol "$1")"
209 if [[ -d "$startdir/$file" ]]; then
210 file="$startdir/$file"
211 elif [[ -d "$SRCDEST/$file" ]]; then
212 file="$SRCDEST/$file"
218 if [[ -f "$startdir/$file" ]]; then
219 file="$startdir/$file"
220 elif [[ -f "$SRCDEST/$file" ]]; then
221 file="$SRCDEST/$file"
228 printf "%s\n" "$file"
231 # extract the filename from a source entry
235 # if a filename is specified, use it
236 if [[ $netfile = *::* ]]; then
237 printf "%s\n" ${netfile%%::*}
241 local proto
=$(get_protocol "$netfile")
245 filename
=${netfile%%#*}
246 filename
=${filename%/}
247 filename
=${filename##*/}
248 if [[ $proto = bzr
* ]]; then
249 filename
=${filename#*lp:}
251 if [[ $proto = git
* ]]; then
252 filename
=${filename%%.git*}
256 # if it is just an URL, we only keep the last component
257 filename
="${netfile##*/}"
260 printf "%s\n" "${filename}"
263 # extract the URL from a source entry
265 # strip an eventual filename
266 printf "%s\n" "${1#*::}"
269 # extract the protocol from a source entry - return "local" for local sources
271 if [[ $1 = *://* ]]; then
272 # strip leading filename
273 local proto
="${1##*::}"
274 printf "%s\n" "${proto%%://*}"
275 elif [[ $1 = *lp:* ]]; then
276 local proto
="${1##*::}"
277 printf "%s\n" "${proto%%lp:*}"
283 get_downloadclient
() {
286 # loop through DOWNLOAD_AGENTS variable looking for protocol
288 for i
in "${DLAGENTS[@]}"; do
289 local handler
="${i%%::*}"
290 if [[ $proto = "$handler" ]]; then
291 local agent
="${i##*::}"
296 # if we didn't find an agent, return an error
297 if [[ -z $agent ]]; then
298 error
"$(gettext "Unknown download protocol: %s")" "$proto"
299 plain
"$(gettext "Aborting...")"
300 exit 1 # $E_CONFIG_ERROR
303 # ensure specified program is installed
304 local program
="${agent%% *}"
305 if [[ ! -x $program ]]; then
306 local baseprog
="${program##*/}"
307 error
"$(gettext "The download program %s is not installed.")" "$baseprog"
308 plain
"$(gettext "Aborting...")"
309 exit 1 # $E_MISSING_PROGRAM
312 printf "%s\n" "$agent"
317 local filepath
=$(get_filepath "$netfile")
319 if [[ -n "$filepath" ]]; then
320 msg2
"$(gettext "Found %s")" "${filepath##*/}"
321 rm -f "$srcdir/${filepath##*/}"
322 ln -s "$filepath" "$srcdir/"
324 local filename
=$(get_filename "$netfile")
325 error
"$(gettext "%s was not found in the build directory and is not a URL.")" "$filename"
326 exit 1 # $E_MISSING_FILE
333 local filepath
=$(get_filepath "$netfile")
334 if [[ -n "$filepath" ]]; then
335 msg2
"$(gettext "Found %s")" "${filepath##*/}"
336 rm -f "$srcdir/${filepath##*/}"
337 ln -s "$filepath" "$srcdir/"
341 local proto
=$(get_protocol "$netfile")
343 # find the client we should use for this URL
345 dlcmd
=$(get_downloadclient "$proto") || exit $?
347 local filename
=$(get_filename "$netfile")
348 local url
=$(get_url "$netfile")
350 if [[ $proto = "scp" ]]; then
351 # scp downloads should not pass the protocol in the url
355 msg2
"$(gettext "Downloading %s...")" "$filename"
357 # temporary download file, default to last component of the URL
358 local dlfile
="${url##*/}"
360 # replace %o by the temporary dlfile if it exists
361 if [[ $dlcmd = *%o
* ]]; then
362 dlcmd
=${dlcmd//\%o/\"$filename.part\"}
363 dlfile
="$filename.part"
365 # add the URL, either in place of %u or at the end
366 if [[ $dlcmd = *%u
* ]]; then
367 dlcmd
=${dlcmd//\%u/\"$url\"}
369 dlcmd
="$dlcmd \"$url\""
373 eval "$dlcmd || ret=\$?"
375 [[ ! -s $dlfile ]] && rm -f -- "$dlfile"
376 error
"$(gettext "Failure while downloading %s")" "$filename"
377 plain
"$(gettext "Aborting...")"
381 # rename the temporary download file to the final destination
382 if [[ $dlfile != "$filename" ]]; then
383 mv -f "$SRCDEST/$dlfile" "$SRCDEST/$filename"
386 rm -f "$srcdir/$filename"
387 ln -s "$SRCDEST/$filename" "$srcdir/"
393 local file_type
=$(file -bizL "$file")
394 local ext
=${file##*.}
397 *application
/x
-tar*|*application
/zip*|*application
/x
-zip*|*application
/x
-cpio*)
399 *application
/x
-gzip*)
401 gz
|z
|Z
) cmd
="gzip" ;;
404 *application
/x
-bzip*)
406 bz2
|bz
) cmd
="bzip2" ;;
415 # See if bsdtar can recognize the file
416 if bsdtar
-tf "$file" -q '*' &>/dev
/null
; then
424 msg2
"$(gettext "Extracting %s with %s")" "$file" "$cmd"
425 if [[ $cmd = "bsdtar" ]]; then
426 $cmd -xf "$file" || ret
=$?
428 rm -f -- "${file%.*}"
429 $cmd -dcf "$file" > "${file%.*}" || ret
=$?
432 error
"$(gettext "Failed to extract %s")" "$file"
433 plain
"$(gettext "Aborting...")"
437 if (( EUID
== 0 )); then
438 # change perms of all source files to root user & root group
439 chown
-R 0:0 "$srcdir"
446 local url
=$(get_url "$netfile")
450 local repo
=$(get_filename "$netfile")
451 local displaylocation
="$url"
453 local dir
=$(get_filepath "$netfile")
454 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
456 if [[ ! -d "$dir" ]] || dir_is_empty
"$dir" ; then
457 msg2
"$(gettext "Branching %s ...")" "${displaylocation}"
458 if ! bzr branch
"$url" "$dir" --no-tree --use-existing-dir; then
459 error
"$(gettext "Failure while branching %s")" "${displaylocation}"
460 plain
"$(gettext "Aborting...")"
463 elif (( ! HOLDVER
)); then
464 # Make sure we are fetching the right repo
465 local distant_url
="$(bzr info $url 2> /dev/null | sed -n '/branch root/{s/ branch root: //p;q;}')"
466 local local_url
="$(bzr config parent_location -d $dir)"
467 if [[ -n $distant_url ]]; then
468 if [[ $distant_url != "$local_url" ]]; then
469 error
"$(gettext "%s is not a branch of %s")" "$dir" "$url"
470 plain
"$(gettext "Aborting...")"
474 if [[ $url != "$local_url" ]] ; then
475 error
"$(gettext "%s is not a branch of %s")" "$dir" "$url"
476 error
"$(gettext "The local URL is %s")" "$local_url"
477 plain
"$(gettext "Aborting...")"
481 msg2
"$(gettext "Pulling %s ...")" "${displaylocation}"
483 if ! bzr pull
"$url" --overwrite; then
484 # only warn on failure to allow offline builds
485 warning
"$(gettext "Failure while pulling %s")" "${displaylocation}"
493 local repo
=$(get_filename "$netfile")
494 local fragment
=${netfile#*#}
495 if [[ $fragment = "$netfile" ]]; then
499 if [[ -n $fragment ]]; then
500 case ${fragment%%=*} in
502 revision
=("-r" "${fragment#*=}")
503 displaylocation
="$url -r ${fragment#*=}"
506 error
"$(gettext "Unrecognized reference: %s")" "${fragment}"
507 plain
"$(gettext "Aborting...")"
512 local dir
=$(get_filepath "$netfile")
513 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
515 msg2
"$(gettext "Creating working copy of %s %s repo...")" "${repo}" "bzr"
516 pushd "$srcdir" &>/dev
/null
519 if ! { bzr checkout
"$dir" "${revision[@]}" --lightweight &&
520 ( cd "$repo" && bzr pull
"$dir" -q --overwrite "${revision[@]}" ); }; then
521 error
"$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "bzr"
522 plain
"$(gettext "Aborting...")"
532 local dir
=$(get_filepath "$netfile")
533 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
535 local repo
=$(get_filename "$netfile")
537 local url
=$(get_url "$netfile")
541 if [[ ! -d "$dir" ]] || dir_is_empty
"$dir" ; then
542 msg2
"$(gettext "Cloning %s %s repo...")" "${repo}" "git"
543 if ! git clone
--mirror "$url" "$dir"; then
544 error
"$(gettext "Failure while downloading %s %s repo")" "${repo}" "git"
545 plain
"$(gettext "Aborting...")"
548 elif (( ! HOLDVER
)); then
550 # Make sure we are fetching the right repo
551 if [[ "$url" != "$(git config --get remote.origin.url)" ]] ; then
552 error
"$(gettext "%s is not a clone of %s")" "$dir" "$url"
553 plain
"$(gettext "Aborting...")"
556 msg2
"$(gettext "Updating %s %s repo...")" "${repo}" "git"
557 if ! git fetch
--all -p; then
558 # only warn on failure to allow offline builds
559 warning
"$(gettext "Failure while updating %s %s repo")" "${repo}" "git"
567 local fragment
=${netfile#*#}
568 if [[ $fragment = "$netfile" ]]; then
572 local repo
=${netfile##*/}
576 local dir
=$(get_filepath "$netfile")
577 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
579 msg2
"$(gettext "Creating working copy of %s %s repo...")" "${repo}" "git"
580 pushd "$srcdir" &>/dev
/null
583 if ! git clone
"$dir"; then
584 error
"$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git"
585 plain
"$(gettext "Aborting...")"
592 if [[ -n $fragment ]]; then
593 case ${fragment%%=*} in
598 ref
=origin
/${fragment##*=}
601 error
"$(gettext "Unrecognized reference: %s")" "${fragment}"
602 plain
"$(gettext "Aborting...")"
607 if [[ -n $ref ]]; then
608 if ! git checkout
-b makepkg
$ref; then
609 error
"$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git"
610 plain
"$(gettext "Aborting...")"
621 local dir
=$(get_filepath "$netfile")
622 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
624 local repo
=$(get_filename "$netfile")
626 local url
=$(get_url "$netfile")
630 if [[ ! -d "$dir" ]] || dir_is_empty
"$dir" ; then
631 msg2
"$(gettext "Cloning %s %s repo...")" "${repo}" "hg"
632 if ! hg clone
-U "$url" "$dir"; then
633 error
"$(gettext "Failure while downloading %s %s repo")" "${repo}" "hg"
634 plain
"$(gettext "Aborting...")"
637 elif (( ! HOLDVER
)); then
638 msg2
"$(gettext "Updating %s %s repo...")" "${repo}" "hg"
641 # only warn on failure to allow offline builds
642 warning
"$(gettext "Failure while updating %s %s repo")" "${repo}" "hg"
650 local fragment
=${netfile#*#}
651 if [[ $fragment = "$netfile" ]]; then
655 local dir
=$(get_filepath "$netfile")
656 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
658 local repo
=${netfile##*/}
661 msg2
"$(gettext "Creating working copy of %s %s repo...")" "${repo}" "hg"
662 pushd "$srcdir" &>/dev
/null
666 if [[ -n $fragment ]]; then
667 case ${fragment%%=*} in
669 ref
=('-u' "${fragment##*=}")
672 error
"$(gettext "Unrecognized reference: %s")" "${fragment}"
673 plain
"$(gettext "Aborting...")"
678 if ! hg clone
"${ref[@]}" "$dir" "${dir##*/}"; then
679 error
"$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "hg"
680 plain
"$(gettext "Aborting...")"
690 local fragment
=${netfile#*#}
691 if [[ $fragment = "$netfile" ]]; then
695 local dir
=$(get_filepath "$netfile")
696 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
698 local repo
=$(get_filename "$netfile")
700 local url
=$(get_url "$netfile")
701 if [[ $url != svn
+ssh* ]]; then
706 if [[ ! -d "$dir" ]] || dir_is_empty
"$dir" ; then
707 msg2
"$(gettext "Cloning %s %s repo...")" "${repo}" "svn"
708 mkdir -p "$dir/.makepkg"
709 if ! svn checkout
--config-dir "$dir/.makepkg" "$url" "$dir"; then
710 error
"$(gettext "Failure while downloading %s %s repo")" "${repo}" "svn"
711 plain
"$(gettext "Aborting...")"
714 elif (( ! HOLDVER
)); then
715 msg2
"$(gettext "Updating %s %s repo...")" "${repo}" "svn"
717 if ! svn update
; then
718 # only warn on failure to allow offline builds
719 warning
"$(gettext "Failure while updating %s %s repo")" "${repo}" "svn"
727 local fragment
=${netfile#*#}
728 if [[ $fragment = "$netfile" ]]; then
732 local dir
=$(get_filepath "$netfile")
733 [[ -z "$dir" ]] && dir
="$SRCDEST/$(get_filename "$netfile")"
735 local repo
=${netfile##*/}
738 msg2
"$(gettext "Creating working copy of %s %s repo...")" "${repo}" "svn"
739 pushd "$srcdir" &>/dev
/null
743 if [[ -n $fragment ]]; then
744 case ${fragment%%=*} in
746 ref
="${fragment##*=}"
749 error
"$(gettext "Unrecognized reference: %s")" "${fragment}"
750 plain
"$(gettext "Aborting...")"
757 if [[ -n ${ref} ]]; then
758 cd_safe
"$(get_filename "$netfile")"
759 if ! svn update
-r ${ref}; then
760 error
"$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "svn"
761 plain
"$(gettext "Aborting...")"
769 msg
"$(gettext "Retrieving sources...")"
772 if [[ $1 == "fast" ]]; then
777 for netfile
in "${source[@]}"; do
778 pushd "$SRCDEST" &>/dev
/null
780 local proto
=$(get_protocol "$netfile")
783 download_local
"$netfile"
786 (( GET_VCS
)) && download_bzr
"$netfile"
789 (( GET_VCS
)) && download_git
"$netfile"
792 (( GET_VCS
)) && download_hg
"$netfile"
795 (( GET_VCS
)) && download_svn
"$netfile"
798 download_file
"$netfile"
806 # Automatically update pkgver variable if a pkgver() function is provided
807 # Re-sources the PKGBUILD afterwards to allow for other variables that use $pkgver
809 newpkgver
=$(run_function_safe pkgver)
811 if [[ -n $newpkgver && $newpkgver != "$pkgver" ]]; then
812 if [[ -f $BUILDFILE && -w $BUILDFILE ]]; then
813 @SEDINPLACE@
"s/^pkgver=[^ ]*/pkgver=$newpkgver/" "$BUILDFILE"
814 @SEDINPLACE@
"s/^pkgrel=[^ ]*/pkgrel=1/" "$BUILDFILE"
816 local fullver
=$(get_full_version)
817 msg
"$(gettext "Updated version: %s")" "$pkgbase $fullver"
819 warning
"$(gettext "%s is not writeable -- pkgver will not be updated")" \
825 # Print 'source not found' error message and exit makepkg
826 missing_source_file
() {
827 error
"$(gettext "Unable to find source file %s.")" "$(get_filename "$1")"
828 plain
"$(gettext "Aborting...")"
829 exit 1 # $E_MISSING_FILE
833 # usage : get_full_version( [$pkgname] )
834 # return : full version spec, including epoch (if necessary), pkgver, pkgrel
838 if [[ $epoch ]] && (( ! $epoch )); then
839 printf "%s\n" "$pkgver-$pkgrel"
841 printf "%s\n" "$epoch:$pkgver-$pkgrel"
844 for i
in pkgver pkgrel epoch
; do
845 local indirect
="${i}_override"
846 eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override
=/p
")
847 [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
849 if (( ! $epoch_override )); then
850 printf "%s
\n" "$pkgver_override-$pkgrel_override"
852 printf "%s
\n" "$epoch_override:$pkgver_override-$pkgrel_override"
858 # usage : get_pkg_arch( [$pkgname] )
859 # return : architecture of the package
863 if [[ $arch = "any
" ]]; then
866 printf "%s
\n" "$CARCH"
870 eval $(declare -f package_$1 | sed -n 's/\(^[[:space:]]*arch=\)/arch_override=/p')
871 (( ${#arch_override[@]} == 0 )) && arch_override=("${arch[@]}")
872 if [[ $arch_override = "any
" ]]; then
875 printf "%s
\n" "$CARCH"
881 # Checks to see if options are present in makepkg.conf or PKGBUILD;
882 # PKGBUILD options always take precedence.
884 # usage : check_option( $option, $expected_val )
885 # return : 0 - matches expected
886 # 1 - does not match expected
890 in_opt_array "$1" ${options[@]}
900 # fall back to makepkg.conf options
901 in_opt_array "$1" ${OPTIONS[@]}
917 # Check if option is present in BUILDENV
919 # usage : check_buildenv( $option, $expected_val )
920 # return : 0 - matches expected
921 # 1 - does not match expected
925 in_opt_array "$1" ${BUILDENV[@]}
941 # usage : in_opt_array( $needle, $haystack )
942 # return : 0 - enabled
947 local needle=$1; shift
950 for (( i = $#; i > 0; i-- )); do
952 if [[ $opt = "$needle" ]]; then
955 elif [[ $opt = "!$needle" ]]; then
967 # usage : in_array( $needle, $haystack )
972 local needle=$1; shift
975 [[ $item = "$needle" ]] && return 0 # Found
980 source_has_signatures() {
982 for file in "${source[@]}"; do
983 if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then
992 if [[ ! $1 = -@(T|Qq) ]]; then
993 cmd=("$PACMAN_PATH" $PACMAN_OPTS "$@
")
995 cmd=("$PACMAN_PATH" "$@
")
997 if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
998 if type -p sudo >/dev/null; then
999 cmd=(sudo "${cmd[@]}")
1001 cmd=(su root -c "$(printf '%q ' "${cmd[@]}")")
1008 (( $# > 0 )) || return 0
1012 pmout=$(run_pacman -T "$@")
1015 if (( ret == 127 )); then #unresolved deps
1016 printf "%s
\n" "$pmout"
1017 elif (( ret )); then
1018 error "$(gettext "'%s' returned a fatal error (%i): %s
")" "$PACMAN" "$ret" "$pmout"
1024 local R_DEPS_SATISFIED
=0
1025 local R_DEPS_MISSING
=1
1027 (( $# == 0 )) && return $R_DEPS_SATISFIED
1031 if (( ! DEP_BIN
)); then
1032 return $R_DEPS_MISSING
1035 if (( DEP_BIN
)); then
1036 # install missing deps from binary packages (using pacman -S)
1037 msg
"$(gettext "Installing missing dependencies...")"
1039 if ! run_pacman
-S --asdeps $deplist; then
1040 error
"$(gettext "'%s' failed to install missing dependencies.")" "$PACMAN"
1041 exit 1 # TODO: error code
1045 # we might need the new system environment
1046 # save our shell options and turn off extglob
1047 local shellopts
=$(shopt -p)
1049 source /etc
/profile
&>/dev
/null
1052 return $R_DEPS_SATISFIED
1056 local R_DEPS_SATISFIED
=0
1057 local R_DEPS_MISSING
=1
1059 # deplist cannot be declared like this: local deplist=$(foo)
1060 # Otherwise, the return value will depend on the assignment.
1062 deplist
="$(set +E; check_deps $*)" || exit 1
1063 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
1065 if handle_deps
$deplist; then
1066 # check deps again to make sure they were resolved
1067 deplist
="$(set +E; check_deps $*)" || exit 1
1068 [[ -z $deplist ]] && return $R_DEPS_SATISFIED
1071 msg
"$(gettext "Missing dependencies:")"
1073 for dep
in $deplist; do
1077 return $R_DEPS_MISSING
1081 (( ! RMDEPS
)) && return
1083 # check for packages removed during dependency install (e.g. due to conflicts)
1084 # removing all installed packages is risky in this case
1085 if [[ -n $(grep -xvFf <(printf '%s\n' "${current_packagelist[@]}") \
1086 <(printf '%s\n' "${original_packagelist[@]}") || true
) ]]; then
1087 warning
"$(gettext "Failed to remove installed dependencies.")"
1092 deplist
=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
1093 <(printf "%s\n" "${current_pkglist[@]}") || true
))
1094 if [[ -z $deplist ]]; then
1098 msg
"Removing installed dependencies..."
1099 # exit cleanly on failure to remove deps as package has been built successfully
1100 if ! run_pacman
-Rn ${deplist[@]}; then
1101 warning
"$(gettext "Failed to remove installed dependencies.")"
1110 for integ
in md5 sha1 sha256 sha384 sha512
; do
1111 local integrity_sums
=($(eval echo "\${${integ}sums[@]}"))
1112 if [[ -n "$integrity_sums" ]]; then
1113 integlist
=(${integlist[@]} $integ)
1117 if (( ${#integlist[@]} > 0 )); then
1118 printf "%s\n" "${integlist[@]}"
1120 printf "%s\n" "${INTEGRITY_CHECK[@]}"
1124 generate_checksums
() {
1125 msg
"$(gettext "Generating checksums for source files...")"
1127 if ! type -p openssl
>/dev
/null
; then
1128 error
"$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl"
1129 exit 1 # $E_MISSING_PROGRAM
1133 if (( $# == 0 )); then
1134 integlist
=$(get_integlist)
1140 for integ
in ${integlist[@]}; do
1142 md5
|sha1
|sha256
|sha384
|sha512
) : ;;
1144 error
"$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
1145 exit 1;; # $E_CONFIG_ERROR
1149 local numsrc
=${#source[@]}
1150 printf "%s" "${integ}sums=("
1154 for (( i
= 0; i
< ${#integ} + 6; i
++ )); do
1159 for netfile
in "${source[@]}"; do
1161 proto
="$(get_protocol "$netfile")"
1168 if [[ ! $netfile = *.@
(sig?
(n
)|asc
) ]]; then
1170 file="$(get_filepath "$netfile")" || missing_source_file
"$netfile"
1171 sum="$(openssl dgst -${integ} "$file")"
1179 (( ct
)) && printf "%s" "$indent"
1180 printf "%s" "'$sum'"
1182 (( $ct < $numsrc )) && echo
1190 (( SKIPCHECKSUMS
)) && return 0
1191 (( ! ${#source[@]} )) && return 0
1194 local integ required
1195 for integ
in md5 sha1 sha256 sha384 sha512
; do
1196 local integrity_sums
=($(eval echo "\${${integ}sums[@]}"))
1197 if (( ${#integrity_sums[@]} == ${#source[@]} )); then
1198 msg
"$(gettext "Validating source files with %s...")" "${integ}sums"
1203 for file in "${source[@]}"; do
1205 file="$(get_filename "$file")"
1206 printf "%s" " $file ... " >&2
1208 if [[ ${integrity_sums[$idx]} = 'SKIP' ]]; then
1209 echo "$(gettext "Skipped")" >&2
1214 if ! file="$(get_filepath "$file")"; then
1215 printf -- "$(gettext "NOT FOUND")\n" >&2
1220 if (( $found )) ; then
1221 local expectedsum
="${integrity_sums[idx],,}"
1222 local realsum
="$(openssl dgst -${integ} "$file")"
1223 realsum
="${realsum##* }"
1224 if [[ $expectedsum = "$realsum" ]]; then
1225 printf -- "$(gettext "Passed")\n" >&2
1227 printf -- "$(gettext "FAILED")\n" >&2
1235 if (( errors
)); then
1236 error
"$(gettext "One or more files did not pass the validity check!")"
1237 exit 1 # TODO: error code
1239 elif (( ${#integrity_sums[@]} )); then
1240 error
"$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ"
1241 exit 1 # TODO: error code
1245 if (( ! correlation )); then
1246 error "$(gettext "Integrity checks are missing.")"
1247 exit 1 # TODO: error code
1252 (( SKIPPGPCHECK )) && return 0
1253 ! source_has_signatures && return 0
1255 msg "$(gettext "Verifying source file signatures with %s...")" "gpg
"
1260 local statusfile=$(mktemp)
1262 for file in "${source[@]}"; do
1263 file="$(get_filename "$file")"
1264 if [[ ! $file = *.@(sig?(n)|asc) ]]; then
1268 printf " %s ...
" "${file%.*}" >&2
1270 if ! file="$(get_filepath "$file")"; then
1271 printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
1276 if ! sourcefile="$(get_filepath "${file%.*}")"; then
1277 printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
1282 if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
1283 printf '%s' "$(gettext "FAILED")" >&2
1284 if ! pubkey=$(awk '/NO_PUBKEY/ { print $3; exit 1; }' "$statusfile"); then
1285 printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2
1292 if grep -q "REVKEYSIG
" "$statusfile"; then
1293 printf '%s (%s)' "$(gettext "FAILED")" "$(gettext "the key has been revoked.")" >&2
1296 printf '%s' "$(gettext "Passed")" >&2
1297 if grep -q "EXPSIG
" "$statusfile"; then
1298 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2
1300 elif grep -q "EXPKEYSIG
" "$statusfile"; then
1301 printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2
1311 if (( errors )); then
1312 error "$(gettext "One or more PGP signatures could not be verified!")"
1316 if (( warnings )); then
1317 warning "$(gettext "Warnings have occurred while verifying the signatures.")"
1318 plain "$(gettext "Please make sure you really trust them.")"
1322 check_source_integrity() {
1323 if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then
1324 warning "$(gettext "Skipping all source file integrity checks.")"
1325 elif (( SKIPCHECKSUMS )); then
1326 warning "$(gettext "Skipping verification of source file checksums.")"
1328 elif (( SKIPPGPCHECK )); then
1329 warning "$(gettext "Skipping verification of source file PGP signatures.")"
1338 msg "$(gettext "Extracting sources...")"
1340 for netfile in "${source[@]}"; do
1341 local file=$(get_filename "$netfile")
1342 if in_array "$file" "${noextract[@]}"; then
1343 #skip source files in the noextract=() array
1344 # these are marked explicitly to NOT be extracted
1347 local proto=$(get_protocol "$netfile")
1350 extract_bzr "$netfile"
1353 extract_git "$netfile"
1356 extract_hg "$netfile"
1359 extract_svn "$netfile"
1362 extract_file "$file"
1367 if (( PKGVERFUNC )); then
1369 check_pkgver || exit 1
1375 if [[ -p $logpipe ]]; then
1378 # first exit all subshells, then print the error
1379 if (( ! BASH_SUBSHELL )); then
1380 error "$(gettext "A failure occurred in %s().
")" "$1"
1381 plain
"$(gettext "Aborting...")"
1383 exit 2 # $E_BUILD_FAILED
1388 error
"$(gettext "Failed to change to directory %s")" "$1"
1389 plain
"$(gettext "Aborting...")"
1396 if ! source "$@"; then
1397 error
"$(gettext "Failed to source %s")" "$1"
1403 run_function_safe
() {
1409 restoretrap
=$(trap -p ERR)
1410 trap 'error_function $pkgfunc' ERR
1421 if [[ -z $1 ]]; then
1426 # clear user-specified buildflags if requested
1427 if check_option
"buildflags" "n"; then
1428 unset CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
1431 if check_option
"debug" "y"; then
1432 CFLAGS
+=" $DEBUG_CFLAGS"
1433 CXXFLAGS
+=" $DEBUG_CXXFLAGS"
1436 # clear user-specified makeflags if requested
1437 if check_option
"makeflags" "n"; then
1441 msg
"$(gettext "Starting %s()...")" "$pkgfunc"
1444 # ensure all necessary build variables are exported
1445 export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS MAKEFLAGS CHOST
1446 # save our shell options so pkgfunc() can't override what we need
1447 local shellopts=$(shopt -p)
1450 if (( LOGGING )); then
1451 local fullver=$(get_full_version)
1452 local BUILDLOG="$LOGDEST/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log
"
1453 if [[ -f $BUILDLOG ]]; then
1456 if [[ -f $BUILDLOG.$i ]]; then
1462 mv "$BUILDLOG" "$BUILDLOG.
$i"
1465 # ensure overridden package variables survive tee with split packages
1466 logpipe=$(mktemp -u "$LOGDEST/logpipe.XXXXXXXX")
1468 tee "$BUILDLOG" < "$logpipe" &
1471 $pkgfunc &>"$logpipe"
1478 # reset our shell options
1483 run_function_safe "prepare
"
1487 # use distcc if it is requested (check buildenv and PKGBUILD opts)
1488 if check_buildenv "distcc
" "y
" && ! check_option "distcc
" "n
"; then
1489 [[ -d /usr/lib/distcc/bin ]] && export PATH="/usr
/lib
/distcc
/bin
:$PATH"
1493 # use ccache if it is requested (check buildenv and PKGBUILD opts)
1494 if check_buildenv "ccache
" "y
" && ! check_option "ccache
" "n
"; then
1495 [[ -d /usr/lib/ccache/bin ]] && export PATH="/usr
/lib
/ccache
/bin
:$PATH"
1498 run_function_safe "build
"
1502 run_function_safe "check
"
1507 if [[ -z $1 ]]; then
1510 pkgfunc="package_
$1"
1513 run_function_safe "$pkgfunc"
1517 LANG=C readelf -n $1 | sed -n '/Build ID/ { s/.*: //p; q; }'
1521 local binary=$1; shift
1523 if check_option "debug
" "y
"; then
1524 local bid=$(build_id "$binary")
1526 # has this file already been stripped
1527 if [[ -n "$bid" ]]; then
1528 if [[ -f "$dbgdir/.build_id
/${bid:0:2}/${bid:2}.debug
" ]]; then
1531 elif [[ -f "$dbgdir/$binary.debug
" ]]; then
1535 mkdir -p "$dbgdir/${binary%/*}"
1536 objcopy --only-keep-debug "$binary" "$dbgdir/$binary.debug
"
1537 objcopy --add-gnu-debuglink="$dbgdir/${binary#/}.debug
" "$binary"
1539 # create any needed hardlinks
1540 while read -d '' file ; do
1541 if [[ "${binary}" -ef "${file}" && ! -f "$dbgdir/${file}.debug
" ]]; then
1542 mkdir -p "$dbgdir/${file%/*}"
1543 ln "$dbgdir/${binary}.debug
" "$dbgdir/${file}.debug
"
1545 done < <(find . -type f -perm -u+w -print0 2>/dev/null)
1547 if [[ -n "$bid" ]]; then
1549 mkdir -p "$dbgdir/.build_id
/${bid:0:2}"
1551 target="..
/..
/..
/..
/..
/${binary#./}"
1552 target="${target/..\/..\/usr\/lib\/}"
1553 target="${target/..\/usr\/}"
1554 ln -s "$target" "$dbgdir/.build_id
/${bid:0:2}/${bid:2}"
1556 target="..
/..
/${binary#./}.debug
"
1557 ln -s "$target" "$dbgdir/.build_id
/${bid:0:2}/${bid:2}.debug
"
1566 msg "$(gettext "Tidying install...")"
1568 if check_option "docs
" "n
" && [[ -n ${DOC_DIRS[*]} ]]; then
1569 msg2 "$(gettext "Removing doc files...")"
1570 rm -rf -- ${DOC_DIRS[@]}
1573 if check_option "purge
" "y
" && [[ -n ${PURGE_TARGETS[*]} ]]; then
1574 msg2 "$(gettext "Purging unwanted files...")"
1576 for pt in "${PURGE_TARGETS[@]}"; do
1577 if [[ ${pt} = "${pt//\/}" ]]; then
1578 find . ! -type d -name "${pt}" -exec rm -f -- '{}' +
1585 if check_option "libtool
" "n
"; then
1586 msg2 "$(gettext "Removing "%s" files...")" "libtool
"
1587 find . ! -type d -name "*.la
" -exec rm -f -- '{}' +
1590 if check_option "staticlibs
" "n
"; then
1591 msg2 "$(gettext "Removing "%s" files...")" "static library
"
1592 find . ! -type d -name "*.a
" -exec rm -f -- '{}' +
1595 if check_option "emptydirs
" "n
"; then
1596 msg2 "$(gettext "Removing empty directories...")"
1597 find . -depth -type d -exec rmdir '{}' + 2>/dev/null
1600 # check existence of backup files
1602 for file in "${backup[@]}"; do
1603 if [[ ! -f $file ]]; then
1604 warning "$(gettext "%s entry file not in package : %s")" "backup
" "$file"
1608 # check for references to the build and package directory
1609 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${srcdir}" ; then
1610 warning "$(gettext "Package contains reference to %s")" "\
$srcdir"
1612 if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdirbase}" ; then
1613 warning "$(gettext "Package contains reference to %s")" "\
$pkgdir"
1616 if check_option "zipman
" "y
" && [[ -n ${MAN_DIRS[*]} ]]; then
1617 msg2 "$(gettext "Compressing man and info pages...")"
1618 local file files inode link
1619 while read -rd ' ' inode; do
1621 find ${MAN_DIRS[@]} -type l 2>/dev/null |
1622 while read link ; do
1623 if [[ "${file}" -ef "${link}" ]] ; then
1624 rm -f "$link" "${link}.gz
"
1625 if [[ ${file%/*} = ${link%/*} ]]; then
1626 ln -s -- "${file##*/}.gz
" "${link}.gz
"
1628 ln -s -- "/${file}.gz
" "${link}.gz
"
1632 if [[ -z ${files[$inode]} ]]; then
1634 gzip -9 -n -f "$file"
1637 ln "${files[$inode]}.gz
" "${file}.gz
"
1638 chmod 644 "${file}.gz
"
1640 done < <(find ${MAN_DIRS[@]} -type f \! -name "*.gz
" \! -name "*.bz2
" \
1641 -exec @INODECMD@ '{}' + 2>/dev/null)
1644 if check_option "strip
" "y
"; then
1645 msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"
1646 # make sure library stripping variables are defined to prevent excess stripping
1647 [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"
1648 [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"
1650 if check_option "debug
" "y
"; then
1651 dbgdir="$pkgdir-@DEBUGSUFFIX@
/usr
/lib
/debug
"
1655 local binary strip_flags
1656 find . -type f -perm -u+w -print0 2>/dev/null | while read -d '' binary ; do
1657 case "$(file -bi "$binary")" in
1658 *application/x-sharedlib*) # Libraries (.so)
1659 strip_flags="$STRIP_SHARED";;
1660 *application/x-archive*) # Libraries (.a)
1661 strip_flags="$STRIP_STATIC";;
1662 *application/x-executable*) # Binaries
1663 strip_flags="$STRIP_BINARIES";;
1667 strip_file "$binary" ${strip_flags}
1671 if check_option "upx
" "y
"; then
1672 msg2 "$(gettext "Compressing binaries with %s...")" "UPX
"
1674 find . -type f -perm -u+w 2>/dev/null | while read binary ; do
1675 if [[ $(file -bi "$binary") = *'application/x-executable'* ]]; then
1676 upx $UPXFLAGS "$binary" &>/dev/null ||
1677 warning "$(gettext "Could not compress binary : %s")" "${binary/$pkgdir\//}"
1687 for d in "${depends[@]}"; do
1688 if [[ $d = *.so ]]; then
1694 if (( sodepends == 0 )); then
1695 printf '%s\n' "${depends[@]}"
1699 local libdeps filename soarch sofile soname soversion;
1702 while read filename; do
1703 # get architecture of the file; if soarch is empty it's not an ELF binary
1704 soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1705 [[ -n "$soarch" ]] || continue
1707 # process all libraries needed by the binary
1708 for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p')
1710 # extract the library name: libfoo.so
1711 soname="${sofile%.so?(+(.+([0-9])))}".so
1712 # extract the major version: 1
1713 soversion="${sofile##*\.so\.}"
1715 if [[ ${libdeps[$soname]} ]]; then
1716 if [[ ${libdeps[$soname]} != *${soversion}-${soarch}* ]]; then
1717 libdeps[$soname]+=" ${soversion}-${soarch}"
1720 libdeps[$soname]="${soversion}-${soarch}"
1723 done < <(find "$pkgdir" -type f -perm -u+x)
1726 for d in "${depends[@]}"; do
1729 if [[ ${libdeps[$d]} ]]; then
1730 for v in ${libdeps[$d]}; do
1731 libdepends+=("$d=$v")
1734 warning "$(gettext "Library listed in %s is not required by any files: %s")" "'depends'" "$d"
1744 printf '%s\n' "${libdepends[@]}"
1748 find_libprovides() {
1749 local p libprovides missing
1750 for p in "${provides[@]}"; do
1754 mapfile -t filename < <(find "$pkgdir" -type f -name $p\*)
1755 if [[ $filename ]]; then
1756 # packages may provide multiple versions of the same library
1757 for fn in "${filename[@]}"; do
1758 # check if we really have a shared object
1759 if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
1760 # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
1761 local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
1762 if [[ -z "$sofile" ]]; then
1763 warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
1768 # get the library architecture (32 or 64 bit)
1769 local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
1771 # extract the library major version
1772 local soversion="${sofile##*\.so\.}"
1774 libprovides+=("${p}=${soversion}-${soarch}")
1776 warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
1790 if (( missing )); then
1791 warning "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$p"
1795 printf '%s\n' "${libprovides[@]}"
1799 # TODO maybe remove this at some point
1800 # warn if license array is not present or empty
1801 if [[ -z $license ]]; then
1802 warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
1803 plain "$(gettext "Example for GPL\'ed software: %s.")" "license
=('GPL')"
1808 local builddate=$(date -u "+%s")
1809 if [[ -n $PACKAGER ]]; then
1810 local packager="$PACKAGER"
1812 local packager="Unknown Packager
"
1815 local size="$(@DUPATH@ @DUFLAGS@)"
1816 size="$(( ${size%%[^0-9]*} * 1024 ))"
1818 msg2 "$(gettext "Generating %s file...")" ".PKGINFO
"
1819 printf "# Generated by makepkg %s\n" "$makepkg_version"
1820 (( INFAKEROOT
)) && printf "# using %s\n" "$(fakeroot -v)"
1821 printf "# %s\n" "$(LC_ALL=C date -u)"
1822 printf "pkgname = %s\n" "$pkgname"
1823 (( SPLITPKG
)) && printf "pkgbase = %s\n" "$pkgbase"
1824 printf "pkgver = %s\n" "$(get_full_version)"
1825 printf "pkgdesc = %s\n" "${pkgdesc//+([[:space:]])/ }"
1826 printf "url = %s\n" "$url"
1827 printf "builddate = %s\n" "$builddate"
1828 printf "packager = %s\n" "$packager"
1829 printf "size = %s\n" "$size"
1830 printf "arch = %s\n" "$pkgarch"
1832 mapfile
-t provides
< <(find_libprovides
)
1833 mapfile
-t depends
< <(find_libdepends
)
1835 [[ $license ]] && printf "license = %s\n" "${license[@]}"
1836 [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
1837 [[ $groups ]] && printf "group = %s\n" "${groups[@]}"
1838 [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
1839 [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
1840 [[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
1841 [[ $depends ]] && printf "depend = %s\n" "${depends[@]}"
1842 [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
1843 [[ $makedepends ]] && printf "makedepend = %s\n" "${makedepends[@]}"
1844 [[ $checkdepends ]] && printf "checkdepend = %s\n" "${checkdepends[@]}"
1847 for it
in "${packaging_options[@]}"; do
1848 check_option
"$it" "y"
1851 printf "makepkgopt = %s\n" "$it"
1854 printf "makepkgopt = %s\n" "!$it"
1863 if [[ ! -d $pkgdir ]]; then
1864 error
"$(gettext "Missing %s directory.")" "pkg/"
1865 plain
"$(gettext "Aborting...")"
1866 exit 1 # $E_MISSING_PKGDIR
1870 msg
"$(gettext "Creating package \"%s\"...")" "$pkgname"
1872 pkgarch
=$(get_pkg_arch)
1874 write_pkginfo
> .PKGINFO
1876 local comp_files
=('.PKGINFO')
1878 # check for changelog/install files
1879 for i
in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
1880 IFS
='/' read -r orig dest
< <(printf '%s\n' "$i")
1882 if [[ -n ${!orig} ]]; then
1883 msg2
"$(gettext "Adding %s file...")" "$orig"
1884 cp "$startdir/${!orig}" "$dest"
1886 comp_files
+=("$dest")
1891 local fullver
=$(get_full_version)
1892 local pkg_file
="$PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT}"
1895 [[ -f $pkg_file ]] && rm -f "$pkg_file"
1896 [[ -f $pkg_file.sig
]] && rm -f "$pkg_file.sig"
1898 # when fileglobbing, we want * in an empty directory to expand to
1899 # the null string rather than itself
1902 msg2
"$(gettext "Generating .MTREE file...")"
1903 bsdtar
-czf .MTREE
--format=mtree \
1904 --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' \
1905 "${comp_files[@]}" *
1906 comp_files
+=(".MTREE")
1908 msg2
"$(gettext "Compressing package...")"
1909 # TODO: Maybe this can be set globally for robustness
1910 shopt -s -o pipefail
1911 # bsdtar's gzip compression always saves the time stamp, making one
1912 # archive created using the same command line distinct from another.
1913 # Disable bsdtar compression and use gzip -n for now.
1914 bsdtar
-cf - "${comp_files[@]}" * |
1916 *tar.gz
) ${COMPRESSGZ[@]:-gzip -c -f -n} ;;
1917 *tar.bz2
) ${COMPRESSBZ2[@]:-bzip2 -c -f} ;;
1918 *tar.xz
) ${COMPRESSXZ[@]:-xz -c -z -} ;;
1919 *tar.lrz
) ${COMPRESSLRZ[@]:-lrzip -q} ;;
1920 *tar.lzo
) ${COMPRESSLZO[@]:-lzop -q} ;;
1921 *tar.Z
) ${COMPRESSZ[@]:-compress -c -f} ;;
1923 *) warning
"$(gettext "'%s' is not a valid archive extension.")" \
1925 esac > "${pkg_file}" || ret
=$?
1928 shopt -u -o pipefail
1931 error
"$(gettext "Failed to create package file.")"
1932 exit 1 # TODO: error code
1935 create_signature
"$pkg_file"
1937 if (( ! ret
)) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then
1938 rm -f "${pkg_file/$PKGDEST/$startdir}"
1939 ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
1941 if [[ -f $pkg_file.sig
]]; then
1942 rm -f "${pkg_file/$PKGDEST/$startdir}.sig"
1943 ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
1948 warning
"$(gettext "Failed to create symlink to package file.")"
1952 create_debug_package
() {
1953 # check if a debug package was requested
1954 if ! check_option
"debug" "y" || ! check_option
"strip" "y"; then
1958 pkgdir
="${pkgdir}-@DEBUGSUFFIX@"
1960 # check if we have any debug symbols to package
1961 if dir_is_empty
"$pkgdir/usr/lib/debug"; then
1965 depends
=("$pkgname=$(get_full_version)")
1966 pkgdesc
="Detached debugging symbols for $pkgname"
1967 pkgname
=$pkgname-@DEBUGSUFFIX@
1969 unset groups optdepends provides conflicts replaces backup
install changelog
1974 create_signature
() {
1975 if [[ $SIGNPKG != 'y' ]]; then
1980 msg
"$(gettext "Signing package...")"
1982 local SIGNWITHKEY
=""
1983 if [[ -n $GPGKEY ]]; then
1984 SIGNWITHKEY
="-u ${GPGKEY}"
1986 # The signature will be generated directly in ascii-friendly format
1987 gpg
--detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev
/null
|| ret
=$?
1990 if (( ! ret
)); then
1991 msg2
"$(gettext "Created signature file %s.")" "$filename.sig"
1993 warning
"$(gettext "Failed to sign package file.")"
1997 create_srcpackage
() {
1999 msg
"$(gettext "Creating source package...")"
2000 local srclinks
="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
2001 mkdir "${srclinks}"/${pkgbase}
2005 msg2
"$(gettext "Adding %s...")" "$BUILDSCRIPT"
2006 ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
2009 for file in "${source[@]}"; do
2010 if [[ "$file" = "$(get_filename "$file")" ]] || (( SOURCEONLY
== 2 )); then
2012 absfile
=$(get_filepath "$file") || missing_source_file
"$file"
2013 msg2
"$(gettext "Adding %s...")" "${absfile##*/}"
2014 ln -s "$absfile" "$srclinks/$pkgbase"
2019 for i
in 'changelog' 'install'; do
2021 while read -r file; do
2022 # evaluate any bash variables used
2023 eval file=\"$(sed 's/^\(['\''"]\)\
(.
*\
)\
1$
/\
2/' <<< "$file")\"
2024 if [[ $file && ! -f "${srclinks}/${pkgbase}/$file" ]]; then
2025 msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}"
2026 ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/"
2028 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
2033 *tar.gz) TAR_OPT="-z" ;;
2034 *tar.bz2) TAR_OPT="-j" ;;
2035 *tar.xz) TAR_OPT="-J" ;;
2036 *tar.lrz) TAR_OPT="--lrzip" ;;
2037 *tar.lzo) TAR_OPT="--lzop" ;;
2038 *tar.Z) TAR_OPT="-Z" ;;
2040 *) warning "$(gettext "'%s' is not a valid archive extension.")" \
2044 local fullver=$(get_full_version)
2045 local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}"
2048 msg2 "$(gettext "Compressing source package...")"
2049 cd_safe "${srclinks}"
2050 if ! bsdtar -cL ${TAR_OPT} -f "$pkg_file" ${pkgbase}; then
2051 error "$(gettext "Failed to create source package file.")"
2052 exit 1 # TODO: error code
2055 if [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then
2056 rm -f "${pkg_file/$SRCPKGDEST/$startdir}"
2057 ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}"
2062 warning "$(gettext "Failed to create symlink to source package file.")"
2065 cd_safe "${startdir}"
2066 rm -rf "${srclinks}"
2070 (( ! INSTALL )) && return
2072 if (( ! SPLITPKG )); then
2073 msg "$(gettext "Installing package %s with %s...")" "$pkgname" "$PACMAN -U"
2075 msg "$(gettext "Installing %s package group with %s...")" "$pkgbase" "$PACMAN -U"
2078 local fullver pkgarch pkg pkglist
2079 (( ASDEPS )) && pkglist+=('--asdeps')
2080 (( NEEDED )) && pkglist+=('--needed')
2082 for pkg in ${pkgname[@]}; do
2083 fullver=$(get_full_version $pkg)
2084 pkgarch=$(get_pkg_arch $pkg)
2085 pkglist+=("$PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT}")
2087 if [[ -f "$PKGDEST/${pkg}-debug-${fullver}-${pkgarch}${PKGEXT}" ]]; then
2088 pkglist+=("$PKGDEST/${pkg}-debug-${fullver}-${pkgarch}${PKGEXT}")
2092 if ! run_pacman -U ${pkglist[@]}; then
2093 warning "$(gettext "Failed to install built package(s).")"
2099 # check for no-no's
in the build
script
2102 for i
in 'pkgname' 'pkgrel'; do
2103 if [[ -z ${!i} ]]; then
2104 error
"$(gettext "%s is not allowed to be empty.")" "$i"
2109 for i
in "${pkgname[@]}"; do
2110 if [[ ${i:0:1} = "-" ]]; then
2111 error
"$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
2114 if [[ ${i:0:1} = "." ]]; then
2115 error
"$(gettext "%s is not allowed to start with a dot.")" "pkgname"
2118 if [[ $i = *[^[:alnum:]+_.@-]* ]]; then
2119 error
"$(gettext "%s contains invalid characters: '%s'")" \
2120 'pkgname' "${pkgname//[[:alnum:]+_.@-]}"
2125 if [[ ${pkgbase:0:1} = "-" ]]; then
2126 error
"$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase"
2130 if (( ! PKGVERFUNC
)) ; then
2131 check_pkgver
|| ret
=1
2134 awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
2135 while IFS
='=' read -r _ i
; do
2136 eval i
=\"$(sed 's/^\(['\''"]\)\
(.
*\
)\
1$
/\
2/' <<< "${i%%+([[:space:]])}")\"
2137 if [[ $i != +([0-9])?(.+([0-9])) ]]; then
2138 error "$(gettext "%s must be a decimal.")" "pkgrel"
2143 awk -F'=' '$1 ~
/^
[[:space
:]]*epoch$
/' "$BUILDFILE" |
2144 while IFS='=' read -r _ i; do
2145 eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
2146 if [[ $i != *([[:digit
:]]) ]]; then
2147 error
"$(gettext "%s must be an integer.")" "epoch"
2152 if [[ $arch != 'any' ]]; then
2153 if ! in_array
$CARCH ${arch[@]}; then
2154 if (( ! IGNOREARCH
)); then
2155 error
"$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH"
2156 plain
"$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
2157 plain
"$(gettext "such as %s.")" "arch=('$CARCH')"
2163 if (( ${#pkgname[@]} > 1 )); then
2164 for i
in ${pkgname[@]}; do
2166 eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list
=/p
')
2167 if [[ ${arch_list[@]} && ${arch_list} != 'any
' ]]; then
2168 if ! in_array $CARCH ${arch_list[@]}; then
2169 if (( ! IGNOREARCH )); then
2170 error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH"
2178 local provides_list=()
2179 eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \
2180 sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//')
2181 for i
in ${provides_list[@]}; do
2182 if [[ $i == *['<>']* ]]; then
2183 error
"$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides
"
2188 local backup_list=()
2189 eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \
2190 sed -e "s
/backup
=/backup_list
+=/" -e "s
/#.*//" -e 's/\\$//')
2191 for i
in "${backup_list[@]}"; do
2192 if [[ ${i:0:1} = "/" ]]; then
2193 error
"$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i"
2198 local optdepends_list
=()
2199 eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space
:]]*(#.*)?$/' "$BUILDFILE" | \
2200 sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//')
2201 for i
in "${optdepends_list[@]}"; do
2202 local pkg
=${i%%:[[:space:]]*}
2203 # the '-' character _must_ be first or last in the character range
2204 if [[ $pkg != +([-[:alnum
:]><=.
+_
:]) ]]; then
2205 error
"$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i"
2210 for i
in 'changelog' 'install'; do
2212 while read -r file; do
2213 # evaluate any bash variables used
2214 eval file=\"$(sed 's/^\(['\''"]\)\
(.
*\
)\
1$
/\
2/' <<< "$file")\"
2215 if [[ $file && ! -f $file ]]; then
2216 error "$(gettext "%s file (%s) does not exist.")" "$i" "$file"
2219 done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
2222 local valid_options=1
2223 local known kopt options_list
2224 eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \
2225 sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//')
2226 for i
in ${options_list[@]}; do
2228 # check if option matches a known option or its inverse
2229 for kopt
in ${packaging_options[@]} ${other_options[@]}; do
2230 if [[ ${i} = "${kopt}" || ${i} = "!${kopt}" ]]; then
2234 if (( ! known
)); then
2235 error
"$(gettext "%s array contains unknown option '%s'")" "options" "$i"
2239 if (( ! valid_options
)); then
2243 if (( ${#pkgname[@]} > 1 )); then
2244 for i
in ${pkgname[@]}; do
2245 if ! declare -f package_
${i} >/dev
/null
; then
2246 error
"$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
2252 for i
in ${PKGLIST[@]}; do
2253 if ! in_array
$i ${pkgname[@]}; then
2254 error
"$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
2265 if [[ -z ${pkgver} ]]; then
2266 error
"$(gettext "%s is not allowed to be empty.")" "pkgver"
2270 awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
2271 while IFS
='=' read -r _ i
; do
2272 eval i
=\"$(sed 's/^\(['\''"]\)\
(.
*\
)\
1$
/\
2/' <<< "${i%%+([[:space:]])}")\"
2273 if [[ $i = *[[:space:]:-]* ]]; then
2274 error "$(gettext "%s is not allowed to contain colons, hyphens or whitespace.")" "pkgver"
2283 # check for needed software
2286 # check for PACMAN if we need it
2287 if (( ! INFAKEROOT && ( ! NODEPS || DEP_BIN || RMDEPS || INSTALL ) )); then
2288 if [[ -z $PACMAN_PATH ]]; then
2289 error "$(gettext "Cannot find the %s binary required for dependency operations.")" "$PACMAN"
2294 # check for sudo if we will need it during makepkg execution
2295 if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then
2296 if ! type -p sudo >/dev/null; then
2297 warning "$(gettext "Cannot find the %s binary. Will use %s to acquire root privileges.")" "sudo" "su"
2301 # fakeroot - building as non-root user
2302 if check_buildenv "fakeroot" "y" && (( EUID > 0 )); then
2303 if ! type -p fakeroot >/dev/null; then
2304 error "$(gettext "Cannot find the %s binary required for building as non-root user.")" "fakeroot"
2309 # gpg - package signing
2310 if [[ $SIGNPKG == 'y
' ]] || { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; }; then
2311 if ! type -p gpg >/dev/null; then
2312 error "$(gettext "Cannot find the %s binary required for signing packages.")" "gpg"
2317 # gpg - source verification
2318 if (( ! SKIPPGPCHECK )) && source_has_signatures; then
2319 if ! type -p gpg >/dev/null; then
2320 error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg"
2325 # openssl - checksum operations
2326 if (( ! SKIPCHECKSUMS )); then
2327 if ! type -p openssl >/dev/null; then
2328 error "$(gettext "Cannot find the %s binary required for validating sourcefile checksums.")" "openssl"
2333 # upx - binary compression
2334 if check_option "upx" "y"; then
2335 if ! type -p upx >/dev/null; then
2336 error "$(gettext "Cannot find the %s binary required for compressing binaries.")" "upx"
2341 # distcc - compilation with distcc
2342 if check_buildenv "distcc" "y" && ! check_option "distcc" "n" ]]; then
2343 if ! type -p distcc >/dev/null; then
2344 error "$(gettext "Cannot find the %s binary required for distributed compilation.")" "distcc"
2349 # ccache - compilation with ccache
2350 if check_buildenv "ccache" "y" && ! check_option "ccache" "n"; then
2351 if ! type -p ccache >/dev/null; then
2352 error "$(gettext "Cannot find the %s binary required for compiler cache usage.")" "ccache"
2357 # strip - strip symbols from binaries/libraries
2358 if check_option "strip" "y"; then
2359 if ! type -p strip >/dev/null; then
2360 error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
2365 # gzip - compressig man and info pages
2366 if check_option "zipman" "y"; then
2367 if ! type -p gzip >/dev/null; then
2368 error "$(gettext "Cannot find the %s binary required for compressing man and info pages.")" "gzip"
2376 check_build_status() {
2377 if (( ! SPLITPKG )); then
2378 fullver=$(get_full_version)
2379 pkgarch=$(get_pkg_arch)
2380 if [[ -f $PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT} ]] \
2381 && ! (( FORCE || SOURCEONLY || NOBUILD )); then
2382 if (( INSTALL )); then
2383 warning "$(gettext "A package has already been built, installing existing package...")"
2387 error "$(gettext "A package has already been built. (use %s to overwrite)")" "-f"
2394 for pkg in ${pkgname[@]}; do
2395 fullver=$(get_full_version $pkg)
2396 pkgarch=$(get_pkg_arch $pkg)
2397 if [[ -f $PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT} ]]; then
2403 if ! (( FORCE || SOURCEONLY || NOBUILD )); then
2404 if (( allpkgbuilt )); then
2405 if (( INSTALL )); then
2406 warning "$(gettext "The package group has already been built, installing existing packages...")"
2410 error "$(gettext "The package group has already been built. (use %s to overwrite)")" "-f"
2414 if (( somepkgbuilt && ! PKGVERFUNC )); then
2415 error "$(gettext "Part of the package group has already been built. (use %s to overwrite)")" "-f"
2419 unset allpkgbuilt somepkgbuilt
2423 backup_package_variables() {
2425 for var in ${splitpkg_overrides[@]}; do
2426 local indirect="${var}_backup"
2427 eval "${indirect}=(\"\${$var[@]}\")"
2431 restore_package_variables() {
2433 for var in ${splitpkg_overrides[@]}; do
2434 local indirect="${var}_backup"
2435 if [[ -n ${!indirect} ]]; then
2436 eval "${var}=(\"\${$indirect[@]}\")"
2443 run_split_packaging() {
2444 local pkgname_backup=${pkgname[@]}
2445 for pkgname in ${pkgname_backup[@]}; do
2446 pkgdir="$pkgdirbase/$pkgname"
2448 backup_package_variables
2449 run_package $pkgname
2452 create_debug_package
2453 restore_package_variables
2455 pkgname=${pkgname_backup[@]}
2458 # Canonicalize a directory path if it exists
2459 canonicalize_path() {
2462 if [[ -d $path ]]; then
2468 printf "%s\n" "$path"
2474 shopt -s dotglob nullglob
2476 (( ${#files} == 0 ))
2480 m4_include(library/parseopts.sh)
2483 printf "makepkg (pacman) %s\n" "$makepkg_version"
2485 printf -- "$(gettext "Usage: %s [options]")\n" "$0"
2487 printf -- "$(gettext "Options:")\n"
2488 printf -- "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT"
2489 printf -- "$(gettext " -c, --clean Clean up work files after build")\n"
2490 printf -- "$(gettext " -d, --nodeps Skip all dependency checks")\n"
2491 printf -- "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/"
2492 printf -- "$(gettext " -f, --force Overwrite existing package")\n"
2493 printf -- "$(gettext " -g, --geninteg Generate integrity checks for source files")\n"
2494 printf -- "$(gettext " -h, --help Show this help message and exit")\n"
2495 printf -- "$(gettext " -i, --install Install package after successful build")\n"
2496 printf -- "$(gettext " -L, --log Log package build process")\n"
2497 printf -- "$(gettext " -m, --nocolor Disable colorized output messages")\n"
2498 printf -- "$(gettext " -o, --nobuild Download and extract files only")\n"
2499 printf -- "$(gettext " -p <file> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
2500 printf -- "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")\n"
2501 printf -- "$(gettext " -R, --repackage Repackage contents of the package without rebuilding")\n"
2502 printf -- "$(gettext " -s, --syncdeps Install missing dependencies with %s")\n" "pacman"
2503 printf -- "$(gettext " -S, --source Generate a source-only tarball without downloaded sources")\n"
2504 printf -- "$(gettext " -V, --version Show version information and exit")\n"
2505 printf -- "$(gettext " --allsource Generate a source-only tarball including downloaded sources")\n"
2506 printf -- "$(gettext " --verifysource Download source files (if needed) and perform integrity checks")\n"
2507 printf -- "$(gettext " --asroot Allow %s to run as root user")\n" "makepkg"
2508 printf -- "$(gettext " --check Run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
2509 printf -- "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf"
2510 printf -- "$(gettext " --holdver Do not update VCS sources")\n"
2511 printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
2512 printf -- "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
2513 printf -- "$(gettext " --nosign Do not create a signature for the package")\n"
2514 printf -- "$(gettext " --pkg <list> Only build listed packages from a split package")\n"
2515 printf -- "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
2516 printf -- "$(gettext " --skipchecksums Do not verify checksums of the source files")\n"
2517 printf -- "$(gettext " --skipinteg Do not perform any verification checks on source files")\n"
2518 printf -- "$(gettext " --skippgpcheck Do not verify source files with PGP signatures")\n"
2520 printf -- "$(gettext "These options can be passed to %s:")\n" "pacman"
2522 printf -- "$(gettext " --asdeps Install packages as non-explicitly installed")\n"
2523 printf -- "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")\n"
2524 printf -- "$(gettext " --needed Do not reinstall the targets that are already up to date")\n"
2525 printf -- "$(gettext " --noprogressbar Do not show a progress bar when downloading files")\n"
2527 printf -- "$(gettext "If %s is not specified, %s will look for '%s'")\n" "-p" "makepkg" "$BUILDSCRIPT"
2532 printf "makepkg (pacman) %s\n" "$makepkg_version"
2533 printf -- "$(gettext "\
2534 Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>.\n\
2535 Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
2536 This is free software; see the source for copying conditions.\n\
2537 There is NO WARRANTY, to the extent permitted by law.\n")"
2542 # determine whether we have gettext; make it a no-op if we do not
2543 if ! type -p gettext >/dev/null; then
2551 # Parse Command Line Options.
2552 OPT_SHORT="AcdefFghiLmop:rRsSV"
2553 OPT_LONG=('allsource
' 'asroot
' 'check
' 'clean
' 'config
:' 'force
' 'geninteg
'
2554 'help' 'holdver
' 'ignorearch
' 'install' 'key
:' 'log
' 'nobuild
' 'nocolor
'
2555 'nocheck
' 'nodeps
' 'noextract
' 'nosign
' 'pkg
:' 'repackage
' 'rmdeps
'
2556 'sign
' 'skipchecksums
' 'skipinteg
' 'skippgpcheck
' 'source' 'syncdeps
'
2557 'verifysource
' 'version
')
2560 OPT_LONG+=('asdeps
' 'noconfirm
' 'needed
' 'noprogressbar
')
2562 if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
2563 exit 1 # E_INVALID_OPTION;
2565 set -- "${OPTRET[@]}"
2566 unset OPT_SHORT OPT_LONG OPTRET
2571 --asdeps) ASDEPS=1;;
2572 --noconfirm) PACMAN_OPTS+=" --noconfirm" ;;
2573 --needed) NEEDED=1;;
2574 --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;;
2577 --allsource) SOURCEONLY=2 ;;
2578 --asroot) ASROOT=1 ;;
2579 -A|--ignorearch) IGNOREARCH=1 ;;
2580 -c|--clean) CLEANUP=1 ;;
2581 --check) RUN_CHECK='y
' ;;
2582 --config) shift; MAKEPKG_CONF=$1 ;;
2583 -d|--nodeps) NODEPS=1 ;;
2584 -e|--noextract) NOEXTRACT=1 ;;
2585 -f|--force) FORCE=1 ;;
2587 -g|--geninteg) GENINTEG=1 ;;
2588 --holdver) HOLDVER=1 ;;
2589 -i|--install) INSTALL=1 ;;
2590 --key) shift; GPGKEY=$1 ;;
2591 -L|--log) LOGGING=1 ;;
2592 -m|--nocolor) USE_COLOR='n
' ;;
2593 --nocheck) RUN_CHECK='n
' ;;
2594 --nosign) SIGNPKG='n
' ;;
2595 -o|--nobuild) NOBUILD=1 ;;
2596 -p) shift; BUILDFILE=$1 ;;
2597 --pkg) shift; IFS=, read -ra p <<<"$1"; PKGLIST+=("${p[@]}"); unset p ;;
2598 -r|--rmdeps) RMDEPS=1 ;;
2599 -R|--repackage) REPKG=1 ;;
2600 --skipchecksums) SKIPCHECKSUMS=1 ;;
2601 --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;;
2602 --skippgpcheck) SKIPPGPCHECK=1;;
2603 --sign) SIGNPKG='y
' ;;
2604 -s|--syncdeps) DEP_BIN=1 ;;
2605 -S|--source) SOURCEONLY=1 ;;
2606 --verifysource) VERIFYSOURCE=1 ;;
2608 -h|--help) usage; exit 0 ;; # E_OK
2609 -V|--version) version; exit 0 ;; # E_OK
2611 --) OPT_IND=0; shift; break 2;;
2616 # setup signal traps
2618 for signal in TERM HUP QUIT; do
2619 trap "trap_exit $signal \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal"
2621 trap 'trap_exit INT
"$(gettext "Aborted by user! Exiting...")"' INT
2622 trap 'trap_exit USR1
"$(gettext "An unknown error has occurred. Exiting...")"' ERR
2624 # preserve environment variables and canonicalize path
2625 [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST})
2626 [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST})
2627 [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})
2628 [[ -n ${LOGDEST} ]] && _LOGDEST=$(canonicalize_path ${LOGDEST})
2629 [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR})
2630 [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
2631 [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
2632 [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
2633 [[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
2635 # default config is makepkg.conf
2636 MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
2638 # Source the config file; fail if it is not found
2639 if [[ -r $MAKEPKG_CONF ]]; then
2640 source_safe "$MAKEPKG_CONF"
2642 error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
2643 plain "$(gettext "Aborting...")"
2644 exit 1 # $E_CONFIG_ERROR
2647 # Source user-specific makepkg.conf overrides, but only if no override config
2648 # file was specified
2649 if [[ $MAKEPKG_CONF = "$confdir/makepkg.conf" && -r ~/.makepkg.conf ]]; then
2650 source_safe ~/.makepkg.conf
2653 # set pacman command if not already defined
2654 PACMAN=${PACMAN:-pacman}
2655 # save full path to command as PATH may change when sourcing /etc/profile
2656 PACMAN_PATH=$(type -P $PACMAN) || true
2658 # check if messages are to be printed using color
2659 unset ALL_OFF BOLD BLUE GREEN RED YELLOW
2660 if [[ -t 2 && ! $USE_COLOR = "n" ]] && check_buildenv "color" "y"; then
2661 # prefer terminal safe colored and bold text when tput is supported
2662 if tput setaf 0 &>/dev/null; then
2663 ALL_OFF="$(tput sgr0)"
2665 BLUE="${BOLD}$(tput setaf 4)"
2666 GREEN="${BOLD}$(tput setaf 2)"
2667 RED="${BOLD}$(tput setaf 1)"
2668 YELLOW="${BOLD}$(tput setaf 3)"
2672 BLUE="${BOLD}\e[1;34m"
2673 GREEN="${BOLD}\e[1;32m"
2674 RED="${BOLD}\e[1;31m"
2675 YELLOW="${BOLD}\e[1;33m"
2678 readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
2680 # override settings with an environment variable for batch processing
2681 BUILDDIR=${_BUILDDIR:-$BUILDDIR}
2682 BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined
2683 if [[ ! -d $BUILDDIR ]]; then
2684 if ! mkdir -p "$BUILDDIR"; then
2685 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2686 plain "$(gettext "Aborting...")"
2689 chmod a-s "$BUILDDIR"
2691 if [[ ! -w $BUILDDIR ]]; then
2692 error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR"
2693 plain "$(gettext "Aborting...")"
2697 PKGDEST=${_PKGDEST:-$PKGDEST}
2698 PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
2699 if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then
2700 error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST"
2701 plain "$(gettext "Aborting...")"
2705 SRCDEST=${_SRCDEST:-$SRCDEST}
2706 SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
2707 if [[ ! -w $SRCDEST ]] ; then
2708 error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
2709 plain "$(gettext "Aborting...")"
2713 SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST}
2714 SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined
2715 if (( SOURCEONLY )) && [[ ! -w $SRCPKGDEST ]]; then
2716 error "$(gettext "You do not have write permission to store source tarballs in %s.")" "$SRCPKGDEST"
2717 plain "$(gettext "Aborting...")"
2721 LOGDEST=${_LOGDEST:-$LOGDEST}
2722 LOGDEST=${LOGDEST:-$startdir} #default to $startdir if undefined
2723 if (( LOGGING )) && [[ ! -w $LOGDEST ]]; then
2724 error "$(gettext "You do not have write permission to store logs in %s.")" "$LOGDEST"
2725 plain "$(gettext "Aborting...")"
2729 PKGEXT=${_PKGEXT:-$PKGEXT}
2730 SRCEXT=${_SRCEXT:-$SRCEXT}
2731 GPGKEY=${_GPGKEY:-$GPGKEY}
2732 PACKAGER=${_PACKAGER:-$PACKAGER}
2734 if (( ! INFAKEROOT )); then
2735 if (( EUID == 0 && ! ASROOT )); then
2736 # Warn those who like to live dangerously.
2737 error "$(gettext "Running %s as root is a BAD idea and can cause permanent,\n\
2738 catastrophic damage to your system. If you wish to run as root, please\n\
2739 use the %s option.")" "makepkg" "--asroot"
2740 exit 1 # $E_USER_ABORT
2741 elif (( EUID > 0 && ASROOT )); then
2742 # Warn those who try to use the --asroot option when they are not root
2743 error "$(gettext "The %s option is meant for the root user only. Please\n\
2744 rerun %s without the %s flag.")" "--asroot" "makepkg" "--asroot"
2745 exit 1 # $E_USER_ABORT
2746 elif (( EUID > 0 )) && ! check_buildenv "fakeroot" "y"; then
2747 warning "$(gettext "Running %s as an unprivileged user will result in non-root\n\
2748 ownership of the packaged files. Try using the %s environment by\n\
2749 placing %s in the %s array in %s.")" "makepkg" "fakeroot" "'fakeroot
'" "BUILDENV" "$MAKEPKG_CONF"
2753 if [[ -z $FAKEROOTKEY ]]; then
2754 error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg"
2755 exit 1 # TODO: error code
2759 unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides
2760 unset md5sums replaces depends conflicts backup source install changelog build
2761 unset makedepends optdepends options noextract
2763 BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
2764 if [[ ! -f $BUILDFILE ]]; then
2766 error "$(gettext "%s does not exist.")" "$BUILDFILE"
2769 # PKGBUILD passed through a pipe
2770 BUILDFILE=/dev/stdin
2771 source_safe "$BUILDFILE"
2774 crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
2775 if [[ -n $crlftest ]]; then
2776 error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
2780 if [[ ${BUILDFILE:0:1} != "/" ]]; then
2781 BUILDFILE="$startdir/$BUILDFILE"
2783 source_safe "$BUILDFILE"
2786 # set defaults if they weren't specified
in buildfile
2787 pkgbase
=${pkgbase:-${pkgname[0]}}
2790 if [[ $BUILDDIR = "$startdir" ]]; then
2791 srcdir
="$BUILDDIR/src"
2792 pkgdirbase
="$BUILDDIR/pkg"
2794 srcdir
="$BUILDDIR/$pkgbase/src"
2795 pkgdirbase
="$BUILDDIR/$pkgbase/pkg"
2799 # set pkgdir to something "sensible" for (not recommended) use during build()
2800 pkgdir
="$pkgdirbase/$pkgbase"
2802 if (( GENINTEG
)); then
2806 download_sources fast
2811 if declare -f pkgver
>/dev
/null
; then
2815 # check the PKGBUILD for some basic requirements
2816 check_sanity
|| exit 1
2818 # check we have the software required to process the PKGBUILD
2819 check_software
|| exit 1
2821 if (( ${#pkgname[@]} > 1 )); then
2825 # test for available PKGBUILD functions
2826 if declare -f prepare
>/dev
/null
; then
2829 if declare -f build
>/dev
/null
; then
2832 if declare -f check
>/dev
/null
; then
2833 # "Hide" check() function if not going to be run
2834 if [[ $RUN_CHECK = 'y' ]] || { ! check_buildenv
"check" "n" && [[ $RUN_CHECK != "n" ]]; }; then
2838 if declare -f package
>/dev
/null
; then
2840 elif [[ $SPLITPKG -eq 0 ]] && declare -f package_
${pkgname} >/dev
/null
; then
2844 if [[ -n "${PKGLIST[@]}" ]]; then
2846 pkgname
=("${PKGLIST[@]}")
2849 # check if gpg signature is to be created and if signing key is valid
2850 if { [[ -z $SIGNPKG ]] && check_buildenv
"sign" "y"; } || [[ $SIGNPKG == 'y' ]]; then
2852 if ! gpg
--list-key ${GPGKEY} &>/dev
/null
; then
2853 if [[ ! -z $GPGKEY ]]; then
2854 error
"$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}"
2856 error
"$(gettext "There is no key in your keyring.")"
2862 if (( ! PKGVERFUNC
)); then
2866 # Run the bare minimum in fakeroot
2867 if (( INFAKEROOT
)); then
2868 if (( SOURCEONLY
)); then
2870 msg
"$(gettext "Leaving %s environment.")" "fakeroot"
2874 chmod 755 "$pkgdirbase"
2875 if (( ! SPLITPKG
)); then
2876 pkgdir
="$pkgdirbase/$pkgname"
2878 if (( ! PKGFUNC
)); then
2879 if (( ! REPKG
)); then
2880 if (( BUILDFUNC
)); then
2882 (( CHECKFUNC
)) && run_check
2885 warning
"$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
2886 plain
"$(gettext "File permissions may not be preserved.")"
2893 create_debug_package
2898 msg
"$(gettext "Leaving %s environment.")" "fakeroot"
2902 fullver
=$(get_full_version)
2903 msg
"$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
2905 if (( !PKGFUNC
&& !SPLITPKG
)); then
2906 warning
"$(gettext "Using a %s without a %s function is deprecated.")" "$BUILDSCRIPT" "package()"
2909 # if we are creating a source-only package, go no further
2910 if (( SOURCEONLY
)); then
2911 if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
2912 && (( ! FORCE
)); then
2913 error
"$(gettext "A source package has already been built. (use %s to overwrite)")" "-f"
2917 # Get back to our src directory so we can begin with sources.
2921 if (( SOURCEONLY == 2 )); then
2923 elif ( (( ! SKIPCHECKSUMS )) || \
2924 ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then
2925 download_sources fast
2927 check_source_integrity
2930 # if we are root or if fakeroot is not enabled, then we don't use it
2931 if ! check_buildenv "fakeroot
" "y
" || (( EUID == 0 )); then
2937 msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))"
2941 if (( NODEPS || (NOBUILD && !DEP_BIN ) )); then
2942 # no warning message needed for nobuild
2943 if (( NODEPS )); then
2944 warning "$(gettext "Skipping dependency checks.")"
2947 if (( RMDEPS && ! INSTALL )); then
2948 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2952 msg "$(gettext "Checking runtime dependencies...")"
2953 resolve_deps ${depends[@]} || deperr=1
2955 if (( RMDEPS && INSTALL )); then
2956 original_pkglist=($(run_pacman -Qq)) # required by remove_dep
2959 msg "$(gettext "Checking buildtime dependencies...")"
2960 resolve_deps ${makedepends[@]} || deperr=1
2962 if (( CHECKFUNC )); then
2963 resolve_deps ${checkdepends[@]} || deperr=1
2966 if (( RMDEPS )); then
2967 current_pkglist=($(run_pacman -Qq)) # required by remove_deps
2970 if (( deperr )); then
2971 error "$(gettext "Could not resolve all dependencies.")"
2976 # ensure we have a sane umask set
2979 # get back to our src directory so we can begin with sources
2984 if (( NOEXTRACT && ! VERIFYSOURCE )); then
2985 warning "$(gettext "Using existing %s tree")" "src
/"
2986 elif (( REPKG )); then
2987 if (( ! PKGFUNC && ! SPLITPKG )) \
2988 && { [[ ! -d $pkgdirbase ]] || dir_is_empty "$pkgdirbase"; }; then
2989 error "$(gettext "The package directory is empty, there is nothing to repackage!")"
2990 plain "$(gettext "Aborting...")"
2995 check_source_integrity
2996 (( VERIFYSOURCE )) && exit 0 # $E_OK
2998 if (( PREPAREFUNC )); then
3003 if (( NOBUILD )); then
3004 msg "$(gettext "Sources are ready.")"
3007 # check for existing pkg directory; don't remove if we are repackaging
3008 if [[ -d $pkgdirbase ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
3009 msg "$(gettext "Removing existing %s directory...")" "pkg
/"
3010 rm -rf "$pkgdirbase"
3012 mkdir -p "$pkgdirbase"
3013 chmod a-srwx "$pkgdirbase"
3016 # if we are root or if fakeroot is not enabled, then we don't use it
3017 if ! check_buildenv "fakeroot
" "y
" || (( EUID == 0 )); then
3018 if (( ! REPKG )); then
3019 if (( ! ( SPLITPKG || PKGFUNC ) )); then
3020 chmod 755 "$pkgdirbase"
3023 (( BUILDFUNC )) && run_build
3024 (( CHECKFUNC )) && run_check
3026 chmod 755 "$pkgdirbase"
3027 if (( ! SPLITPKG )); then
3028 pkgdir="$pkgdirbase/$pkgname"
3030 if (( PKGFUNC )); then
3032 elif (( REPKG )); then
3033 warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package
()"
3034 plain "$(gettext "File permissions may not be preserved.")"
3038 create_debug_package
3043 if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
3044 (( BUILDFUNC )) && run_build
3045 (( CHECKFUNC )) && run_check
3053 fullver=$(get_full_version)
3054 msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))"
3060 # vim: set ts=2 sw=2 noet: