mirror of
https://gitlab.alpinelinux.org/alpine/abuild.git
synced 2025-02-13 18:07:18 +00:00
apk-tools-2.0's apk index will not show the arch so we need to use tar to find arch if we have old apk. We prefer use apk index since it will only read first block of file, regardless size, while tar will read entire file. Reading entire file is slow if file is big. So we check apk --version and use tar if needed, and apk index if possible.
1453 lines
34 KiB
Bash
Executable File
1453 lines
34 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# script to build apk packages (light version of makepkg)
|
|
# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
|
|
#
|
|
# Distributed under GPL-2
|
|
#
|
|
# Depends on: busybox utilities, fakeroot,
|
|
#
|
|
|
|
abuild_ver=@VERSION@
|
|
sysconfdir=@sysconfdir@
|
|
abuildrepo=@abuildrepo@
|
|
datadir=@datadir@
|
|
|
|
program=${0##*/}
|
|
abuild_path=$(readlink -f $0)
|
|
|
|
# defaults
|
|
BUILD_BASE="build-base"
|
|
SUDO=${SUDO:-"sudo"}
|
|
FAKEROOT=${FAKEROOT:-"fakeroot"}
|
|
APK=${APK:-apk}
|
|
apk_opt_wait="--wait 30"
|
|
|
|
# read config
|
|
ABUILD_CONF=${ABUILD_CONF:-"$sysconfdir/abuild.conf"}
|
|
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"
|
|
|
|
default_colors() {
|
|
NORMAL="\033[1;0m"
|
|
STRONG="\033[1;1m"
|
|
RED="\033[1;31m"
|
|
GREEN="\033[1;32m"
|
|
YELLOW="\033[1;33m"
|
|
BLUE="\033[1;34m"
|
|
}
|
|
|
|
monochrome() {
|
|
NORMAL=""
|
|
STRONG=""
|
|
RED=""
|
|
GREEN=""
|
|
YELLOW=""
|
|
BLUE=""
|
|
}
|
|
|
|
#colors
|
|
if [ -n "$USE_COLORS" ]; then
|
|
default_colors
|
|
fi
|
|
|
|
|
|
# functions
|
|
msg() {
|
|
local prompt="$GREEN>>>${NORMAL}"
|
|
local fake="${FAKEROOTKEY:+${BLUE}*${NORMAL}}"
|
|
local name="${STRONG}${subpkgname:-$pkgname}${NORMAL}"
|
|
[ -z "$quiet" ] && printf "${prompt} ${name}${fake}: $@\n" >&2
|
|
}
|
|
|
|
warning() {
|
|
local prompt="${YELLOW}>>> WARNING:${NORMAL}"
|
|
local fake="${FAKEROOTKEY:+${BLUE}*${NORMAL}}"
|
|
local name="${STRONG}${subpkgname:-$pkgname}${NORMAL}"
|
|
printf "${prompt} ${name}${fake}: $@\n" >&2
|
|
}
|
|
|
|
error() {
|
|
local prompt="${RED}>>> ERROR:${NORMAL}"
|
|
local fake="${FAKEROOTKEY:+${BLUE}*${NORMAL}}"
|
|
local name="${STRONG}${subpkgname:-$pkgname}${NORMAL}"
|
|
printf "${prompt} ${name}${fake}: $@\n" >&2
|
|
}
|
|
|
|
|
|
set_xterm_title() {
|
|
if [ "$TERM" = xterm ] && [ -n "$USE_COLORS" ]; then
|
|
printf "\033]0;$1\007" >&2
|
|
fi
|
|
}
|
|
|
|
cleanup() {
|
|
set_xterm_title ""
|
|
if [ -z "$install_after" ] && [ -n "$uninstall_after" ]; then
|
|
$SUDO $APK del $apk_opt_wait $uninstall_after
|
|
fi
|
|
}
|
|
|
|
die() {
|
|
error "$@"
|
|
cleanup
|
|
exit 1
|
|
}
|
|
|
|
# check if apkbuild is basicly sane
|
|
sanitycheck() {
|
|
local i suggestion
|
|
msg "Checking sanity of $APKBUILD..."
|
|
[ -z "$pkgname" ] && die "Missing pkgname in APKBUILD"
|
|
[ -z "${pkgname##* *}" ] && die "pkgname contains spaces"
|
|
[ -z "$pkgver" ] && die "Missing pkgver in APKBUILD"
|
|
if [ "$pkgver" != "volatile" ] && [ -z "$nodeps" ]; then
|
|
$APK version --check -q "$pkgver" ||\
|
|
die "$pkgver is not a valid version"
|
|
fi
|
|
[ -z "$pkgrel" ] && die "Missing pkgrel in APKBUILD"
|
|
[ -z "$pkgdesc" ] && die "Missing pkgdesc in APKBUILD"
|
|
[ -z "$url" ] && die "Missing url in APKBUILD"
|
|
[ -z "$license" ] && die "Missing license in APKBULID"
|
|
|
|
# check if CARCH, CBUILD, CHOST and CTARGET is set
|
|
if [ -z "$CARCH" ]; then
|
|
case "$(uname -m)" in
|
|
i[0-9]86) suggestion=" (Suggestion: CARCH=x86)";;
|
|
x86_64) suggestion=" (Suggestion: CARCH=x86_64)";;
|
|
esac
|
|
die "Please set CARCH in /etc/abuild.conf$suggestion"
|
|
fi
|
|
[ -z "$CHOST" ] && die "Please set CHOST in /etc/abuild.conf"
|
|
|
|
for i in $install; do
|
|
[ -e "$startdir/$i" ] || die "install script $startdir/$i is missing"
|
|
done
|
|
|
|
[ -n "${triggers%%:*}" ] && [ ! -e "$startdir"/${triggers%%:*} ] \
|
|
&& die "trigger script $startdir/${triggers%%:*} is missing"
|
|
|
|
if [ -n "$source" ]; then
|
|
for i in $source; do
|
|
if install_has "$i"; then
|
|
warning "You should not have \$install in source"
|
|
continue
|
|
fi
|
|
md5sums_has ${i##*/} || die "${i##*/} is missing in md5sums"
|
|
case "$i" in
|
|
https://*) makedepends_has wget || die "wget must be in makedepends when source has https://" ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
if [ -n "$md5sums" ]; then
|
|
for i in $(echo "$md5sums" | awk '{ print $2 }'); do
|
|
source_has $i || die "$i exists in md5sums but is missing in source"
|
|
done
|
|
fi
|
|
|
|
# common spelling errors
|
|
[ -n "$depend" ] && die "APKBUILD contains 'depend'. It should be depends"
|
|
[ -n "$makedepend" ] && die "APKBUILD contains 'makedepend'. It should be makedepends"
|
|
|
|
grep '^# Maintainer:' $APKBUILD >/dev/null || warning "No maintainer"
|
|
|
|
makedepends_has 'g++' && warning "g++ should not be in makedepends"
|
|
return 0
|
|
}
|
|
|
|
md5check() {
|
|
local dummy f endreturnval originalparams origin file
|
|
if [ -z "$source" ]; then
|
|
return 0
|
|
fi
|
|
if [ -z "$md5sums" ]; then
|
|
die "Use 'abuild checksum' to generate/update the checksum(s)"
|
|
fi
|
|
if [ "$(echo $source | wc -l)" -ne "$(echo $md5sums | wc -l)" ]; then
|
|
die "Number of md5sums does not correspond to number of sources"
|
|
fi
|
|
fetch || return 1
|
|
msg "Checking md5sums..."
|
|
cd "$srcdir" || return 1
|
|
IFS=$'\n'
|
|
endreturnval=0
|
|
originalparams=$@
|
|
set -- $source
|
|
for src in $md5sums; do
|
|
origin=$1; shift
|
|
echo "$src" | md5sum -c
|
|
if [ $? -ne 0 ]; then
|
|
is_remote $origin || continue
|
|
echo "Because the remote file above failed the md5sum check it will be deleted."
|
|
echo "Rebuilding will cause it to re-download which in some cases may fix the problem."
|
|
file=`echo "$src" | sed 's/.*[ \t\n]\(.*\)/\1/'`
|
|
echo "Deleting: $file"
|
|
rm $file
|
|
endreturnval=1
|
|
fi
|
|
done
|
|
unset IFS
|
|
set -- $originalparams
|
|
return $endreturnval
|
|
}
|
|
|
|
# verify upstream sources
|
|
sourcecheck() {
|
|
local uri
|
|
for uri in $source; do
|
|
is_remote $uri || continue
|
|
case "$uri" in
|
|
saveas-*://*)
|
|
uri=${uri#saveas-}
|
|
uri=${uri%/*}
|
|
;;
|
|
esac
|
|
wget -q -s "$uri" || return 1
|
|
done
|
|
return 0
|
|
}
|
|
|
|
uri_fetch() {
|
|
local uri="$1"
|
|
local d="${uri##*/}" # $(basename $uri)
|
|
local opts
|
|
[ -n "$quiet" ] && opts="-q"
|
|
[ -f "$SRCDEST/$d" ] && return 0
|
|
|
|
# fix saveas-*://* URIs
|
|
case "$uri" in
|
|
# remove 'saveas-' from beginning and
|
|
# '/filename' from end of URI
|
|
saveas-*://*) uri="${uri:7:$(expr ${#uri} - 7 - ${#d} - 1)}";;
|
|
esac
|
|
|
|
# we need GNU wget for this
|
|
case "$uri" in
|
|
https://*) opts="--no-check-certificate";;
|
|
esac
|
|
|
|
mkdir -p "$SRCDEST"
|
|
if [ -f "$SRCDEST/$d.part" ]; then
|
|
msg "Partial download found. Trying to resume"
|
|
opts="$opts -c"
|
|
fi
|
|
msg "Fetching $uri"
|
|
wget $opts -O "$SRCDEST/$d.part" "$uri" \
|
|
&& mv "$SRCDEST/$d.part" "$SRCDEST/$d"
|
|
}
|
|
|
|
is_remote() {
|
|
case "$1" in
|
|
http://*|ftp://*|https://*|saveas-*://*)
|
|
return 0;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
# try download from file from mirror first
|
|
uri_fetch_mirror() {
|
|
local uri="$1"
|
|
local d="${uri##*/}" # $(basename $uri)
|
|
if [ -n "$DISTFILES_MIRROR" ]; then
|
|
if is_remote "$DISTFILES_MIRROR"; then
|
|
uri_fetch "$DISTFILES_MIRROR"/$d && return 0
|
|
else
|
|
cp "$DISTFILES_MIRROR"/$d "$SRCDEST" && return 0
|
|
fi
|
|
fi
|
|
uri_fetch "$uri"
|
|
}
|
|
|
|
default_fetch() {
|
|
local s
|
|
mkdir -p "$srcdir"
|
|
for s in $source; do
|
|
if is_remote "$s"; then
|
|
uri_fetch_mirror "$s" || return 1
|
|
ln -sf "$SRCDEST/${s##*/}" "$srcdir"/
|
|
else
|
|
ln -sf "$startdir/$s" "$srcdir/"
|
|
fi
|
|
done
|
|
}
|
|
|
|
fetch() {
|
|
default_fetch
|
|
}
|
|
|
|
# verify that all init.d scripts are openrc runscripts
|
|
initdcheck() {
|
|
local i
|
|
for i in $source; do
|
|
case $i in
|
|
*.initd)
|
|
head -n 1 "$srcdir"/$i | grep -q '/sbin/runscript' \
|
|
&& continue
|
|
error "$i is not an openrc #!/sbin/runscript"
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# unpack the sources
|
|
default_unpack() {
|
|
local u
|
|
if [ -z "$force" ]; then
|
|
md5check || return 1
|
|
initdcheck || return 1
|
|
fi
|
|
mkdir -p "$srcdir"
|
|
for u in $source; do
|
|
local s="$SRCDEST/${u##*/}" # $(basename $s)
|
|
case "$s" in
|
|
*.tar.gz|*.tgz)
|
|
msg "Unpacking $s..."
|
|
tar -C "$srcdir" -zxf "$s" || return 1;;
|
|
*.tar.bz2)
|
|
msg "Unpacking $s..."
|
|
tar -C "$srcdir" -jxf "$s" || return 1;;
|
|
*.tar.lzma)
|
|
msg "Unpacking $s..."
|
|
unlzma -c "$s" | tar -C "$srcdir" -x \
|
|
|| return 1;;
|
|
*.tar.xz)
|
|
msg "Unpacking $s..."
|
|
unxz -c "$s" | tar -C "$srcdir" -x || return 1;;
|
|
*.zip)
|
|
msg "Unpacking $s..."
|
|
unzip "$s" -d "$srcdir" || return 1;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
unpack() {
|
|
default_unpack
|
|
}
|
|
|
|
# cleanup source and package dir
|
|
clean() {
|
|
msg "Cleaning temporary build dirs..."
|
|
rm -rf "$srcdir"
|
|
rm -rf "$pkgbasedir"
|
|
}
|
|
|
|
# cleanup fetched sources
|
|
cleancache() {
|
|
local s
|
|
for s in $source; do
|
|
if is_remote "$s"; then
|
|
msg "Cleaning downloaded ${s##*/}..."
|
|
rm -f "$SRCDEST/${s##*/}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
listpkgnames() {
|
|
local i
|
|
for i in $pkgname $subpackages; do
|
|
echo ${i%:*}
|
|
done
|
|
for i in $linguas; do
|
|
echo $pkgname-lang-$i
|
|
done
|
|
}
|
|
|
|
cleanpkg() {
|
|
local i
|
|
getpkgver || return 1
|
|
msg "Cleaning built packages..."
|
|
for i in $(listpkgnames); do
|
|
local p="${i%:*}-$pkgver-r$pkgrel"
|
|
rm -f "$PKGDEST/$p.apk" "$PKGDEST/$p.src.tar.gz" \
|
|
"$abuildrepo"/$p.apk "$abuildrepo"/*/$p.apk
|
|
done
|
|
# remove given packages from index
|
|
}
|
|
|
|
# clean all packages except current
|
|
cleanoldpkg() {
|
|
local i j
|
|
getpkgver || return 1
|
|
msg "Cleaning all packages except $pkgver-r$pkgrel..."
|
|
for i in $(listpkgnames); do
|
|
local pn=${i%:*}
|
|
for j in "$PKGDEST"/$pn-[0-9]*.apk ; do
|
|
[ "$j" = "$PKGDEST/$pn-$pkgver-r$pkgrel.apk" ] \
|
|
&& continue
|
|
rm -f "$j" "$abuildrepo"/*/${j##*/}
|
|
done
|
|
done
|
|
return 0
|
|
}
|
|
|
|
mkusers() {
|
|
local i
|
|
for i in $pkgusers; do
|
|
if ! getent passwd $i >/dev/null; then
|
|
msg "Creating user $i"
|
|
$SUDO adduser -D -H $i || return 1
|
|
fi
|
|
done
|
|
for i in $pkggroups; do
|
|
if ! getent group $i >/dev/null; then
|
|
msg "Creating group $i"
|
|
$SUDO addgroup $i || return 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
|
|
runpart() {
|
|
local part=$1
|
|
[ -n "$DEBUG" ] && msg "$part"
|
|
$part || die "$part failed"
|
|
}
|
|
|
|
# override those in your build script
|
|
getpkgver() {
|
|
# this func is supposed to be overridden by volatile packages
|
|
if [ "$pkgver" = "volatile" ]; then
|
|
error "Please provide a getpkgver() function in your APKBUILD"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
prepare() {
|
|
:
|
|
}
|
|
|
|
build() {
|
|
:
|
|
}
|
|
|
|
# generate a simple tar.gz package of pkgdir
|
|
targz() {
|
|
cd "$pkgdir" || return 1
|
|
tar -czf "$PKGDEST"/$pkgname-$pkgver-r$pkgrel.tar.gz *
|
|
}
|
|
|
|
get_split_func() {
|
|
# get the 'func' from "sub-pkg:func"
|
|
local func=${1##*:}
|
|
|
|
# get 'func' from "sub-pkg-func" if there was no :func
|
|
[ "$func" = "$1" ] && func=${func##*-}
|
|
echo $func
|
|
}
|
|
|
|
prepare_subpackages() {
|
|
local i
|
|
cd "$startdir"
|
|
for i in $subpackages; do
|
|
local func=$(get_split_func $i)
|
|
# call abuild recursively, setting subpkg{dir,name}
|
|
msg "Running split function $func..."
|
|
subpkgdir="$pkgbasedir/${i%:*}" subpkgname="${i%:*}" \
|
|
$0 $func prepare_package || return 1
|
|
done
|
|
}
|
|
|
|
lang_subpkg() {
|
|
if [ -z "$lang" ]; then
|
|
error "lang is not set"
|
|
return 1
|
|
fi
|
|
arch="noarch"
|
|
install_if="$pkgname=$pkgver-r$pkgrel lang-$lang"
|
|
mkdir -p "$subpkgdir"/usr/share/locale
|
|
mv "$pkgdir"/usr/share/locale/$lang* \
|
|
"$subpkgdir"/usr/share/locale/ \
|
|
|| return 1
|
|
}
|
|
|
|
prepare_language_packs() {
|
|
for lang in $linguas; do
|
|
lang="$lang" \
|
|
subpkgname="$pkgname-lang-$lang" \
|
|
subpkgdir="$pkgbasedir"/$subpkgname \
|
|
$0 lang_subpkg prepare_package || return 1
|
|
done
|
|
}
|
|
|
|
# echo '-dirty' if git is not clean
|
|
git_dirty() {
|
|
if [ $(git status -s "$startdir" | wc -l) -ne 0 ]; then
|
|
echo "-dirty"
|
|
fi
|
|
}
|
|
|
|
# echo last commit hash id
|
|
git_last_commit() {
|
|
git log --format=oneline -n 1 "$startdir" | awk '{print $1}'
|
|
}
|
|
|
|
get_maintainer() {
|
|
if [ -z "$maintainer" ]; then
|
|
maintainer=$(awk -F': ' '/\# *Maintainer/ {print $2}' "$APKBUILD")
|
|
fi
|
|
}
|
|
|
|
prepare_metafiles() {
|
|
getpkgver || return 1
|
|
local name=${subpkgname:-$pkgname}
|
|
[ -z "${name##* *}" ] && die "package name contains spaces"
|
|
local dir=${subpkgdir:-$pkgdir}
|
|
local pkg="$name-$pkgver-r$pkgrel.apk"
|
|
local pkginfo="$controldir"/.PKGINFO
|
|
local sub
|
|
|
|
[ ! -d "$dir" ] && die "Missing $dir"
|
|
cd "$dir"
|
|
mkdir -p "$controldir"
|
|
local builddate=$(date -u "+%s")
|
|
local size=$(du -sk | awk '{print $1 * 1024}')
|
|
local parch="$CARCH"
|
|
|
|
# we need to wait with setting noarch til our build infra can handle it
|
|
# if [ "$arch" = "noarch" ]; then
|
|
# parch="noarch"
|
|
# fi
|
|
|
|
echo "# Generated by $(basename $0) $abuild_ver" >"$pkginfo"
|
|
if [ -n "$FAKEROOTKEY" ]; then
|
|
echo "# using $($FAKEROOT -v)" >> "$pkginfo"
|
|
fi
|
|
echo "# $(date -u)" >> "$pkginfo"
|
|
cat >> "$pkginfo" <<EOF
|
|
pkgname = $name
|
|
pkgver = $pkgver-r$pkgrel
|
|
pkgdesc = $pkgdesc
|
|
url = $url
|
|
builddate = $builddate
|
|
packager = ${PACKAGER:-"Unknown"}
|
|
size = $size
|
|
arch = $parch
|
|
EOF
|
|
local i deps
|
|
deps="$depends"
|
|
if [ "$pkgname" != "busybox" ] && ! depends_has busbox; then
|
|
for i in $install ${triggers%%:*}; do
|
|
if head -n 1 "$startdir/$i" | grep '^#!/bin/sh' >/dev/null ; then
|
|
msg "Script found. busybox added as a dependency for $pkg"
|
|
deps="$deps busybox"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
local last_commit="$(git_last_commit)$(git_dirty)"
|
|
if [ -n "$last_commit" ]; then
|
|
echo "commit = $last_commit" >> "$pkginfo"
|
|
fi
|
|
|
|
get_maintainer
|
|
if [ -n "$maintainer" ]; then
|
|
echo "maintainer = $maintainer" >> "$pkginfo"
|
|
fi
|
|
|
|
for i in $license; do
|
|
echo "license = $i" >> "$pkginfo"
|
|
done
|
|
for i in $replaces; do
|
|
echo "replaces = $i" >> "$pkginfo"
|
|
done
|
|
for i in $deps; do
|
|
echo "depend = $i" >> "$pkginfo"
|
|
done
|
|
for i in $conflicts; do
|
|
echo "conflict = $i" >> "$pkginfo"
|
|
done
|
|
for i in $provides; do
|
|
echo "provides = $i" >> "$pkginfo"
|
|
done
|
|
if [ -n "$triggers" ]; then
|
|
echo "triggers = ${triggers#*:}" >> "$pkginfo"
|
|
fi
|
|
if [ -n "$install_if" ]; then
|
|
echo "install_if = $(echo $install_if)" >> "$pkginfo"
|
|
fi
|
|
|
|
local metafiles=".PKGINFO"
|
|
for i in $install ${triggers%%:*}; do
|
|
script=${i#$name}
|
|
case "$script" in
|
|
.pre-install|.post-install|.pre-upgrade|.post-upgrade|.pre-deinstall|.post-deinstall|.trigger)
|
|
msg "Adding $script"
|
|
;;
|
|
*) error "$script: Invalid install/trigger script"
|
|
return 1
|
|
;;
|
|
esac
|
|
cp "$startdir/$i" "$controldir/$script" || return 1
|
|
chmod +x "$controldir/$script"
|
|
metafiles="$metafiles $script"
|
|
done
|
|
echo $metafiles | tr ' ' '\n' > "$controldir"/.metafiles
|
|
}
|
|
|
|
prepare_tracedeps() {
|
|
local dir=${subpkgdir:-$pkgdir}
|
|
[ "$arch" = "noarch" ] && return 0
|
|
options_has "!tracedeps" && return 0
|
|
# lets tell all the .so files this package provides in .provides-so
|
|
find -name '*.so' -o -name '*.so.[0-9]*' | sed 's:.*/::' \
|
|
>"$controldir"/.provides-so
|
|
# lets tell all the places we should look for .so files - all rpaths
|
|
scanelf -q -Rr "$dir" | sed -e 's/[[:space:]].*//' -e 's/:/\n/' \
|
|
| sort | uniq \
|
|
>"$controldir"/.rpaths
|
|
# now find the so dependencies
|
|
scanelf -Rn "$dir" | tr ' ' ':' | awk -F ":" '$1 == "ET_DYN" || $1 == "ET_EXEC" {print $2}' \
|
|
| sed 's:,:\n:g' | sort | uniq \
|
|
| while read i; do
|
|
# only add files that are not self provided
|
|
grep "^$i$" "$controldir"/.provides-so >/dev/null \
|
|
|| echo $i >> "$controldir"/.needs-so
|
|
done
|
|
}
|
|
|
|
# check if dir has arch specific binaries
|
|
dir_has_arch_binaries() {
|
|
local dir="$1"
|
|
# if scanelf returns something, then we have binaries
|
|
[ -n "$(scanelf -R "$dir" | head -n 1)" ] && return 0
|
|
|
|
# look for static *.a
|
|
[ -n "$(find "$dir" -type f -name '*.a' | head -n 1)" ] && return 0
|
|
|
|
return 1
|
|
}
|
|
|
|
# returns true if this is the -dev package
|
|
is_dev_pkg() {
|
|
test "${subpkgname%-dev}" != "$subpkgname"
|
|
}
|
|
|
|
# check that noarch is set if needed
|
|
archcheck() {
|
|
options_has "!archcheck" && return 0
|
|
if dir_has_arch_binaries "${subpkgdir:-$pkgdir}"; then
|
|
[ "$arch" != "noarch" ] && return 0
|
|
error "Arch specific binaries found so arch must not be set to \"noarch\""
|
|
return 1
|
|
elif [ "$arch" != "noarch" ] && ! is_dev_pkg; then
|
|
# we dont want -dev package go to noarch
|
|
warning "No arch specific binaries found so arch should probably be set to \"noarch\""
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
prepare_package() {
|
|
msg "Preparing ${subpkgname:+sub}package ${subpkgname:-$pkgname}..."
|
|
stripbin
|
|
prepare_metafiles && prepare_tracedeps || return 1
|
|
archcheck
|
|
}
|
|
|
|
pkginfo_val() {
|
|
local key="$1"
|
|
local file="$2"
|
|
awk -F ' = ' "\$1 == \"$key\" {print \$2}" "$file"
|
|
}
|
|
|
|
# find real path to so files
|
|
real_so_path() {
|
|
local so="$1"
|
|
shift
|
|
while [ $# -gt 0 ]; do
|
|
[ -e "$1"/$so ] && realpath "$1/$so" && return 0
|
|
shift
|
|
done
|
|
error "$so: path not found"
|
|
return 1
|
|
}
|
|
|
|
# search rpaths and /usr/lib /lib for given so files
|
|
find_so_files() {
|
|
local rpaths=$(cat "$1")
|
|
shift
|
|
while [ $# -gt 0 ]; do
|
|
real_so_path "$1" /usr/lib /lib $rpaths || return 1
|
|
shift
|
|
done
|
|
return 0
|
|
}
|
|
|
|
trace_apk_deps() {
|
|
local name="$1"
|
|
local dir="$2"
|
|
local i= j= found= autodeps= deppkgs= missing= so_paths= self_provided=
|
|
msg "Tracing dependencies for $name..."
|
|
# add pkgconfig if usr/lib/pkgconfig is found
|
|
if [ -d "$pkgbasedir"/$name/usr/lib/pkgconfig ] \
|
|
&& ! grep -q '^depend = pkgconfig' "$dir"/.PKGINFO; then
|
|
msg " added pkgconfig (found /usr/lib/pkgconfig)"
|
|
autodeps="$autodeps pkgconfig"
|
|
fi
|
|
|
|
# special case for libpthread: we need depend on libgcc
|
|
if [ -f "$dir"/.needs-so ] && grep -q -w '^libpthread.so.*' "$dir"/.needs-so \
|
|
&& ! grep -q -w "^depend = libgcc" "$dir"/.PKGINFO; then
|
|
autodeps="$autodeps libgcc"
|
|
msg " added libgcc (due to libpthread)"
|
|
fi
|
|
[ -f "$dir"/.needs-so ] && for i in $(cat "$dir"/.needs-so); do
|
|
found=
|
|
# first check if its provide by same apkbuild
|
|
for j in "$dir"/../.control.*/.provides-so; do
|
|
grep -w "$i" "$j" >/dev/null || continue
|
|
found=${j%/.provides-so}
|
|
found=${found##*/.control.}
|
|
break
|
|
done
|
|
if [ -n "$found" ]; then
|
|
if ! list_has "$found" $self_provided; then
|
|
self_provided="$self_provided $found"
|
|
fi
|
|
else
|
|
missing="$missing $i"
|
|
fi
|
|
done
|
|
|
|
# find all packages that holds the so files
|
|
if [ -f "$dir"/.rpaths ]; then
|
|
so_files=$(find_so_files "$dir"/.rpaths $missing) || return 1
|
|
deppkgs=$($APK info -q -W $so_files) || return 1
|
|
fi
|
|
|
|
for found in $self_provided $deppkgs; do
|
|
if grep -w "^depend = ${found}$" "$dir"/.PKGINFO >/dev/null ; then
|
|
warning "You can remove '$found' from depends"
|
|
continue
|
|
fi
|
|
if [ "$found" != "$name" ] && ! list_has "$found" $autodeps; then
|
|
autodeps="$autodeps $found"
|
|
msg " added $found"
|
|
fi
|
|
done
|
|
|
|
[ -z "$autodeps" ] && return 0
|
|
echo "# automatically detected:" >> "$dir"/.PKGINFO
|
|
for i in $autodeps; do
|
|
echo "depend = $i" >> "$dir"/.PKGINFO
|
|
done
|
|
}
|
|
|
|
create_apks() {
|
|
local file
|
|
getpkgver || return 1
|
|
for file in "$pkgbasedir"/.control.*/.PKGINFO; do
|
|
local dir="${file%/.PKGINFO}"
|
|
local name=$(pkginfo_val pkgname $file)
|
|
local ver=$(pkginfo_val pkgver $file)
|
|
local apk=$name-$ver.apk
|
|
local datadir="$pkgbasedir"/$name
|
|
|
|
trace_apk_deps "$name" "$dir" || return 1
|
|
msg "Creating $apk..."
|
|
(
|
|
cd "$datadir"
|
|
# data.tar.gz
|
|
set -- *
|
|
if [ "$1" = '*' ]; then
|
|
touch .dummy
|
|
set -- .dummy
|
|
fi
|
|
tar -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz
|
|
|
|
# append the hash for data.tar.gz
|
|
local sha256=$(sha256sum "$dir"/data.tar.gz | cut -f1 -d' ')
|
|
echo "datahash = $sha256" >> "$dir"/.PKGINFO
|
|
|
|
# control.tar.gz
|
|
cd "$dir"
|
|
tar -c $(cat "$dir"/.metafiles) | abuild-tar --cut \
|
|
| gzip -9 > control.tar.gz
|
|
abuild-sign -q control.tar.gz || exit 1
|
|
|
|
# create the final apk
|
|
cat control.tar.gz data.tar.gz > "$PKGDEST"/$apk
|
|
)
|
|
done
|
|
}
|
|
|
|
# fish out the arch from an apk file
|
|
apk_arch_prefix() {
|
|
apk index -q "$1" | tar -zxO | awk -F: '$1 == "A" { print $2 }'
|
|
}
|
|
|
|
apk_arch_prefix_compat() {
|
|
tar -zxOf "$1" .PKGINFO | awk -F" = " '$1 == "arch" { print $2 }'
|
|
}
|
|
|
|
clean_abuildrepo() {
|
|
local apk
|
|
cd "$abuildrepo" || return 1
|
|
|
|
# remove compat symlink
|
|
for d in "$abuildrepo/$CARCH" "$abuildrepo"/noarch; do
|
|
[ -L "$d" ] && rm "$d"
|
|
done
|
|
|
|
# remove broken links from abuildrepo
|
|
for apk in *.apk */*.apk; do
|
|
if [ -L "$apk" ] && [ ! -f "$apk" ]; then
|
|
rm -f "$apk"
|
|
fi
|
|
done
|
|
}
|
|
|
|
mklinks_abuildrepo() {
|
|
local apk get_prefix=apk_arch_prefix
|
|
local version=$($APK --version | awk '{print $2}')
|
|
if [ "$($APK version --test $version 2.1)" = '<' ]; then
|
|
get_prefix=apk_arch_prefix_compat
|
|
fi
|
|
mkdir -p "$abuildrepo"/$CARCH "$abuildrepo"/noarch
|
|
cd "$abuildrepo" || return 1
|
|
# create links for this package
|
|
for apk in $(listpkg); do
|
|
[ -f "$PKGDEST"/$apk ] || continue
|
|
local prefix=$($get_prefix "$PKGDEST"/$apk)
|
|
mkdir -p "$abuildrepo"/$prefix
|
|
ln -sf "$PKGDEST"/$apk "$abuildrepo"/$prefix/$apk
|
|
done
|
|
}
|
|
|
|
update_abuildrepo() {
|
|
local d apk
|
|
if ! apk_up2date || [ -n "$force" ]; then
|
|
sanitycheck && builddeps && clean && fetch && unpack \
|
|
&& prepare && mkusers && rootpkg || return 1
|
|
fi
|
|
|
|
clean_abuildrepo
|
|
mklinks_abuildrepo
|
|
|
|
cd "$abuildrepo"
|
|
local index=$CARCH/APKINDEX.tar.gz
|
|
|
|
msg "Updating the cached abuild repository index..."
|
|
local sign=".SIGN.RSA.${SIGN_PUBLIC_KEY##*/}"
|
|
local oldindex=
|
|
if [ -f "$index" ]; then
|
|
oldindex="--index $index"
|
|
fi
|
|
$APK index --quiet $oldindex --output "$index".unsigned \
|
|
--description "$repo $(cd $startdir && git describe)" \
|
|
noarch/*.apk $CARCH/*.apk || exit 1
|
|
msg "Signing the index..."
|
|
abuild-sign -q "$index".unsigned || exit 1
|
|
mv "$index".unsigned "$index"
|
|
chmod 644 "$index"
|
|
}
|
|
|
|
# predefined splitfunc doc
|
|
default_doc() {
|
|
depends="$depends_doc"
|
|
install="$install_doc"
|
|
triggers="$triggers_doc"
|
|
pkgdesc="$pkgdesc (documentation)"
|
|
arch=${arch_doc:-"noarch"}
|
|
|
|
local i
|
|
for i in doc man info html sgml licenses gtk-doc; do
|
|
if [ -d "$pkgdir/usr/share/$i" ]; then
|
|
mkdir -p "$subpkgdir/usr/share"
|
|
mv "$pkgdir/usr/share/$i" "$subpkgdir/usr/share/"
|
|
fi
|
|
done
|
|
|
|
rm -f "$subpkgdir/usr/share/info/dir"
|
|
|
|
# # compress info and man pages
|
|
# find "$subpkgdir/usr/share" \( -name '*.info' -o -name '*.info-[1-9]' \
|
|
# -o -name '*.[1-9]' \) -exec gzip {} \;
|
|
|
|
# remove if empty, ignore error (not empty)
|
|
rmdir "$pkgdir/usr/share" "$pkgdir/usr" 2>/dev/null
|
|
|
|
# [ -d "$subpkgdir/usr/share/man" ] && depends="man"
|
|
return 0
|
|
}
|
|
|
|
doc() {
|
|
default_doc
|
|
}
|
|
|
|
# predefined splitfunc mod
|
|
default_mod() {
|
|
depends="$kernel $depends_mod"
|
|
install="$install_mod"
|
|
for i in firmware modules; do
|
|
if [ -d "$pkgdir/lib/$i" ]; then
|
|
rm -rf "$subpkgdir/lib"
|
|
mkdir -p "$subpkgdir/lib"
|
|
mv "$pkgdir/lib/$i" "$subpkgdir/lib"
|
|
fi
|
|
done
|
|
}
|
|
|
|
mod() {
|
|
default_mod
|
|
}
|
|
|
|
# predefined splitfunc dev
|
|
default_dev() {
|
|
local i= j=
|
|
depends="$pkgname $depends_dev"
|
|
install="$install_dev"
|
|
triggers="$triggers_dev"
|
|
pkgdesc="$pkgdesc (development files)"
|
|
|
|
for i in $origsubpackages; do
|
|
[ "${i%:*}" = "$subpkgname" ] || depends="$depends ${i%:*}"
|
|
done
|
|
|
|
cd "$pkgdir" || return 0
|
|
for i in usr/include usr/lib/pkgconfig usr/share/aclocal\
|
|
usr/share/gettext usr/bin/*-config \
|
|
usr/share/vala/vapi usr/share/gir-[0-9]*\
|
|
$(find -name include -type d) \
|
|
$(find usr/ -name '*.[acho]' -o -name '*.la' \
|
|
2>/dev/null); do
|
|
if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
|
|
d="$subpkgdir/${i%/*}" # dirname $i
|
|
mkdir -p "$d"
|
|
mv "$pkgdir/$i" "$d"
|
|
rmdir "$pkgdir/${i%/*}" 2>/dev/null
|
|
fi
|
|
done
|
|
# move *.so links needed when linking the apps to -dev packages
|
|
for i in lib/*.so usr/lib/*.so; do
|
|
if [ -L "$i" ]; then
|
|
mkdir -p "$subpkgdir"/"${i%/*}"
|
|
mv "$i" "$subpkgdir/$i" || return 1
|
|
fi
|
|
done
|
|
return 0
|
|
}
|
|
|
|
dev() {
|
|
default_dev
|
|
}
|
|
|
|
is_function() {
|
|
type "$1" 2>&1 | head -n 1 | egrep -q "is a (shell )?function"
|
|
}
|
|
|
|
do_fakeroot() {
|
|
if [ -n "$FAKEROOT" ]; then
|
|
$FAKEROOT -- "$@"
|
|
else
|
|
"$@"
|
|
fi
|
|
}
|
|
|
|
# build and package in fakeroot
|
|
rootpkg() {
|
|
local do_build=build
|
|
cd "$startdir"
|
|
if is_function package; then
|
|
build || return 1
|
|
do_build=package
|
|
fi
|
|
cd "$startdir"
|
|
[ -n "$FAKEROOT" ] && msg "Entering fakeroot..."
|
|
do_fakeroot "$abuild_path" $color_opt $do_build \
|
|
prepare_subpackages \
|
|
prepare_language_packs \
|
|
prepare_package \
|
|
create_apks
|
|
}
|
|
|
|
srcpkg() {
|
|
getpkgver || return 1
|
|
local p="$pkgname-$pkgver-$pkgrel"
|
|
local prefix="${startdir##*/}"
|
|
local i files="$prefix/APKBUILD"
|
|
for i in $source; do
|
|
files="$files $prefix/${i##*/}"
|
|
done
|
|
mkdir -p "$PKGDEST"
|
|
msg "Creating source package $p.src.tar.gz..."
|
|
(cd .. && tar -zcf "$PKGDEST/$p.src.tar.gz" $files)
|
|
}
|
|
|
|
# return true if arch is supported or noarch
|
|
check_arch() {
|
|
list_has $CARCH $arch || [ "$arch" = "noarch" ] || [ "$arch" = "all" ]
|
|
}
|
|
|
|
# check if package is up to date
|
|
apk_up2date() {
|
|
getpkgver || return 1
|
|
local pkg="$PKGDEST/$pkgname-$pkgver-r$pkgrel.apk"
|
|
local i s
|
|
cd "$startdir"
|
|
for i in $pkgname $subpackages; do
|
|
[ -f "$PKGDEST/$pkgname-$pkgver-r$pkgrel.apk" ] || return 1
|
|
done
|
|
[ -n "$keep" ] && return 0
|
|
|
|
for i in $source APKBUILD; do
|
|
local s
|
|
if is_remote "$i"; then
|
|
s="$SRCDEST/${i##*/}" # $(basename $i)
|
|
else
|
|
s="$startdir/${i##*/}"
|
|
fi
|
|
if [ "$s" -nt "$pkg" ]; then
|
|
return 1
|
|
fi
|
|
done
|
|
return 0
|
|
}
|
|
|
|
abuildindex_up2date() {
|
|
local i j apk
|
|
getpkgver || return 1
|
|
for i in $pkgname $subpackages; do
|
|
apk="${i%:*}-$pkgver-r$pkgrel.apk"
|
|
for j in "$abuildrepo"/*/$apk; do
|
|
[ -r "$j" ] || continue # ignore missing files
|
|
local idx="${j%/*}"/APKINDEX.tar.gz
|
|
if ! [ "$idx" -nt "$j" ]; then
|
|
return 1
|
|
fi
|
|
done
|
|
done
|
|
return 0
|
|
}
|
|
|
|
up2date() {
|
|
check_arch || return 0
|
|
apk_up2date && abuildindex_up2date
|
|
}
|
|
|
|
# rebuild package and abuildrepo index if needed
|
|
abuildindex() {
|
|
up2date && return 0
|
|
update_abuildrepo
|
|
}
|
|
|
|
# source all APKBUILDs and output:
|
|
# 1) origin of package
|
|
# 2) all dependencies
|
|
# the output is i in a format easy parseable for awk
|
|
depparse_aports() {
|
|
# lets run this in a subshell since we source all APKBUILD here
|
|
(
|
|
aportsdir=$(realpath ${APKBUILD%/APKBUILD}/..)
|
|
for i in $aportsdir/*/APKBUILD; do
|
|
pkgname=
|
|
subpackages=
|
|
depends=
|
|
makedepends=
|
|
. $i
|
|
dir=${i%/APKBUILD}
|
|
deps=
|
|
# filter out conflicts from deps and version info
|
|
for j in $depends $makedepends; do
|
|
case "$j" in
|
|
!*) continue;;
|
|
esac
|
|
deps="$deps ${j%%[<>=]*}"
|
|
done
|
|
for j in $pkgname $subpackages; do
|
|
echo "o ${j%%:*} $dir"
|
|
set -- $deps
|
|
echo -n "d ${j%%:*} $1"
|
|
shift
|
|
while [ $# -gt 0 ]; do
|
|
echo -n ",$1"
|
|
shift
|
|
done
|
|
echo
|
|
done
|
|
done
|
|
)
|
|
}
|
|
|
|
deptrace() {
|
|
local deps= i=
|
|
# strip versions from deps
|
|
for i in "$@"; do
|
|
deps="$deps ${i%%[<>=]*}"
|
|
done
|
|
[ -z "$deps" ] && return 0
|
|
( depparse_aports
|
|
if [ -z "$upgrade" ]; then
|
|
# list installed pkgs and prefix with 'i '
|
|
$APK info -q | sort | sed 's/^/i /'
|
|
fi
|
|
) | awk -v pkgs="$deps" '
|
|
|
|
function depgraph(pkg, a, i) {
|
|
if (visited[pkg])
|
|
return 0;
|
|
visited[pkg] = 1;
|
|
split(deps[pkg], a, ",");
|
|
for (i in a)
|
|
depgraph(a[i]);
|
|
print pkg ":" origin[pkg];
|
|
|
|
}
|
|
|
|
$1 == "i" { visited[$2] = 1 }
|
|
$1 == "o" { origin[$2] = $3 }
|
|
$1 == "d" { deps[$2] = $3 }
|
|
END {
|
|
split(pkgs, pkgarray);
|
|
for (i in pkgarray)
|
|
depgraph(pkgarray[i]);
|
|
}
|
|
'
|
|
}
|
|
|
|
# build and install dependencies
|
|
builddeps() {
|
|
local deps= alldeps= pkg= i= dir= ver= missing= installed_deps=
|
|
local filtered_deps= conflicts=
|
|
[ -n "$nodeps" ] && return 0
|
|
msg "Analyzing dependencies..."
|
|
|
|
# add depends unless it is a subpackage or package itself
|
|
for i in $BUILD_BASE $depends $makedepends; do
|
|
[ "$pkgname" = "${i%%[<>=]*}" ] && continue
|
|
subpackages_has ${i%%[<>=]*} || deps="$deps $i"
|
|
done
|
|
|
|
installed_deps=$($APK info -e $deps)
|
|
# find which deps are missing
|
|
for i in $deps; do
|
|
if [ "${i#\!}" != "$i" ]; then
|
|
$APK info -q -e "${i#\!}" \
|
|
&& conflicts="$conflicts ${i#\!}"
|
|
elif ! deplist_has $i $installed_deps || [ -n "$upgrade" ]; then
|
|
missing="$missing $i"
|
|
fi
|
|
done
|
|
|
|
if [ -n "$conflicts" ]; then
|
|
error "Conflicting package(s) installed:$conflicts"
|
|
return 1
|
|
fi
|
|
|
|
if [ -z "$install_deps" ] && [ -z "$recursive" ]; then
|
|
# if we dont have any missing deps we are done now
|
|
[ -z "$missing" ] && return 0
|
|
error "Missing dependencies: $missing Use -r to autoinstall or -R to build"
|
|
return 1
|
|
fi
|
|
|
|
uninstall_after=".makedepends-$pkgname $uninstall_after"
|
|
if [ -n "$install_deps" ] && [ -z "$recursive" ] && [ -n "$deps" ]; then
|
|
# make a --simluate run first to detect missing deps
|
|
# apk-tools --virtual is no goot at reporting those.
|
|
$SUDO $APK add --repository "$abuildrepo" \
|
|
$apk_opt_wait \
|
|
--simulate --quiet $deps || return 1
|
|
$SUDO $APK add --repository "$abuildrepo" \
|
|
$apk_opt_wait \
|
|
--virtual .makedepends-$pkgname $deps \
|
|
&& return 0
|
|
fi
|
|
|
|
[ -z "$recursive" ] && return 1
|
|
|
|
# find dependencies that are installed but missing in repo.
|
|
for i in $deps; do
|
|
local m=$($APK search --repository "$abuildrepo" ${i%%[<>=]*})
|
|
if [ -z "$m" ]; then
|
|
missing="$missing $i"
|
|
fi
|
|
done
|
|
|
|
for i in $(deptrace $missing); do
|
|
# i = pkg:dir
|
|
local dir=${i#*:}
|
|
local pkg=${i%:*}
|
|
|
|
# ignore if dependency is in other repo
|
|
[ -d "$dir" ] || continue
|
|
|
|
# break cricular deps
|
|
list_has $pkg $ABUILD_VISITED && continue
|
|
export ABUILD_VISITED="$ABUILD_VISITED $pkg"
|
|
|
|
msg "Entering $dir"
|
|
cd "$dir" && $0 $forceroot $keep $quiet $install_deps \
|
|
$recursive $upgrade $color_opt abuildindex || return 1
|
|
done
|
|
$SUDO $APK add -u --repository "$abuildrepo" \
|
|
$apk_opt_wait \
|
|
--virtual .makedepends-$pkgname $deps
|
|
}
|
|
|
|
# replace the md5sums in the APKBUILD
|
|
checksum() {
|
|
local s files
|
|
[ -z "$source" ] && return 0
|
|
fetch
|
|
msg "Updating the md5sums in APKBUILD..."
|
|
for s in $source; do
|
|
files="$files ${s##*/}"
|
|
done
|
|
md5sums="$(cd "$srcdir" && md5sum $files)" || die "md5sum failed"
|
|
sed -i -e '/^md5sums="/,/"\$/d; /^md5sums=''/,/''\$/d' "$APKBUILD"
|
|
echo "md5sums=\"$md5sums\"" >>"$APKBUILD"
|
|
}
|
|
|
|
stripbin() {
|
|
local bin
|
|
if options_has "!strip" || [ "$arch" = "noarch" ]; then
|
|
return 0
|
|
fi
|
|
cd "${subpkgdir:-$pkgdir}" || return 1
|
|
msg "Stripping binaries"
|
|
scanelf --recursive --nobanner --etype "ET_DYN,ET_EXEC" . \
|
|
| sed -e 's:^ET_DYN ::' -e 's:^ET_EXEC ::' \
|
|
| xargs -r strip
|
|
}
|
|
|
|
# simply list target apks
|
|
listpkg() {
|
|
local name
|
|
getpkgver || return 1
|
|
for name in $(listpkgnames) ; do
|
|
echo "$name-$pkgver-r$pkgrel.apk"
|
|
done
|
|
}
|
|
|
|
source_has() {
|
|
local i
|
|
for i in $source; do
|
|
[ "$1" = "${i##*/}" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
subpackages_has() {
|
|
local i
|
|
for i in $subpackages; do
|
|
[ "$1" = "${i%:*}" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
list_has() {
|
|
local needle="$1"
|
|
local i
|
|
shift
|
|
for i in $@; do
|
|
[ "$needle" = "$i" ] && return 0
|
|
[ "$needle" = "!$i" ] && return 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# same as list_has but we filter version info
|
|
deplist_has() {
|
|
local needle="$1"
|
|
local i
|
|
shift
|
|
for i in $@; do
|
|
i=${i%%[<>=]*}
|
|
[ "$needle" = "$i" ] && return 0
|
|
[ "$needle" = "!$i" ] && return 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
options_has() {
|
|
list_has "$1" $options
|
|
}
|
|
|
|
depends_has() {
|
|
deplist_has "$1" $depends
|
|
}
|
|
|
|
makedepends_has() {
|
|
deplist_has "$1" $makedepends
|
|
}
|
|
|
|
md5sums_has() {
|
|
list_has "$1" $md5sums
|
|
}
|
|
|
|
install_has() {
|
|
list_has "$1" $install
|
|
}
|
|
|
|
# install package after build
|
|
post_add() {
|
|
getpkgver || return 1
|
|
local pkgf="$PKGDEST/$1-$pkgver-r$pkgrel.apk"
|
|
local deps i
|
|
if ! subpackages_has $1 && [ "$1" != "$pkgname" ]; then
|
|
die "$1 is not built by this APKBUILD"
|
|
fi
|
|
# recursively install dependencies that are provided by this APKBUILD
|
|
deps=$($APK index "$pkgf" 2>/dev/null | awk -F: '$1=="D" { print $2 }')
|
|
for i in $deps; do
|
|
if subpackages_has $i || [ "$i" = "$pkgname" ]; then
|
|
post_add $i || return 1
|
|
fi
|
|
done
|
|
$SUDO $APK add $apk_opt_wait -u "$pkgf" || die "Failed to install $1"
|
|
}
|
|
|
|
installdeps() {
|
|
local deps i
|
|
$SUDO $APK add $apk_opt_wait --repository "$abuildrepo" \
|
|
--virtual .makedepends-$pkgname \
|
|
$makedepends
|
|
}
|
|
|
|
uninstalldeps (){
|
|
$SUDO $APK del $apk_opt_wait .makedepends-$pkgname
|
|
}
|
|
|
|
all() {
|
|
if ! [ -n "$force" ]; then
|
|
check_arch || return 0
|
|
fi
|
|
if up2date && [ -z "$force" ]; then
|
|
msg "Package is up to date"
|
|
else
|
|
update_abuildrepo
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
echo "$program $abuild_ver"
|
|
echo "usage: $program [options] [-i PKG] [-P REPODEST] [-p PKGDEST]"
|
|
echo " [-s SRCDEST] [cmd] ..."
|
|
echo " $program [-c] -n PKGNAME[-PKGVER]"
|
|
echo "Options:"
|
|
echo " -c Enable colored output"
|
|
echo " -d Disable dependency checking"
|
|
echo " -f Force specified cmd, even if they are already done"
|
|
echo " -F Force run as root"
|
|
echo " -h Show this help"
|
|
echo " -i Install PKG after successul build"
|
|
echo " -k Keep built packages, even if APKBUILD or sources are newer"
|
|
echo " -m Disable colors (monochrome)"
|
|
echo " -p Set package destination directory"
|
|
echo " -P Set PKGDEST to REPODEST/<repo>, where repo is the parents dir name"
|
|
echo " -q Quiet"
|
|
echo " -r Install missing dependencies from system repository (using sudo)"
|
|
echo " -R Recursively build and install missing dependencies (using sudo)"
|
|
echo " -s Set source package destination directory"
|
|
echo " -u Recursively build and upgrade all dependencies (using sudo)"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " checksum Generate checksum to be included in APKBUILD"
|
|
echo " fetch Fetch sources to \$SRCDEST and verify checksums"
|
|
echo " sanitycheck Basic sanity check of APKBUILD"
|
|
echo " md5check Check md5sums"
|
|
echo " unpack Unpack sources to \$srcdir"
|
|
echo " build Compile and install package into \$pkgdir"
|
|
echo " listpkg List target packages"
|
|
echo " package Create package in \$PKGDEST"
|
|
echo " rootpkg Run '$0 build package' as fakeroot"
|
|
echo " clean Remove temp build and install dirs"
|
|
echo " cleanoldpkg Remove binary packages except current version"
|
|
echo " cleanpkg Remove already built binary and source package"
|
|
echo " cleancache Remove downloaded files from \$SRCDEST"
|
|
echo " srcpkg Make a source package"
|
|
echo " sourcecheck Check if remote source package exists upstream"
|
|
echo " up2date Compare target and sources dates"
|
|
echo " installdeps Install packages listed in makedepends and depends"
|
|
echo " uninstalldeps Uninstall packages listed in makedepends and depends"
|
|
echo ""
|
|
exit 0
|
|
}
|
|
|
|
APKBUILD="${APKBUILD:-./APKBUILD}"
|
|
unset force
|
|
unset recursive
|
|
while getopts "cdfFhi:kimnp:P:qrRs:u" opt; do
|
|
case $opt in
|
|
'c') default_colors
|
|
color_opt="-c";;
|
|
'd') nodeps=1;;
|
|
'f') force="-f";;
|
|
'F') forceroot="-F";;
|
|
'h') usage;;
|
|
'i') install_after="$install_after $OPTARG";;
|
|
'k') keep="-k";;
|
|
'm') monochrome
|
|
color_opt="-m";;
|
|
'n') die "Use newapkbuild to create new aports";;
|
|
'p') PKGDEST=$OPTARG;;
|
|
'P') REPODEST=$OPTARG;;
|
|
'q') quiet="-q";;
|
|
'r') install_deps="-r";;
|
|
'R') recursive="-R";;
|
|
's') SRCDEST=$OPTARG;;
|
|
'u') upgrade="-u"
|
|
recursive="-R";;
|
|
esac
|
|
done
|
|
shift $(( $OPTIND - 1 ))
|
|
|
|
# check so we are not root
|
|
if [ "$(whoami)" = "root" ] && [ -z "$FAKEROOTKEY" ]; then
|
|
[ -z "$forceroot" ] && die "Do not run abuild as root"
|
|
SUDO=
|
|
FAKEROOT=
|
|
fi
|
|
|
|
# find startdir
|
|
[ -f "$APKBUILD" ] || die "Could not find $APKBUILD (PWD=$PWD)"
|
|
APKBUILD=$(readlink -f "$APKBUILD")
|
|
|
|
startdir="${APKBUILD%/*}"
|
|
srcdir=${srcdir:-"$startdir/src"}
|
|
pkgbasedir=${pkgbasedir:-"$startdir/pkg"}
|
|
pkgrel=0
|
|
repo=${startdir%/*}
|
|
repo=${repo##*/}
|
|
|
|
SRCDEST=${SRCDEST:-$startdir}
|
|
PKGDEST=${PKGDEST:-$startdir}
|
|
|
|
cd "$startdir" || die
|
|
. "$APKBUILD"
|
|
|
|
# If REPODEST is set then it will override the PKGDEST
|
|
if [ -n "$REPODEST" ]; then
|
|
PKGDEST="$REPODEST/$repo"
|
|
fi
|
|
|
|
# If we are handling a sub package then reset subpackages and install
|
|
if [ -n "$subpkgname" ]; then
|
|
origsubpackages="$subpackages"
|
|
subpackages=
|
|
install=
|
|
fi
|
|
pkgdir="$pkgbasedir/$pkgname"
|
|
controldir="$pkgbasedir"/.control.${subpkgname:-$pkgname}
|
|
|
|
trap 'die "Aborted by user"' INT
|
|
set_xterm_title "abuild: $pkgname"
|
|
|
|
if [ -z "$1" ]; then
|
|
set all
|
|
fi
|
|
|
|
while [ $# -gt 0 ]; do
|
|
runpart $1
|
|
shift
|
|
done
|
|
|
|
for i in $install_after; do
|
|
post_add $i
|
|
done
|
|
|
|
cleanup
|
|
|