projects/aports·blob v2.25.0_rc1 · refs

2211 lines · 54.4 KiB

1#!/bin/sh
2
3# abuild - build apk packages (light version of makepkg)
4# Copyright (c) 2008-2015 Natanael Copa <[email protected]>
5#
6# Distributed under GPL-2
7#
8
9program_version=@VERSION@
10sysconfdir=@sysconfdir@
11abuildrepo_base=@abuildrepo@
12datadir=@datadir@
13
14abuild_path=$(readlink -f $0)
15
16if ! [ -f "$datadir/functions.sh" ]; then
17 echo "$datadir/functions.sh: not found" >&2
18 exit 1
19fi
20. "$datadir/functions.sh"
21
22# defaults
23BUILD_BASE="build-base"
24
25: ${FAKEROOT:="fakeroot"}
26: ${SUDO_APK:="abuild-apk"}
27: ${APK:="apk"}
28: ${ADDUSER:="abuild-adduser"}
29: ${ADDGROUP:="abuild-addgroup"}
30
31apk_opt_wait="--wait 30"
32
33# run optional log command for remote logging
34logcmd() {
35 ${ABUILD_LOG_CMD:-true} "$@"
36 return 0
37}
38
39# we override the default msg, warning and error as we want the pkgname
40msg() {
41 [ -n "$quiet" ] && return 0
42 local prompt="$GREEN>>>${NORMAL}"
43 local fake="${FAKEROOTKEY:+${BLUE}*${NORMAL}}"
44 local name="${STRONG}${subpkgname:-$pkgname}${NORMAL}"
45 printf "${prompt} ${name}${fake}: %s\n" "$1" >&2
46}
47
48warning() {
49 local prompt="${YELLOW}>>> WARNING:${NORMAL}"
50 local fake="${FAKEROOTKEY:+${BLUE}*${NORMAL}}"
51 local name="${STRONG}${subpkgname:-$pkgname}${NORMAL}"
52 printf "${prompt} ${name}${fake}: %s\n" "$1" >&2
53}
54
55error() {
56 local prompt="${RED}>>> ERROR:${NORMAL}"
57 local fake="${FAKEROOTKEY:+${BLUE}*${NORMAL}}"
58 local name="${STRONG}${subpkgname:-$pkgname}${NORMAL}"
59 printf "${prompt} ${name}${fake}: %s\n" "$1" >&2
60 logcmd "ERROR: $pkgname: $1"
61}
62
63cross_compiling() {
64 test "$CBUILD" != "$CHOST" -a -n "$CBUILDROOT"
65}
66
67cleanup() {
68 local i=
69 set_xterm_title ""
70 if [ -n "$CLEANUP_FILES" ]; then
71 rm -f $CLEANUP_FILES
72 fi
73 for i; do
74 case $i in
75 pkgdir) msg "Cleaning up pkgdir"; rm -rf "$pkgbasedir";;
76 srcdir) msg "Cleaning up srcdir"; rm -rf "$srcdir";;
77 deps)
78 if [ -z "$install_after" ] && [ -n "$uninstall_after" ]; then
79 msg "Uninstalling dependencies..."
80 $SUDO_APK del --quiet $apk_opt_wait $uninstall_after
81 if cross_compiling; then
82 $SUDO_APK del --root "$CBUILDROOT" \
83 --quiet $apk_opt_wait \
84 $uninstall_after
85 fi
86 fi
87 ;;
88 esac
89 done
90}
91
92die() {
93 error "$@"
94 cleanup $ERROR_CLEANUP
95 exit 1
96}
97
98spell_error() {
99 die "APKBUILD contains '$1'. It should be '$2'"
100}
101
102# check if apkbuild is basicly sane
103default_sanitycheck() {
104 local i= j= suggestion=
105 msg "Checking sanity of $APKBUILD..."
106 [ -z "$pkgname" ] && die "Missing pkgname in APKBUILD"
107 [ -z "${pkgname##* *}" ] && die "pkgname contains spaces"
108 [ -z "$pkgver" ] && die "Missing pkgver in APKBUILD"
109 if [ "$pkgver" != "volatile" ] && [ -z "$nodeps" ]; then
110 $APK version --check --quiet "$pkgver" ||\
111 die "$pkgver is not a valid version"
112 fi
113 [ -z "$pkgrel" ] && die "Missing pkgrel in APKBUILD"
114 [ -z "$pkgdesc" ] && die "Missing pkgdesc in APKBUILD"
115 [ -z "$url" ] && die "Missing url in APKBUILD"
116 [ -z "$license" ] && die "Missing license in APKBULID"
117 if [ $(echo "$pkgdesc" | wc -c) -gt 128 ]; then
118 die "pkgdesc is too long"
119 fi
120 is_function package || warning "Missing package() function in APKBUILD"
121
122 if [ -n "$replaces_priority" ] \
123 && ! echo $replaces_priority | egrep -q '^[0-9]+$'; then
124 die "replaces_priority must be a number"
125 fi
126 # check so no package names starts with -
127 for i in $pkgname $subpackages; do
128 case $i in
129 -*) die "${i%:*} is not a valid package name";;
130 esac
131 done
132
133 # check if CARCH, CBUILD, CHOST and CTARGET is set
134 [ -z "$CHOST" ] && die "Please set CHOST in /etc/abuild.conf"
135
136 if [ -z "$CARCH" ]; then
137 die "Please fix CHOST, or set CARCH in abuild.conf"
138 fi
139
140 for i in $install; do
141 local n=${i%.*}
142 local suff=${i##*.}
143 case "$suff" in
144 pre-install|post-install|pre-upgrade|post-upgrade|pre-deinstall|post-deinstall);;
145 *) die "$i: unknown install script suffix"
146 esac
147 if ! subpackages_has "$n" && [ "$n" != "$pkgname" ]; then
148 die "$i: install script does not match pkgname or any subpackage"
149 fi
150 [ -e "$startdir/$i" ] || die "install script $i is missing"
151 for j in chown chmod chgrp; do
152 if grep -q $j "$startdir"/$i; then
153 warning "$i: found $j"
154 warning2 "Permissions should be fixed in APKBUILD package()"
155 fi
156 done
157 done
158
159 for i in $triggers; do
160 local f=${i%=*}
161 local p=${f%.trigger}
162 [ "$f" = "$i" ] && die "$f: triggers must contain '='"
163 [ "$p" = "$f" ] && die "$f: triggers scripts must have .trigger suffix"
164 if ! subpackages_has "$p" && [ "$p" != "$pkgname" ]; then
165 die "$p: trigger script does not match pkgname or any subpackage"
166 fi
167
168 [ -e "$startdir"/$f ] || die "trigger script $f is missing"
169 done
170 if [ -n "$source" ]; then
171 for i in $source; do
172 if install_has "$i"; then
173 warning "You should not have \$install in source"
174 continue
175 fi
176 case "$i" in
177 *::*) i=${i%%::*};;
178 https://*) makedepends_has wget && warning "wget no longer need to be in makedepends when source has https://" ;;
179 esac
180 list_has ${i##*/} $md5sums $sha256sums $sha512sums \
181 || die "${i##*/} is missing in checksums"
182
183 # verify that our source does not have git tag version
184 # name as tarball (typicallly github)
185 if is_remote "$i" && [ "${i#*::}" = "$i" ]; then
186 case ${i##*/} in
187 v$pkgver.tar.*|$pkgver.tar.*)
188 die "source ${i##*/} needs to be renamed to avoid possible collisions"
189 ;;
190 esac
191 fi
192 done
193 fi
194
195 # verify that things listed in checksum also is listed in source
196 local algo=
197 for algo in md5 sha256 sha512; do
198 eval set -- \$${algo}sums
199 while [ $# -gt 1 ]; do
200 local file="$2"
201 shift 2
202 source_has $file || die "$file exists in ${algo}sums but is missing in source"
203 done
204 done
205
206 # common spelling errors
207 [ -n "$depend" ] && spell_error depend depends
208 [ -n "$makedepend" ] && spell_error makedepend makedepends
209 [ -n "$pkguser" ] && spell_error pkguser pkgusers
210 [ -n "$pkggroup" ] && spell_error pkggroup pkggroups
211 [ -n "$subpackage" ] && spell_error subpackage subpackages
212
213 check_maintainer || die "Provide a valid RFC822 maintainer address"
214
215 check_depends_dev || warning "depends_dev found but no development subpackage found"
216
217 makedepends_has 'g++' && warning "g++ should not be in makedepends"
218 return 0
219}
220
221sanitycheck() {
222 default_sanitycheck
223}
224
225sumcheck() {
226 local algo="$1" sums="$2"
227 local dummy f endreturnval originalparams origin file
228
229 # get number of checksums
230 set -- $sums
231 local numsums=$(( $# / 2 ))
232
233 set -- $source
234 if [ $# -ne $numsums ]; then
235 die "Number of ${algo}sums($numsums) does not correspond to number of sources($#)"
236 fi
237 fetch || return 1
238 msg "Checking ${algo}sums..."
239 cd "$srcdir" || return 1
240 IFS=$'\n'
241 endreturnval=0
242 for src in $sums; do
243 origin=$1; shift
244 echo "$src" | ${algo}sum -c
245 if [ $? -ne 0 ]; then
246 endreturnval=1
247 is_remote $origin || continue
248 echo "Because the remote file above failed the ${algo}sum check it will be deleted."
249 echo "Rebuilding will cause it to re-download which in some cases may fix the problem."
250 file=`echo "$src" | sed 's/.*[ \t\n]\(.*\)/\1/'`
251 echo "Deleting: $file"
252 rm $file
253 fi
254 done
255 unset IFS
256 return $endreturnval
257}
258
259# for compatibility
260md5check() {
261 warning "'md5check' is deprecated. Use 'verify' instead"
262 sumcheck md5 "$md5sums"
263}
264
265# verify checksums
266verify() {
267 local verified=false algo=
268 for algo in sha512 sha256 sha1 md5; do
269 local sums=
270 eval sums=\"\$${algo}sums\"
271 if [ -z "$sums" ] || [ -z "$source" ]; then
272 continue
273 fi
274 sumcheck "$algo" "$sums" || return 1
275 verified=true
276 break
277 done
278 if [ -n "$source" ] && ! $verified; then
279 die "Use 'abuild checksum' to generate/update the checksum(s)"
280 fi
281 return 0
282}
283
284# verify upstream sources
285sourcecheck() {
286 local uri
287 for uri in $source; do
288 is_remote $uri || continue
289 case "$uri" in
290 saveas-*://*)
291 uri=${uri#saveas-}
292 uri=${uri%/*}
293 ;;
294 *::*)
295 uri=${uri##*::}
296 ;;
297 esac
298 wget -q -s "$uri" || return 1
299 done
300 return 0
301}
302
303uri_fetch() {
304 local uri="$1"
305 [ -n "$quiet" ] && opts="-s"
306
307 mkdir -p "$SRCDEST"
308 abuild-fetch -d "$SRCDEST" "$uri"
309}
310
311is_remote() {
312 case "${1#*::}" in
313 http://*|ftp://*|https://*|saveas-*://*)
314 return 0;;
315 esac
316 return 1
317}
318
319filename_from_uri() {
320 local uri="$1"
321 local filename="${uri##*/}" # $(basename $uri)
322 case "$uri" in
323 *::*) filename=${uri%%::*};;
324 esac
325 echo "$filename"
326}
327
328# try download from file from mirror first
329uri_fetch_mirror() {
330 local uri="$1"
331 if [ -n "$DISTFILES_MIRROR" ]; then
332 if is_remote "$DISTFILES_MIRROR"; then
333 uri_fetch "$DISTFILES_MIRROR"/$(filename_from_uri $uri)\
334 && return 0
335 else
336 cp "$DISTFILES_MIRROR"/$(filename_from_uri $uri) \
337 "$SRCDEST" && return 0
338 fi
339 fi
340 uri_fetch "$uri"
341}
342
343default_fetch() {
344 local s
345 mkdir -p "$srcdir"
346 for s in $source; do
347 if is_remote "$s"; then
348 uri_fetch_mirror "$s" || return 1
349 ln -sf "$SRCDEST/$(filename_from_uri $s)" "$srcdir"/
350 else
351 ln -sf "$startdir/$s" "$srcdir/"
352 fi
353 done
354}
355
356fetch() {
357 default_fetch
358}
359
360# verify that all init.d scripts are openrc runscripts
361initdcheck() {
362 local i line
363 for i in $source; do
364 case $i in
365 *.initd) line=$(head -n 1 "$srcdir"/$i);;
366 *) continue ;;
367 esac
368
369 case "$line" in
370 *sbin/openrc-run)
371 ;;
372 *sbin/runscript)
373 warning "$i is not an openrc #!/sbin/openrc-run"
374 ;;
375 *) error "$i is not an openrc #!/sbin/openrc-run"
376 return 1
377 ;;
378 esac
379 done
380}
381
382# unpack the sources
383default_unpack() {
384 local u
385 if [ -z "$force" ]; then
386 verify || return 1
387 initdcheck || return 1
388 fi
389 mkdir -p "$srcdir"
390 for u in $source; do
391 local s="$SRCDEST/$(filename_from_uri $u)"
392 case "$s" in
393 *.tar)
394 msg "Unpacking $s..."
395 tar -C "$srcdir" -xf "$s" || return 1;;
396 *.tar.gz|*.tgz)
397 msg "Unpacking $s..."
398 tar -C "$srcdir" -zxf "$s" || return 1;;
399 *.tar.bz2)
400 msg "Unpacking $s..."
401 tar -C "$srcdir" -jxf "$s" || return 1;;
402 *.tar.lzma)
403 msg "Unpacking $s..."
404 unlzma -c "$s" | tar -C "$srcdir" -x \
405 || return 1;;
406 *.tar.xz)
407 msg "Unpacking $s..."
408 unxz -c "$s" | tar -C "$srcdir" -x || return 1;;
409 *.zip)
410 msg "Unpacking $s..."
411 unzip "$s" -d "$srcdir" || return 1;;
412 esac
413 done
414}
415
416unpack() {
417 default_unpack
418}
419
420# cleanup source and package dir
421clean() {
422 msg "Cleaning temporary build dirs..."
423 rm -rf "$srcdir"
424 rm -rf "$pkgbasedir"
425}
426
427# cleanup fetched sources
428cleancache() {
429 local s
430 for s in $source; do
431 if is_remote "$s"; then
432 s=$(filename_from_uri $s)
433 msg "Cleaning downloaded $s ..."
434 rm -f "$SRCDEST/$s"
435 fi
436 done
437}
438
439listpkgnames() {
440 local i
441 for i in $pkgname $subpackages; do
442 echo ${i%:*}
443 done
444 for i in $linguas; do
445 echo $pkgname-lang-$i
446 done
447}
448
449cleanpkg() {
450 local i
451 getpkgver || return 1
452 msg "Cleaning built packages..."
453 for i in $(listpkgnames); do
454 local p="${i%:*}-$pkgver-r$pkgrel"
455 rm -f "$PKGDEST/$p.apk" "$PKGDEST/$p.src.tar.gz" \
456 "$abuildrepo"/$p.apk "$abuildrepo"/*/$p.apk
457 done
458 # remove given packages from index
459 update_abuildrepo_index
460}
461
462# clean all packages except current
463cleanoldpkg() {
464 local i j
465 getpkgver || return 1
466 msg "Cleaning all packages except $pkgver-r$pkgrel..."
467 for i in $(listpkgnames); do
468 local pn=${i%:*}
469 for j in "$PKGDEST"/$pn-[0-9]*.apk ; do
470 [ "$j" = "$PKGDEST/$pn-$pkgver-r$pkgrel.apk" ] \
471 && continue
472 rm -f "$j" "$abuildrepo"/*/${j##*/}
473 done
474 done
475 update_abuildrepo_index
476 return 0
477}
478
479mkusers() {
480 local i
481 for i in $pkggroups; do
482 if ! getent group $i >/dev/null; then
483 msg "Creating group $i"
484 $ADDGROUP -S $i || return 1
485 fi
486 done
487 for i in $pkgusers; do
488 if ! getent passwd $i >/dev/null; then
489 local gopt=
490 msg "Creating user $i"
491 if getent group $i >/dev/null; then
492 gopt="-G $i"
493 fi
494 $ADDUSER -S -D -H $gopt $i || return 1
495 fi
496 done
497}
498
499# helper to update config.sub to a recent version
500update_config_sub() {
501 local changed=false
502 find . -name config.sub | while read f; do
503 if ! ./$f armv6-alpine-linux-muslgnueabihf 2>/dev/null; then
504 msg "Updating $f"
505 cp "$datadir"/${f##*/} "$f" || return 1
506 changed=true
507 else
508 msg "No update needed for $f"
509 fi
510 # pipe subshell will return status of last command
511 $changed
512 done
513 return $?
514}
515
516runpart() {
517 local part=$1
518 [ -n "$DEBUG" ] && msg "$part"
519 $part || die "$part failed"
520}
521
522# override those in your build script
523getpkgver() {
524 # this func is supposed to be overridden by volatile packages
525 if [ "$pkgver" = "volatile" ]; then
526 error "Please provide a getpkgver() function in your APKBUILD"
527 return 1
528 fi
529}
530
531prepare() {
532 :
533}
534
535build() {
536 :
537}
538
539# generate a simple tar.gz package of pkgdir
540targz() {
541 cd "$pkgdir" || return 1
542 mkdir -p "$PKGDEST"
543 tar -czf "$PKGDEST"/$pkgname-$pkgver-r$pkgrel.tar.gz *
544}
545
546get_split_func() {
547 # get the 'func' from "sub-pkg:func"
548 local func=${1##*:}
549
550 # get 'func' from "sub-pkg-func" if there was no :func
551 [ "$func" = "$1" ] && func=${func##*-}
552 echo $func
553}
554
555postcheck() {
556 local dir="$1" name="$2" i=
557 msg "Running postcheck for $name"
558 # checking for FHS compat
559 if ! options_has "!fhs"; then
560 for i in "$dir"/srv/* "$dir"/usr/local/* "$dir"/opt/*; do
561 if [ -e "$i" ]; then
562 error "Packages must not put anything under /srv, /usr/local or /opt"
563 return 1
564 fi
565 done
566 if [ -d "$dir"/usr/var ]; then
567 error "Found /usr/var, localstatedir is most likely wrong"
568 return 1
569 fi
570 fi
571
572 # remove *.la files if libtool is not set
573 if ! options_has "libtool"; then
574 find "$dir" -name '*.la' -type f -delete
575 fi
576
577 # look for /usr/lib/charset.alias
578 if [ -e "$dir"/usr/lib/charset.alias ] \
579 && ! options_has "charset.alias"; then
580 error "Found /usr/lib/charset.alias"
581 return 1
582 fi
583 # look for /usr/share/doc
584 if [ -e "$dir"/usr/share/doc ] \
585 && ! is_doc_pkg "$name"; then
586 warning "Found /usr/share/doc but package name doesn't end with -doc"
587 fi
588 # look for /usr/share/man
589 if [ -e "$dir"/usr/share/man ]; then
590 if ! is_doc_pkg "$name"; then
591 warning "Found /usr/share/man but package name doesn't end with -doc"
592 fi
593 # check for uncompressed man pages
594 i=$(find "$dir"/usr/share/man -name '*.[0-9]' -type f | sed "s|^$dir|\t|")
595 if [ -n "$i" ]; then
596 error "Found uncompressed man pages:"
597 echo "$i"
598 return 1
599 fi
600 fi
601 # check directory permissions
602 i=$(find "$dir" -type d -perm -777 | sed "s|^$dir|\t|")
603 if [ -n "$i" ]; then
604 warning "World writeable directories found:"
605 echo "$i"
606 fi
607 # check so we dont have any suid root binaries that are not PIE
608 i=$(find "$dir" -type f -perm +6000 \
609 | xargs scanelf --nobanner --etype ET_EXEC \
610 | sed "s|ET_EXEC $dir|\t|")
611 if [ -n "$i" ]; then
612 error "Found non-PIE files that has SUID:"
613 echo "$i"
614 return 1
615 fi
616 # test suid bit on executable
617 if ! options_has "suid"; then
618 i=$(find "$dir" \( -perm -u+s -o -perm -g+s \) -a -type f \
619 -a -perm -o+x)
620 if [ -n "$i" ]; then
621 error "Found executable files with SUID bit set:"
622 echo "$i"
623 return 1
624 fi
625 fi
626
627 # test for textrels
628 if ! options_has "textrels"; then
629 local res="$(scanelf --recursive --textrel --quiet "$dir")"
630 if [ -n "$res" ]; then
631 error "Found textrels:"
632 echo "$res"
633 return 1
634 fi
635 fi
636 return 0
637}
638
639pre_split() {
640 if [ -z "$subpkgname" ]; then
641 return 0
642 fi
643 # the subpackages should not inherit those form main package
644 provides=""
645 install_if=""
646 apkbuild_arch="$arch"
647}
648
649prepare_subpackages() {
650 local i
651 cd "$startdir"
652 for i in $subpackages; do
653 local func=$(get_split_func $i)
654 # call abuild recursively, setting subpkg{dir,name}
655 msg "Running split function $func..."
656 local dir="$pkgbasedir/${i%:*}" name="${i%:*}"
657 ( subpkgdir="$dir" subpkgname="$name" \
658 $0 pre_split $func prepare_package \
659 && postcheck "$dir" "$name" ) || return 1
660 done
661 postcheck "$pkgdir" "$pkgname" || return 1
662 # post check for /usr/share/locale
663 if [ -d "$pkgdir"/usr/share/locale ]; then
664 warning "Found /usr/share/locale"
665 warning2 "Maybe add \$pkgname-lang to subpackages?"
666 fi
667}
668
669default_lang() {
670 pkgdesc="Languages for package $pkgname"
671 install_if="$pkgname=$pkgver-r$pkgrel lang"
672 arch="noarch"
673 local dir
674 for dir in ${langdir:-/usr/share/locale}; do
675 mkdir -p "$subpkgdir"/${dir%/*}
676 mv "$pkgdir"/"$dir" "$subpkgdir"/"$dir" || return 1
677 done
678}
679
680lang() {
681 default_lang
682}
683
684default_lang_subpkg() {
685 if [ -z "$lang" ]; then
686 error "lang is not set"
687 return 1
688 fi
689 pkgdesc="$pkgname language pack for $lang"
690 arch="noarch"
691 install_if="$pkgname=$pkgver-r$pkgrel lang-$lang"
692 local dir
693 for dir in ${langdir:-/usr/share/locale}; do
694 mkdir -p "$subpkgdir"/$dir
695 mv "$pkgdir"/$dir/$lang* \
696 "$subpkgdir"/$dir/ \
697 || return 1
698 done
699}
700
701lang_subpkg() {
702 default_lang_subpkg
703}
704
705prepare_language_packs() {
706 for lang in $linguas; do
707 lang="$lang" \
708 subpkgname="$pkgname-lang-$lang" \
709 subpkgdir="$pkgbasedir"/$subpkgname \
710 $0 lang_subpkg prepare_package || return 1
711 done
712}
713
714# echo '-dirty' if git is not clean
715git_dirty() {
716 if [ $(git status -s "$startdir" | wc -l) -ne 0 ]; then
717 echo "-dirty"
718 fi
719}
720
721# echo last commit hash id
722git_last_commit() {
723 git log --format=oneline -n 1 "$startdir" | awk '{print $1}'
724}
725
726get_maintainer() {
727 if [ -z "$maintainer" ]; then
728 maintainer=$(awk -F': ' '/\# *Maintainer/ {print $2}' "$APKBUILD")
729 # remove surrounding whitespace
730 maintainer=$(echo "$maintainer" | xargs)
731 fi
732}
733
734
735
736check_maintainer() {
737 get_maintainer
738 if [ -z "$maintainer" ]; then
739 warning "No maintainer"
740 else
741 # try to check for a valid rfc822 address
742 case "$maintainer" in
743 *[A-Za-z0-9]*\ \<*@*.*\>) ;;
744 *) return 1 ;;
745 esac
746 fi
747}
748
749check_depends_dev() {
750 if [ -z "$depends_dev" ]; then
751 return 0
752 fi
753 local i
754 for i in $pkgname $subpackages; do
755 case "$i" in
756 *-dev) return 0 ;;
757 esac
758 done
759 return 1
760}
761
762prepare_metafiles() {
763 getpkgver || return 1
764 local name=${subpkgname:-$pkgname}
765 [ -z "${name##* *}" ] && die "package name contains spaces"
766 local dir=${subpkgdir:-$pkgdir}
767 local pkg="$name-$pkgver-r$pkgrel.apk"
768 local pkginfo="$controldir"/.PKGINFO
769 local sub
770
771 [ ! -d "$dir" ] && die "Missing $dir"
772 cd "$dir"
773 mkdir -p "$controldir"
774 local builddate=$(date -u "+%s")
775 local size=$(du -sk | awk '{print $1 * 1024}')
776 local parch="$CARCH"
777
778 # we need to wait with setting noarch til our build infra can handle it
779# if [ "$arch" = "noarch" ]; then
780# parch="noarch"
781# fi
782
783 # save arch incase subpackages set it different than main pkg
784 if [ "${apkbuild_arch:-$arch}" != "$arch" ]; then
785 echo "$arch" > "$controldir"/.arch
786 fi
787
788 echo "# Generated by $(basename $0) $program_version" >"$pkginfo"
789 if [ -n "$FAKEROOTKEY" ]; then
790 echo "# using $($FAKEROOT -v)" >> "$pkginfo"
791 fi
792 echo "# $(date -u)" >> "$pkginfo"
793 cat >> "$pkginfo" <<EOF
794pkgname = $name
795pkgver = $pkgver-r$pkgrel
796pkgdesc = $pkgdesc
797url = $url
798builddate = $builddate
799packager = ${PACKAGER:-"Unknown"}
800size = $size
801arch = $parch
802origin = $pkgname
803EOF
804 local i deps
805 deps="$depends"
806 if [ "$pkgname" != "busybox" ] && ! depends_has busybox; then
807 for i in $install $triggers; do
808 local s=${i%=*}
809 [ "$name" != "${s%.*}" ] && continue
810 if head -n 1 "$startdir/$s" | grep '^#!/bin/sh' >/dev/null ; then
811 msg "Script found. busybox added as a dependency for $pkg"
812 deps="$deps busybox"
813 break
814 fi
815 done
816 fi
817
818 # store last_commit in global var so we only call git once
819 if [ -z "$last_commit" ]; then
820 last_commit="$(git_last_commit)$(git_dirty)"
821 fi
822 echo "commit = $last_commit" >> "$pkginfo"
823
824 get_maintainer
825 if [ -n "$maintainer" ]; then
826 echo "maintainer = $maintainer" >> "$pkginfo"
827 fi
828
829 if [ -n "$replaces_priority" ]; then
830 echo "replaces_priority = $replaces_priority" >> "$pkginfo"
831 fi
832
833 echo "license = $license" >> "$pkginfo"
834 for i in $replaces; do
835 echo "replaces = $i" >> "$pkginfo"
836 done
837 for i in $deps; do
838 echo "depend = $i" >> "$pkginfo"
839 done
840 for i in $provides; do
841 echo "provides = $i" >> "$pkginfo"
842 done
843 for i in $triggers; do
844 local f=${i%=*}
845 local dirs=${i#*=}
846 [ "${f%.trigger}" != "$name" ] && continue
847 echo "triggers = ${dirs//:/ }" >> "$pkginfo"
848 done
849 if [ -n "$install_if" ]; then
850 echo "install_if = $(echo $install_if)" >> "$pkginfo"
851 fi
852
853 local metafiles=".PKGINFO"
854 for i in $install $triggers; do
855 local f=${i%=*}
856 local n=${f%.*}
857 if [ "$n" != "$name" ]; then
858 continue
859 fi
860 script=${f#$name}
861 msg "Adding $script"
862 cp "$startdir/$f" "$controldir/$script" || return 1
863 chmod +x "$controldir/$script"
864 metafiles="$metafiles $script"
865 done
866 echo $metafiles | tr ' ' '\n' > "$controldir"/.metafiles
867}
868
869prepare_trace_rpaths() {
870 local dir=${subpkgdir:-$pkgdir}
871 local etype= soname= file= sover=
872 [ "$arch" = "noarch" ] && return 0
873 options_has "!tracedeps" && return 0
874 # lets tell all the places we should look for .so files - all rpaths
875 scanelf --quiet --recursive --rpath "$dir" \
876 | sed -e 's/[[:space:]].*//' -e 's/:/\n/' | sort -u \
877 >"$controldir"/.rpaths
878 if grep -q -x '/usr/lib' "$controldir"/.rpaths; then
879 warning "Redundant /usr/lib in rpath found"
880 fi
881 if grep '^/home/' "$controldir"/.rpaths; then
882 error "Has /home/... in rpath"
883 return 1
884 fi
885}
886
887# search for broken symlinks so we later can pull in proper depends
888prepare_symlinks() {
889 local dir="${subpkgdir:-$pkgdir}"
890 options_has "!tracedeps" && return 0
891 cd "$dir" || return 1
892 find -type l | while read symlink; do
893 if ! [ -e "$symlink" ]; then
894 echo "$symlink $(readlink $symlink)" \
895 >> "$controldir"/.symlinks
896 fi
897 done
898}
899
900prepare_pkgconfig_provides() {
901 local dir="${subpkgdir:-$pkgdir}"
902 options_has "!tracedeps" && return 0
903 cd "$dir" || return 1
904 for i in usr/lib/pkgconfig/*.pc; do
905 if ! [ -e "$i" ]; then
906 continue
907 fi
908 local f=${i##*/}
909 local v=$(PKG_CONFIG_PATH="$dir"/usr/lib/pkgconfig pkg-config \
910 --modversion ${f%.pc})
911 echo "${f%.pc}=${v:-0}" >> "$controldir"/.provides-pc
912 done
913}
914
915# check if dir has arch specific binaries
916dir_has_arch_binaries() {
917 local dir="$1"
918 # if scanelf returns something, then we have binaries
919 [ -n "$(scanelf -R "$dir" | head -n 1)" ] && return 0
920
921 # look for static *.a
922 [ -n "$(find "$dir" -type f -name '*.a' | head -n 1)" ] && return 0
923
924 return 1
925}
926
927# returns true if this is the -dev package
928is_dev_pkg() {
929 test "${subpkgname%-dev}" != "$subpkgname"
930}
931
932# returns true if this is the -doc package
933is_doc_pkg() {
934 test "${1%-doc}" != "$1"
935}
936
937# check that noarch is set if needed
938archcheck() {
939 options_has "!archcheck" && return 0
940 if dir_has_arch_binaries "${subpkgdir:-$pkgdir}"; then
941 [ "$arch" != "noarch" ] && return 0
942 error "Arch specific binaries found so arch must not be set to \"noarch\""
943 return 1
944 elif [ "$arch" != "noarch" ] && ! is_dev_pkg; then
945 # we dont want -dev package go to noarch
946 warning "No arch specific binaries found so arch should probably be set to \"noarch\""
947 fi
948 return 0
949}
950
951prepare_package() {
952 msg "Preparing ${subpkgname:+sub}package ${subpkgname:-$pkgname}..."
953 stripbin
954 prepare_metafiles \
955 && prepare_trace_rpaths \
956 && prepare_symlinks \
957 && prepare_pkgconfig_provides \
958 || return 1
959 archcheck
960}
961
962pkginfo_val() {
963 local key="$1"
964 local file="$2"
965 awk -F ' = ' "\$1 == \"$key\" {print \$2}" "$file"
966}
967
968# find real path to so files
969real_so_path() {
970 local so="$1"
971 shift
972 while [ $# -gt 0 ]; do
973 [ -e "$1"/$so ] && realpath "$1/$so" && return 0
974 shift
975 done
976 error "$so: path not found"
977 return 1
978}
979
980# search rpaths and /usr/lib /lib for given so files
981find_so_files() {
982 local rpaths=$(cat "$1")
983 shift
984 while [ $# -gt 0 ]; do
985 real_so_path "$1" /usr/lib /lib $rpaths || return 1
986 shift
987 done
988 return 0
989}
990
991subpkg_provides_prefixed_so() {
992 [ -n "$sonameprefix" ] && grep -q -w "^$sonameprefix$1" \
993 "$pkgbasedir"/.control.*/.provides-so 2>/dev/null
994}
995
996subpkg_provides_so() {
997 grep -q -w "^$1" "$pkgbasedir"/.control.*/.provides-so 2>/dev/null
998}
999
1000subpkg_provides_pc() {
1001 grep -q -w "^${1%%[<>=]*}" "$pkgbasedir"/.control.*/.provides-pc \
1002 2>/dev/null
1003}
1004
1005trace_apk_deps() {
1006 local name="$1"
1007 local dir="$2"
1008 local i= found= autodeps= deppkgs= missing=
1009 msg "Tracing dependencies..."
1010 # add pkgconfig if usr/lib/pkgconfig is found
1011 if [ -d "$pkgbasedir"/$name/usr/lib/pkgconfig ] \
1012 && ! grep -q '^depend = pkgconfig' "$dir"/.PKGINFO; then
1013 autodeps="$autodeps pkgconfig"
1014 fi
1015
1016 # special case for libpthread: we need depend on libgcc
1017 if [ "$CLIBC" = "uclibc" ] && [ -f "$dir"/.needs-so ] \
1018 && grep -q -w '^libpthread.so.*' "$dir"/.needs-so \
1019 && ! grep -q -w "^depend = libgcc" "$dir"/.PKGINFO; then
1020 autodeps="$autodeps libgcc"
1021 msg " added libgcc (due to libpthread)"
1022 fi
1023
1024 [ -f "$dir"/.needs-so ] && for i in $(cat "$dir"/.needs-so); do
1025 # first check if its provided by same apkbuild
1026 grep -q -w "^$sonameprefix$i" "$dir"/.provides-so 2>/dev/null && continue
1027
1028 if subpkg_provides_prefixed_so "$i"; then
1029 autodeps="$autodeps so:$sonameprefix$i"
1030 elif subpkg_provides_so "$i" || cross_compiling \
1031 || $APK info --quiet --installed "so:$i"; then
1032 autodeps="$autodeps so:$i"
1033 else
1034 missing="$missing $i"
1035 fi
1036 done
1037
1038 # find all packages that holds the so files
1039 if [ -f "$dir"/.rpaths ]; then
1040 local so_files=$(find_so_files "$dir"/.rpaths $missing) \
1041 || return 1
1042 deppkgs=$($APK info --quiet --who-owns $so_files) || return 1
1043 fi
1044
1045 for found in $deppkgs; do
1046 if grep -w "^depend = ${found}$" "$dir"/.PKGINFO >/dev/null ; then
1047 warning "You can remove '$found' from depends"
1048 continue
1049 fi
1050 autodeps="$autodeps $found"
1051 done
1052
1053 # symlink targets
1054 for i in $(sort -u "$dir"/.symlinks-needs 2>/dev/null); do
1055 autodeps="$autodeps $i"
1056 done
1057
1058 # pkg-config depends
1059 for i in $(sort -u "$dir"/.needs-pc 2>/dev/null); do
1060 if subpkg_provides_pc "$i" || cross_compiling \
1061 || $APK info --quiet --installed "pc:$i"; then
1062 local provider=$(apk search --quiet "pc:$i")
1063 if list_has "$provider" $depends_dev; then
1064 warning "$provider should be removed from depends_dev"
1065 fi
1066 autodeps="$autodeps pc:$i"
1067 else
1068 warning "Could not find any provider for pc:$i"
1069 local pcfile=/usr/lib/pkgconfig/"${i%%[<>=]*}".pc
1070 if [ -e "$pcfile" ]; then
1071 local owner=$($APK info --quiet --who-owns $pcfile)
1072 warning "${owner:-package providing $pcfile} needs to be rebuilt"
1073 fi
1074 fi
1075 done
1076
1077 echo "# automatically detected:" >> "$dir"/.PKGINFO
1078 if [ -f "$dir"/.provides-so ]; then
1079 sed 's/^\(.*\) \([0-9].*\)/provides = so:\1=\2/' "$dir"/.provides-so \
1080 >> "$dir"/.PKGINFO
1081 fi
1082 if [ -f "$dir"/.provides-pc ]; then
1083 sed 's/^/provides = pc:/' "$dir"/.provides-pc | sort -u \
1084 >> "$dir"/.PKGINFO
1085 fi
1086 [ -z "$autodeps" ] && return 0
1087 for i in $autodeps; do
1088 echo "depend = $i"
1089 done | sort -u >> "$dir"/.PKGINFO
1090 # display all depends
1091 sed -n '/^depend =/s/depend = /\t/p' "$dir"/.PKGINFO >&2
1092}
1093
1094find_scanelf_paths() {
1095 local datadir="$1"
1096 local paths="$datadir/lib:$datadir/usr/lib" i= rpaths=
1097 if [ -n "$ldpath" ]; then
1098 paths="$paths:$(echo "${datadir}${ldpath}" | sed "s|:|:$datadir|g")"
1099 fi
1100 # search in all rpaths
1101 for rpaths in "$pkgbasedir"/.control.*/.rpaths; do
1102 [ -f "$rpaths" ] || continue
1103 while read i; do
1104 local dir="${datadir}${i}"
1105 IFS=:
1106 if [ -d "$dir" ] && ! list_has "$dir" $paths; then
1107 paths="$paths:${dir}"
1108 fi
1109 unset IFS
1110 done < "$rpaths"
1111 done
1112 echo "$paths"
1113}
1114
1115scan_shared_objects() {
1116 local name="$1" controldir="$2" datadir="$3"
1117 local opt= i=
1118
1119 if [ "$arch" = "noarch" ] && ! [ -e "$controldir"/.arch ]; then
1120 return 0
1121 fi
1122
1123 # allow spaces in paths
1124 IFS=:
1125 set -- $(find_scanelf_paths "$datadir")
1126 unset IFS
1127
1128 # sanity check, verify that each path is prefixed with datadir
1129 for i; do
1130 if [ "${i#$datadir}" = "$i" ]; then
1131 error "Internal error in scanelf paths"
1132 return 1
1133 fi
1134 done
1135
1136 if options_has "ldpath-recursive"; then
1137 opt="--recursive"
1138 fi
1139 msg "Scanning shared objects"
1140 # lets tell all the .so files this package provides in .provides-so
1141 scanelf --nobanner --soname $opt "$@" | while read etype soname file; do
1142 # if soname field is missing, soname will be the filepath
1143 sover=0
1144 if [ -z "$file" ]; then
1145 file="$soname"
1146 soname=${soname##*/}
1147 fi
1148
1149 # we only want shared libs
1150 case $soname in
1151 *.so|*.so.[0-9]*|*.c32);;
1152 *) continue;;
1153 esac
1154
1155 case "$file" in
1156 *.so.[0-9]*) sover=${file##*.so.};;
1157 *.so)
1158 # filter out sonames with version when file does not
1159 # have version
1160 case "$soname" in
1161 *.so.[0-9]*)
1162 if options_has "sover-namecheck"; then
1163 continue
1164 fi
1165 esac
1166 ;;
1167 esac
1168 list_has "$soname" $somask && continue
1169 echo "$sonameprefix$soname $sover"
1170 # use awk to filter out dupes that has sover = 0
1171 done | awk '{ if (so[$1] == 0) so[$1] = $2; }
1172 END { for (i in so) print(i " " so[i]); }' \
1173 | sort -u > "$controldir"/.provides-so
1174
1175 # verify that we dont have any duplicates
1176 local dupes="$(cut -d' ' -f1 "$controldir"/.provides-so | uniq -d)"
1177 if [ -n "$dupes" ]; then
1178 die "provides multiple versions of same shared object: $dupes"
1179 fi
1180
1181 # now find the so dependencies
1182 scanelf --nobanner --recursive --needed "$datadir" | tr ' ' ':' \
1183 | awk -F ":" '$2 != "" && ($1 == "ET_DYN" || $1 == "ET_EXEC") {print $2}' \
1184 | sed 's:,:\n:g' | sort -u \
1185 | while read soname; do
1186 # only add files that are not self provided
1187 grep -q -w "^$sonameprefix$soname" "$controldir"/.provides-so \
1188 || list_has "$soname" $somask \
1189 || echo $soname
1190 done > "$controldir"/.needs-so
1191}
1192
1193# normalize a path string
1194normalize_path() {
1195 local oifs="$IFS" pathstr= i=
1196 IFS='/'
1197 set -- $1
1198 for i; do
1199 case "$i" in
1200 "."|"") continue;;
1201 "..") pathstr="${pathstr%%/${pathstr##*/}}";;
1202 *) pathstr="${pathstr}/$i";;
1203 esac
1204 done
1205 echo "$pathstr"
1206}
1207
1208# find which package provides file that symlink points to
1209scan_symlink_targets() {
1210 local name="$1" dir="$2" datadir="$3"
1211 local symfile= targetpath=
1212 cd "$datadir"
1213 for symfile in "$pkgbasedir"/.control.*/.symlinks; do
1214 local d="${symfile%/.symlinks}"
1215 if ! [ -e "$symfile" ] || [ "$d" = "$dir" ]; then
1216 continue
1217 fi
1218
1219 while read symlink target; do
1220 if [ "${target#/}" = "$target" ]; then
1221 target="${symlink%/*}/$target"
1222 fi
1223 targetpath="$datadir"/$(normalize_path "$target")
1224 if [ -e "$targetpath" ] || [ -L "$targetpath" ]; then
1225 echo "$name=$pkgver-r$pkgrel" \
1226 >> "$d"/.symlinks-needs
1227 fi
1228 done < "$symfile"
1229 done
1230}
1231
1232#find pkg-config dependencies
1233scan_pkgconfig_depends() {
1234 local provides_pc="$1" controldir= name= datadir=
1235 [ -e "$provides_pc" ] || return 0
1236 controldir="${provides_pc%/*}"
1237 name="$(pkginfo_val pkgname "$controldir"/.PKGINFO)"
1238 datadir="$pkgbasedir"/$name
1239 for i in $(sort -u "$provides_pc"); do
1240 PKG_CONFIG_PATH="$datadir"/usr/lib/pkgconfig pkg-config \
1241 --print-requires \
1242 --print-requires-private ${i%=*} \
1243 | sed -E 's/\s*([<>=]+)\s*/\1/' \
1244 | while read pc; do
1245 # only add files that are not self provided
1246 if ! grep -q -w "^${pc%%[<>=]*}" "$provides_pc"; then
1247 echo "$pc" >> "$controldir"/.needs-pc
1248 fi
1249 done
1250 done
1251}
1252
1253# read size in bytes from stdin and show as human readable
1254human_size() {
1255 awk '{ split("B KB MB GB TB PB", type)
1256 for(i=5; y < 1 && $1 > 0; i--)
1257 y = $1 / (2**(10*i))
1258 printf("%.1f %s\n", y, type[i+2]) }'
1259}
1260
1261create_apks() {
1262 local file= dir= name= ver= apk= datadir= size=
1263 getpkgver || return 1
1264 mkdir -p "$PKGDEST"
1265 if ! options_has "!tracedeps"; then
1266 for file in "$pkgbasedir"/.control.*/.PKGINFO; do
1267 dir="${file%/.PKGINFO}"
1268 name="$(pkginfo_val pkgname $file)"
1269 datadir="$pkgbasedir"/$name
1270 subpkgname=$name
1271 scan_shared_objects "$name" "$dir" "$datadir"
1272 scan_symlink_targets "$name" "$dir" "$datadir"
1273 done
1274 for file in "$pkgbasedir"/.control.*/.provides-pc; do
1275 scan_pkgconfig_depends "$file"
1276 done
1277 fi
1278
1279 for file in "$pkgbasedir"/.control.*/.PKGINFO; do
1280 dir="${file%/.PKGINFO}"
1281 name=$(pkginfo_val pkgname $file)
1282 ver=$(pkginfo_val pkgver $file)
1283 size=$(pkginfo_val size $file | human_size)
1284 apk=$name-$ver.apk
1285 datadir="$pkgbasedir"/$name
1286 subpkgname=$name
1287
1288 trace_apk_deps "$name" "$dir" || return 1
1289 msg "Package size: ${size}"
1290 msg "Compressing data..."
1291 (
1292 cd "$datadir"
1293 # data.tar.gz
1294 set -- *
1295 if [ "$1" = '*' ]; then
1296 touch .dummy
1297 set -- .dummy
1298 fi
1299 tar --xattrs -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz
1300
1301 msg "Create checksum..."
1302 # append the hash for data.tar.gz
1303 local sha256=$(sha256sum "$dir"/data.tar.gz | cut -f1 -d' ')
1304 echo "datahash = $sha256" >> "$dir"/.PKGINFO
1305
1306 # control.tar.gz
1307 cd "$dir"
1308 tar -c $(cat "$dir"/.metafiles) | abuild-tar --cut \
1309 | gzip -9 > control.tar.gz
1310 abuild-sign -q control.tar.gz || exit 1
1311
1312 msg "Create $apk"
1313 # create the final apk
1314 cat control.tar.gz data.tar.gz > "$PKGDEST"/$apk
1315 )
1316 done
1317 subpkgname=
1318}
1319
1320clean_abuildrepo() {
1321 local apk
1322 cd "$abuildrepo" || return 1
1323
1324 # remove compat symlink
1325 for d in "$abuildrepo/$CARCH"; do
1326 [ -L "$d" ] && rm "$d"
1327 done
1328
1329 # remove broken links from abuildrepo
1330 for apk in *.apk */*.apk; do
1331 if [ -L "$apk" ] && [ ! -f "$apk" ]; then
1332 rm -f "$apk"
1333 fi
1334 done
1335}
1336
1337mklinks_abuildrepo() {
1338 [ -n "$REPODEST" ] && return 0
1339 local apk
1340 mkdir -p "$abuildrepo"/$CARCH
1341 cd "$abuildrepo" || return 1
1342 # create links for this package
1343 for apk in $(listpkg); do
1344 [ -f "$PKGDEST"/$apk ] || continue
1345 ln -sf "$PKGDEST"/$apk "$abuildrepo"/$CARCH/$apk
1346 done
1347}
1348
1349build_abuildrepo() {
1350 local d apk _build=build
1351 if ! is_function package; then
1352 # if package() is missing then build is called from rootpkg
1353 _build=true
1354 fi
1355 if ! apk_up2date || [ -n "$force" ]; then
1356 # check early if we have abuild key
1357 abuild-sign --installed || return 1
1358 logcmd "building ${abuildrepo##*/}/$pkgname-$pkgver-r$pkgrel"
1359 sanitycheck && builddeps && clean && fetch && unpack \
1360 && prepare && mkusers && $_build && rootpkg \
1361 && cleanup $CLEANUP \
1362 || return 1
1363 fi
1364 update_abuildrepo_index
1365}
1366
1367update_abuildrepo_index() {
1368 clean_abuildrepo
1369 mklinks_abuildrepo
1370
1371 cd "$abuildrepo"
1372 local index=$CARCH/APKINDEX.tar.gz
1373
1374 msg "Updating the cached abuild repository index..."
1375 local sign=".SIGN.RSA.${SIGN_PUBLIC_KEY##*/}"
1376 local oldindex=
1377 if [ -f "$index" ]; then
1378 oldindex="--index $index"
1379 fi
1380 $APK index --quiet $oldindex --output "$index".unsigned \
1381 --description "$repo $(cd $startdir && git describe)" \
1382 --rewrite-arch $CARCH \
1383 $CARCH/*.apk || exit 1
1384 msg "Signing the index..."
1385 abuild-sign -q "$index".unsigned || exit 1
1386 mv "$index".unsigned "$index"
1387 chmod 644 "$index"
1388}
1389
1390# predefined splitfunc doc
1391default_doc() {
1392 depends="$depends_doc"
1393 pkgdesc="$pkgdesc (documentation)"
1394 arch=${arch_doc:-"noarch"}
1395 install_if="docs $pkgname=$pkgver-r$pkgrel"
1396
1397 local i
1398 for i in doc man info html sgml licenses gtk-doc ri help; do
1399 if [ -d "$pkgdir/usr/share/$i" ]; then
1400 mkdir -p "$subpkgdir/usr/share"
1401 mv "$pkgdir/usr/share/$i" "$subpkgdir/usr/share/"
1402 fi
1403 done
1404
1405 # compress man pages
1406 local previnode= prevname= mandir="$subpkgdir"/usr/share/man
1407 [ -d "$mandir" ] && find "$subpkgdir"/usr/share/man \
1408 -type f \( -name \*.[0-9n] -o -name \*.[0-9][a-z]* \) \
1409 -exec stat -c "%i %n" {} \; | sort -n \
1410 | while read inode name; do
1411
1412 if [ "$inode" = "$previnode" ]; then
1413 # update hard link
1414 rm "$name"
1415 ln "$prevname".gz "$name".gz
1416 else
1417 gzip -9 "$name"
1418 fi
1419
1420 previnode="$inode"
1421 prevname="$name"
1422 done
1423 [ -d "$mandir" ] && find "$subpkgdir"/usr/share/man \
1424 -type l \( -name \*.[0-9n] -o -name \*.[0-9][a-z]* \) \
1425 | while read symlink; do
1426
1427 ln -s $(readlink $symlink).gz "$symlink".gz
1428 rm "$symlink"
1429 done
1430
1431 rm -f "$subpkgdir/usr/share/info/dir"
1432
1433 # remove if empty, ignore error (not empty)
1434 rmdir "$pkgdir/usr/share" "$pkgdir/usr" 2>/dev/null
1435
1436 return 0
1437}
1438
1439doc() {
1440 default_doc
1441}
1442
1443# predefined splitfunc doc
1444default_dbg() {
1445 local f
1446 binfiles=$(scanelf -R "$pkgdir" | grep ET_DYN | sed "s:$pkgdir\/::g" | sed "s:ET_DYN ::g")
1447 for f in $binfiles; do
1448 srcdir=$(dirname $pkgdir/$f)
1449 srcfile=$(basename $pkgdir/$f)
1450 dstdir=$(dirname $subpkgdir/usr/lib/debug/$f.debug)
1451 dstfile=$(basename $subpkgdir/usr/lib/debug/$f.debug)
1452 if [ ! -d $dstdir ] ; then
1453 mkdir -p $dstdir
1454 fi
1455 cd $srcdir
1456 objcopy --only-keep-debug $srcfile $dstfile
1457 objcopy --add-gnu-debuglink=$dstfile $srcdir/$srcfile
1458 mv $dstfile $dstdir
1459 strip $srcfile
1460 done
1461 return 0
1462}
1463
1464dbg() {
1465 default_dbg
1466}
1467
1468# predefined splitfunc dev
1469default_dev() {
1470 local i= j=
1471 depends="$depends_dev"
1472 pkgdesc="$pkgdesc (development files)"
1473
1474 cd "$pkgdir" || return 0
1475 local libdirs=usr/
1476 [ -d lib/ ] && libdirs="lib/ $libdirs"
1477 for i in usr/include usr/lib/pkgconfig usr/share/aclocal\
1478 usr/share/gettext usr/bin/*-config \
1479 usr/share/vala/vapi usr/share/gir-[0-9]*\
1480 usr/share/qt*/mkspecs \
1481 usr/lib/qt*/mkspecs \
1482 usr/lib/cmake \
1483 $(find . -name include -type d) \
1484 $(find $libdirs -name '*.[acho]' \
1485 -o -name '*.prl' 2>/dev/null); do
1486 if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
1487 d="$subpkgdir/${i%/*}" # dirname $i
1488 mkdir -p "$d"
1489 mv "$pkgdir/$i" "$d"
1490 rmdir "$pkgdir/${i%/*}" 2>/dev/null
1491 fi
1492 done
1493 # move *.so links needed when linking the apps to -dev packages
1494 for i in lib/*.so usr/lib/*.so; do
1495 if [ -L "$i" ]; then
1496 mkdir -p "$subpkgdir"/"${i%/*}"
1497 mv "$i" "$subpkgdir/$i" || return 1
1498 fi
1499 done
1500 return 0
1501}
1502
1503dev() {
1504 default_dev
1505}
1506
1507# predefined splitfunc libs
1508default_libs() {
1509 pkgdesc="$pkgdesc (libraries)"
1510 local dir= file=
1511 for dir in lib usr/lib; do
1512 for file in "$pkgdir"/$dir/lib*.so.[0-9]*; do
1513 [ -f "$file" ] || continue
1514 mkdir -p "$subpkgdir"/$dir
1515 mv "$file" "$subpkgdir"/$dir/
1516 done
1517 done
1518}
1519
1520libs() {
1521 default_libs
1522}
1523
1524is_function() {
1525 type "$1" 2>&1 | head -n 1 | egrep -q "is a (shell )?function"
1526}
1527
1528do_fakeroot() {
1529 if [ -n "$FAKEROOT" ]; then
1530 $FAKEROOT -- "$@"
1531 else
1532 "$@"
1533 fi
1534}
1535
1536# build and package in fakeroot
1537rootpkg() {
1538 local _package=package
1539 if ! is_function package; then
1540 # if package() is missing then run 'build' in fakeroot instead
1541 warning "No package() function in APKBUILD"
1542 _package=build
1543 fi
1544 cd "$startdir"
1545 rm -rf "$pkgdir"
1546 [ -n "$FAKEROOT" ] && msg "Entering fakeroot..."
1547 do_fakeroot "$abuild_path" $color_opt \
1548 $_package \
1549 prepare_subpackages \
1550 prepare_language_packs \
1551 prepare_package \
1552 create_apks
1553}
1554
1555srcpkg() {
1556 getpkgver || return 1
1557 local p="$pkgname-$pkgver-$pkgrel"
1558 local prefix="${startdir##*/}"
1559 local i files="$prefix/APKBUILD"
1560 for i in $source; do
1561 files="$files $prefix/$(filename_from uri $i)"
1562 done
1563 mkdir -p "$PKGDEST"
1564 msg "Creating source package $p.src.tar.gz..."
1565 (cd .. && tar -zcf "$PKGDEST/$p.src.tar.gz" $files)
1566}
1567
1568# return true if arch is supported or noarch
1569check_arch() {
1570 list_has $CARCH $arch || [ "$arch" = "noarch" ] || [ "$arch" = "all" ]
1571}
1572
1573# return true if libc is not masked in options
1574check_libc() {
1575 ! list_has "!libc_$CLIBC" $options
1576}
1577
1578# check if package is up to date
1579apk_up2date() {
1580 getpkgver || return 1
1581 local pkg="$PKGDEST/$pkgname-$pkgver-r$pkgrel.apk"
1582 local i s
1583 cd "$startdir"
1584 for i in $pkgname $subpackages; do
1585 [ -f "$PKGDEST/$pkgname-$pkgver-r$pkgrel.apk" ] || return 1
1586 done
1587 [ -n "$keep" ] && return 0
1588
1589 for i in $source APKBUILD; do
1590 local s
1591 if is_remote "$i"; then
1592 s="$SRCDEST/$(filename_from_uri $i)"
1593 else
1594 s="$startdir/${i##*/}"
1595 fi
1596 if [ "$s" -nt "$pkg" ]; then
1597 return 1
1598 fi
1599 done
1600 return 0
1601}
1602
1603abuildindex_up2date() {
1604 local i
1605 getpkgver || return 1
1606 local dir="$abuildrepo"/$CARCH
1607 local apk="${pkgname%:*}-$pkgver-r$pkgrel.apk"
1608 local idx="$dir"/APKINDEX.tar.gz
1609 local file="$dir"/$apk
1610
1611 # check if index is missing
1612 [ -f "$idx" ] || return 1
1613
1614 # if link or file is missing, then we need update abuildrepo index
1615 [ -f "$file" ] || return 1
1616
1617 # if file exists and is newer than index, then we need update index
1618 [ "$file" -nt "$idx" ] && return 1
1619
1620 return 0
1621}
1622
1623up2date() {
1624 check_arch || return 0
1625 check_libc || return 0
1626 apk_up2date && abuildindex_up2date
1627}
1628
1629# rebuild package and abuildrepo index if needed
1630abuildindex() {
1631 up2date && return 0
1632 build_abuildrepo
1633}
1634
1635# source all APKBUILDs and output:
1636# 1) origin of package
1637# 2) all dependencies
1638# the output is i in a format easy parseable for awk
1639parse_aports_makedepends() {
1640 # lets run this in a subshell since we source all APKBUILD here
1641 (
1642 aportsdir=$(realpath ${APKBUILD%/APKBUILD}/..)
1643 for i in $aportsdir/*/APKBUILD; do
1644 # no forks in this loop or it will be painfully slow!
1645 pkgname=
1646 subpackages=
1647 depends=
1648 makedepends=
1649 . $i
1650 dir=${i%/APKBUILD}
1651 deps=
1652 # filter out conflicts from deps and version info
1653 for j in $depends $makedepends; do
1654 case "$j" in
1655 !*) continue;;
1656 esac
1657 deps="$deps ${j%%[<>=]*}"
1658 done
1659 for j in $pkgname $subpackages; do
1660 echo "o ${j%%:*} $dir"
1661 set -- $deps
1662 echo -n "d ${j%%:*} $1"
1663 shift
1664 while [ $# -gt 0 ]; do
1665 echo -n ",$1"
1666 shift
1667 done
1668 echo
1669 done
1670 done
1671 )
1672}
1673
1674trace_makedepends() {
1675 local deps= i=
1676 # strip versions from deps
1677 for i in "$@"; do
1678 deps="$deps ${i%%[<>=]*}"
1679 done
1680 [ -z "$deps" ] && return 0
1681 ( parse_aports_makedepends
1682 if [ -z "$upgrade" ]; then
1683 # list installed pkgs and prefix with 'i '
1684 $APK info --quiet | sort | sed 's/^/i /'
1685 fi
1686 ) | awk -v pkgs="$deps" '
1687
1688 function depgraph(pkg, a, i) {
1689 if (visited[pkg])
1690 return 0;
1691 visited[pkg] = 1;
1692 split(deps[pkg], a, ",");
1693 for (i in a)
1694 depgraph(a[i]);
1695 print pkg ":" origin[pkg];
1696
1697 }
1698
1699 $1 == "i" { visited[$2] = 1 }
1700 $1 == "o" { origin[$2] = $3 }
1701 $1 == "d" { deps[$2] = $3 }
1702 END {
1703 split(pkgs, pkgarray);
1704 for (i in pkgarray)
1705 depgraph(pkgarray[i]);
1706 }
1707 '
1708}
1709
1710# build and install dependencies
1711builddeps() {
1712 local pkg= i= missing=
1713 local hostdeps= builddeps= installed_hostdeps= installed_builddeps=
1714 [ -n "$nodeps" ] && return 0
1715 msg "Analyzing dependencies..."
1716
1717 # add depends unless it is a subpackage or package itself
1718 if cross_compiling && [ -n "$makedepends_build" -o -n "$makedepends_host" ]; then
1719 builddeps="$makedepends_build"
1720 for i in $BUILD_BASE; do
1721 [ "$pkgname" = "${i%%[<>=]*}" ] && continue
1722 subpackages_has ${i%%[<>=]*} || builddeps="$builddeps $i"
1723 done
1724 hostdeps="$makedepends_host"
1725 for i in $depends; do
1726 [ "$pkgname" = "${i%%[<>=]*}" ] && continue
1727 subpackages_has ${i%%[<>=]*} || hostdeps="$hostdeps $i"
1728 done
1729 else
1730 builddeps="$makedepends"
1731 for i in $BUILD_BASE $depends; do
1732 [ "$pkgname" = "${i%%[<>=]*}" ] && continue
1733 subpackages_has ${i%%[<>=]*} || builddeps="$builddeps $i"
1734 done
1735 fi
1736
1737 installed_builddeps=$($APK info --installed $builddeps)
1738 [ -n "$hostdeps" ] && installed_hostdeps=$($APK info --root "$CBUILDROOT" --installed $hostdeps)
1739
1740 # find which deps are missing
1741 for i in $builddeps; do
1742 if [ "${i#\!}" != "$i" ] && $APK info --quiet --installed "${i#\!}"; then
1743 error "Conflicting package installed: ${i#\!}"
1744 elif ! deplist_has $i $installed_builddeps || [ -n "$upgrade" ]; then
1745 missing="$missing $i"
1746 fi
1747 done
1748 for i in $hostdeps; do
1749 if [ "${i#\!}" != "$i" ] && $APK info --quiet --installed --root "$CBUILDROOT" "${i#\!}"; then
1750 error "Conflicting package installed: ${i#\!}"
1751 elif ! deplist_has $i $installed_hostdeps || [ -n "$upgrade" ]; then
1752 missing="$missing $i"
1753 fi
1754 done
1755
1756 if [ -z "$install_deps" ] && [ -z "$recursive" ]; then
1757 # if we dont have any missing deps we are done now
1758 [ -z "$missing" ] && return 0
1759 error "Missing dependencies: $missing Use -r to autoinstall or -R to build"
1760 return 1
1761 fi
1762
1763 uninstall_after=".makedepends-$pkgname $uninstall_after"
1764 if [ -n "$install_deps" ] && [ -z "$recursive" ]; then
1765 # make a --simulate run first to detect missing deps
1766 # apk-tools --virtual is no goot at reporting those.
1767 $SUDO_APK add --repository "$abuildrepo" $apk_opt_wait \
1768 --simulate --quiet $builddeps || return 1
1769 $SUDO_APK add --repository "$abuildrepo" $apk_opt_wait \
1770 --virtual .makedepends-$pkgname $builddeps || return 1
1771 if [ -n "$hostdeps" ]; then
1772 $SUDO_APK add --root "$CBUILDROOT" --repository "$abuildrepo" $apk_opt_wait \
1773 --simulate --quiet $hostdeps || return 1
1774 $SUDO_APK add --root "$CBUILDROOT" --repository "$abuildrepo" $apk_opt_wait \
1775 --virtual .makedepends-$pkgname $hostdeps || return 1
1776 fi
1777 return 0
1778 fi
1779
1780 if [ -n "$CBUILDROOT" ]; then
1781 error "Recursive rebuilding is not supported when cross compiling."
1782 return 1
1783 fi
1784 [ -z "$recursive" ] && return 1
1785
1786 # find dependencies that are installed but missing in repo.
1787 for i in $builddeps; do
1788 local m=$($APK search --repository "$abuildrepo" ${i%%[<>=]*})
1789 if [ -z "$m" ]; then
1790 missing="$missing $i"
1791 fi
1792 done
1793
1794 for i in $(trace_makedepends $missing); do
1795 # i = pkg:dir
1796 local dir=${i#*:}
1797 local pkg=${i%:*}
1798
1799 # ignore if dependency is in other repo
1800 [ -d "$dir" ] || continue
1801
1802 # check if dep is blacklisted
1803 if list_has $pkg $ABUILD_BLACKLIST; then
1804 error "$pkg is blacklisted"
1805 return 1
1806 fi
1807
1808 # break circular deps
1809 list_has $pkg $ABUILD_VISITED && continue
1810 export ABUILD_VISITED="$ABUILD_VISITED $pkg"
1811
1812 msg "Entering $dir"
1813 cd "$dir" && $0 $forceroot $keep $quiet $install_deps \
1814 $recursive $upgrade $color_opt abuildindex || return 1
1815 done
1816 $SUDO_APK add --upgrade --repository "$abuildrepo" \
1817 $apk_opt_wait \
1818 --virtual .makedepends-$pkgname $builddeps
1819}
1820
1821# replace the md5sums in the APKBUILD
1822checksum() {
1823 local s files
1824 [ -z "$source" ] && [ -n "${md5sums}${sha256sums}${sha512sums}" ] \
1825 && msg "Removing checksums from APKBUILD"
1826 sed -i -e '/^md5sums="/,/"\$/d; /^md5sums=''/,/''\$/d' "$APKBUILD"
1827 sed -i -e '/^sha512sums="/,/"\$/d; /^sha512sums=''/,/''\$/d' "$APKBUILD"
1828 sed -i -e '/^sha256sums="/,/"\$/d; /^sha256sums=''/,/''\$/d' "$APKBUILD"
1829 [ -z "$source" ] && return 0
1830 fetch
1831 for s in $source; do
1832 files="$files $(filename_from_uri $s)"
1833 done
1834
1835 # for compatibility/backporting reasons we still add md5sum
1836 msg "Updating the md5sums in APKBUILD..."
1837 md5sums="$(cd "$srcdir" && md5sum $files)" || die "md5sum failed"
1838 echo "md5sums=\"$md5sums\"" >>"$APKBUILD"
1839
1840 msg "Updating the sha256sums in APKBUILD..."
1841 sha256sums="$(cd "$srcdir" && sha256sum $files)" \
1842 || die "sha256sum failed"
1843 echo "sha256sums=\"$sha256sums\"" >>"$APKBUILD"
1844
1845 msg "Updating the sha512sums in APKBUILD..."
1846 sha512sums="$(cd "$srcdir" && sha512sum $files)" \
1847 || die "sha512sum failed"
1848 echo "sha512sums=\"$sha512sums\"" >>"$APKBUILD"
1849}
1850
1851stripbin() {
1852 local bin
1853 if options_has "!strip" || [ "$arch" = "noarch" ]; then
1854 return 0
1855 fi
1856 cd "${subpkgdir:-$pkgdir}" || return 1
1857 msg "Stripping binaries"
1858 scanelf --recursive --nobanner --etype "ET_DYN,ET_EXEC" . \
1859 | sed -e 's:^ET_DYN ::' -e 's:^ET_EXEC ::' \
1860 | while read filename; do
1861 XATTR=$(getfattr --match="*" --dump "${filename}")
1862 ${CROSS_COMPILE}strip "${filename}"
1863 [ -n "$XATTR" ] && (echo "$XATTR" | setfattr --restore=-)
1864 done
1865}
1866
1867# simply list target apks
1868listpkg() {
1869 local name
1870 getpkgver || return 1
1871 for name in $(listpkgnames) ; do
1872 echo "$name-$pkgver-r$pkgrel.apk"
1873 done
1874}
1875
1876source_has() {
1877 local i
1878 for i in $source; do
1879 [ "$1" = "${i##*/}" ] && return 0
1880 [ "$1" = "${i%%::*}" ] && return 0
1881 done
1882 return 1
1883}
1884
1885subpackages_has() {
1886 local i
1887 for i in $subpackages; do
1888 [ "$1" = "${i%:*}" ] && return 0
1889 done
1890 return 1
1891}
1892
1893subpackage_types_has() {
1894 local i
1895 for i in $subpackages; do
1896 [ "$1" = "${i##*-}" ] && return 0
1897 done
1898 return 1
1899}
1900
1901list_has() {
1902 local needle="$1"
1903 local i
1904 shift
1905 for i in $@; do
1906 [ "$needle" = "$i" ] && return 0
1907 [ "$needle" = "!$i" ] && return 1
1908 done
1909 return 1
1910}
1911
1912# same as list_has but we filter version info
1913deplist_has() {
1914 local needle="$1"
1915 local i
1916 shift
1917 for i in $@; do
1918 i=${i%%[<>=]*}
1919 [ "$needle" = "$i" ] && return 0
1920 [ "$needle" = "!$i" ] && return 1
1921 done
1922 return 1
1923}
1924
1925options_has() {
1926 list_has "$1" $options
1927}
1928
1929depends_has() {
1930 deplist_has "$1" $depends
1931}
1932
1933makedepends_has() {
1934 deplist_has "$1" $makedepends
1935}
1936
1937md5sums_has() {
1938 list_has "$1" $md5sums
1939}
1940
1941install_has() {
1942 list_has "$1" $install
1943}
1944
1945# install package after build
1946post_add() {
1947 getpkgver || return 1
1948 local pkgf="$PKGDEST/$1-$pkgver-r$pkgrel.apk"
1949 local deps i
1950 if ! subpackages_has $1 && [ "$1" != "$pkgname" ]; then
1951 die "$1 is not built by this APKBUILD"
1952 fi
1953 # recursively install dependencies that are provided by this APKBUILD
1954 deps=$($APK index "$pkgf" 2>/dev/null | awk -F: '$1=="D" { print $2 }')
1955 for i in $deps; do
1956 if subpackages_has $i || [ "$i" = "$pkgname" ]; then
1957 post_add $i || return 1
1958 fi
1959 done
1960 $SUDO_APK add $apk_opt_wait --upgrade "$pkgf" \
1961 || die "Failed to install $1"
1962}
1963
1964deps() {
1965 local builddeps i
1966 builddeps="$makedepends"
1967 for i in $depends; do
1968 [ "$pkgname" = "${i%%[<>=]*}" ] && continue
1969 subpackages_has ${i%%[<>=]*} || builddeps="$builddeps $i"
1970 done
1971 $SUDO_APK add $apk_opt_wait --repository "$abuildrepo" \
1972 --virtual .makedepends-$pkgname \
1973 $builddeps
1974}
1975
1976undeps (){
1977 $SUDO_APK del $apk_opt_wait .makedepends-$pkgname
1978 if cross_compiling; then
1979 $SUDO_APK del --root "$CBUILDROOT" $apk_opt_wait \
1980 .makedepends-$pkgname
1981 fi
1982}
1983
1984# compat
1985installdeps() { deps; }
1986uninstalldeps() { undeps; }
1987index() { update_abuildrepo_index; }
1988
1989all() {
1990 if ! [ -n "$force" ]; then
1991 check_arch
1992 if [ $? -ne 0 ]; then
1993 echo "Package not available for the target architecture ($CARCH). Aborting."
1994 return 0
1995 fi
1996 check_libc || return 0
1997 fi
1998 if up2date && [ -z "$force" ]; then
1999 msg "Package is up to date"
2000 else
2001 build_abuildrepo
2002 fi
2003}
2004
2005# This abuild hook will checkout an svn or git repository by specifying
2006# $svnurl or $giturl in APKBUILD. You can checkout a specific branch in
2007# git by adding -b $branch in $giturl. $reporev will select the correct
2008# commit, revision or tag for you. If you specify $disturl your distfile
2009# will automatically be uploaded with rsync to the url provided.
2010# Base version defaults to 0 except if specified by $verbase.
2011
2012snapshot() {
2013 # check if we setup vars correctly
2014 [ -z "$disturl" ] && warning "Missing disturl in APKBUILD, auto uploading disabled."
2015 [ -z "$svnurl" ] && [ -z "$giturl" ] && die "Missding repository url in APKBUILD!"
2016 [ -n "$svnurl" ] && [ -n "$giturl" ] && die "You can only use a single repository!"
2017 local _date=$(date +%Y%m%d)
2018 local _format="tar.gz"
2019 # remove any repositories left in srcdir
2020 abuild clean
2021 mkdir -p "$srcdir" && cd "$srcdir"
2022 # clone git repo and archive
2023 if [ -n "$giturl" ]; then
2024 local _version=${verbase:-0}_git${_date}
2025 command -v git >/dev/null || \
2026 die "Missing git! Install git to support git clone."
2027 [ -z "$reporev" ] && local _rev="HEAD" && local _depth="--depth=1"
2028 msg "Creating git snapshot: $pkgname-$_version"
2029 git clone $_depth --bare $giturl $pkgname-$_version || return 1
2030 git --git-dir $pkgname-$_version archive \
2031 --format=$_format \
2032 -o $pkgname-$_version.$_format \
2033 --prefix=$pkgname-$_version/ $_rev \
2034 || return 1
2035 fi
2036 # export svn repo and archive
2037 if [ -n "$svnurl" ]; then
2038 local _version=${verbase:-0}_svn${_date}
2039 command -v svn >/dev/null || \
2040 die "Missing svn! Install subverion to support svn export."
2041 [ -n "$reporev" ] && local _rev="-r $reporev"
2042 msg "Creating svn snapshot: $pkgname-$_version"
2043 svn co $_rev $svnurl $pkgname-$_version || return 1
2044 tar zcf $pkgname-$_version.$_format $pkgname-$_version || return 1
2045 fi
2046 # upload to defined distfiles url
2047 if [ -n "$disturl" ]; then
2048 command -v rsync >/dev/null || \
2049 die "Missing rsync! Install rsync to enable automatic uploads."
2050 msg "Uploading to $disturl"
2051 rsync --progress -La $pkgname-$_version.$_format \
2052 $disturl || return 1
2053 cd "$startdir"
2054 # set the pkgver to current date and update checksum
2055 sed -i -e "s/^pkgver=.*/pkgver=${_version}/" \
2056 APKBUILD || return 1
2057 abuild checksum
2058 fi
2059}
2060
2061usage() {
2062 echo "$program $program_version"
2063 cat << EOF
2064usage: $program [options] [-i PKG] [-P REPODEST] [-p PKGDEST]
2065 [-s SRCDEST] [cmd] ...
2066 $program [-c] -n PKGNAME[-PKGVER]
2067Options:
2068 -A Print CARCH and exit
2069 -c Enable colored output
2070 -d Disable dependency checking
2071 -f Force specified cmd, even if they are already done
2072 -F Force run as root
2073 -h Show this help
2074 -i Install PKG after successful build
2075 -k Keep built packages, even if APKBUILD or sources are newer
2076 -K Keep buildtime temp dirs and files (srcdir/pkgdir/deps)
2077 -m Disable colors (monochrome)
2078 -p Set package destination directory
2079 -P Set PKGDEST to REPODEST/<repo>/\$CARCH, where repo is the parents dir name
2080 -q Quiet
2081 -r Install missing dependencies from system repository (using sudo)
2082 -R Recursively build and install missing dependencies (using sudo)
2083 -s Set source package destination directory
2084 -u Recursively build and upgrade all dependencies (using sudo)
2085
2086Commands:
2087 build Compile and install package into \$pkgdir
2088 checksum Generate checksum to be included in APKBUILD
2089 clean Remove temp build and install dirs
2090 cleancache Remove downloaded files from \$SRCDEST
2091 cleanoldpkg Remove binary packages except current version
2092 cleanpkg Remove already built binary and source package
2093 deps Install packages listed in makedepends and depends
2094 fetch Fetch sources to \$SRCDEST and verify checksums
2095 index Regenerate the APKINDEX for abuildrepo
2096 listpkg List target packages
2097 package Create package in \$PKGDEST
2098 prepare Apply patches
2099 rootpkg Run 'package', the split functions and create apks as fakeroot
2100 sanitycheck Basic sanity check of APKBUILD
2101 snapshot Create a \$giturl or \$svnurl snapshot and upload to \$disturl
2102 sourcecheck Check if remote source package exists upstream
2103 srcpkg Make a source package
2104 undeps Uninstall packages listed in makedepends and depends
2105 unpack Unpack sources to \$srcdir
2106 up2date Compare target and sources dates
2107 verify Verify checksums
2108
2109EOF
2110 exit 0
2111}
2112
2113APKBUILD="${APKBUILD:-./APKBUILD}"
2114unset force
2115unset recursive
2116while getopts "AcdfFhi:kKimnp:P:qrRs:u" opt; do
2117 case $opt in
2118 'A') echo "$CARCH"; exit 0;;
2119 'c') enable_colors
2120 color_opt="-c";;
2121 'd') nodeps=1;;
2122 'f') force="-f";;
2123 'F') forceroot="-F";;
2124 'h') usage;;
2125 'i') install_after="$install_after $OPTARG";;
2126 'k') keep="-k";;
2127 'K') CLEANUP="" ERROR_CLEANUP="" ;;
2128 'm') disable_colors
2129 color_opt="-m";;
2130 'n') die "Use newapkbuild to create new aports";;
2131 'p') PKGDEST=$OPTARG;;
2132 'P') REPODEST=$OPTARG;;
2133 'q') quiet="-q";;
2134 'r') install_deps="-r";;
2135 'R') recursive="-R";;
2136 's') SRCDEST=$OPTARG;;
2137 'u') upgrade="-u"
2138 recursive="-R";;
2139 esac
2140done
2141shift $(( $OPTIND - 1 ))
2142
2143# check so we are not root
2144if [ "$(whoami)" = "root" ] && [ -z "$FAKEROOTKEY" ]; then
2145 [ -z "$forceroot" ] && die "Do not run abuild as root"
2146 FAKEROOT=
2147fi
2148
2149# find startdir
2150[ -f "$APKBUILD" ] || die "Could not find $APKBUILD (PWD=$PWD)"
2151APKBUILD=$(readlink -f "$APKBUILD")
2152
2153startdir="${APKBUILD%/*}"
2154srcdir=${srcdir:-"$startdir/src"}
2155pkgbasedir=${pkgbasedir:-"$startdir/pkg"}
2156
2157repo=${startdir%/*}
2158repo=${repo##*/}
2159
2160SRCDEST=${SRCDEST:-$startdir}
2161PKGDEST=${PKGDEST:-$startdir}
2162
2163# set a default CC
2164: ${CC:=gcc}
2165export CC
2166
2167cd "$startdir" || die
2168. "$APKBUILD"
2169
2170# If REPODEST is set then it will override the PKGDEST
2171if [ -n "$REPODEST" ]; then
2172 PKGDEST="$REPODEST/$repo/$CARCH"
2173 # for recursive action
2174 export REPODEST
2175 abuildrepo="$REPODEST"/$repo
2176else
2177 abuildrepo="$abuildrepo_base"/$repo
2178fi
2179
2180# if we want build debug package
2181if [ -n "$DEBUG" ] || subpackage_types_has "dbg"; then
2182 CFLAGS="$CFLAGS -g"
2183 CXXFLAGS="$CXXFLAGS -g"
2184 options="$options !strip"
2185fi
2186
2187# If we are handling a sub package then reset subpackages and install
2188if [ -n "$subpkgname" ]; then
2189 origsubpackages="$subpackages"
2190 subpackages=
2191fi
2192pkgdir="$pkgbasedir/$pkgname"
2193controldir="$pkgbasedir"/.control.${subpkgname:-$pkgname}
2194
2195trap 'die "Aborted by user"' INT
2196set_xterm_title "abuild: $pkgname"
2197
2198if [ -z "$1" ]; then
2199 set all
2200fi
2201
2202while [ $# -gt 0 ]; do
2203 runpart $1
2204 shift
2205done
2206
2207for i in $install_after; do
2208 post_add $i
2209done
2210
2211cleanup