mirror of
https://gitlab.alpinelinux.org/alpine/abuild.git
synced 2024-12-24 07:52:30 +00:00
2cc63809ad
This has multiple advantages:
* It's tool agnostic (e.g. if we were to drop the ninja symlink
for samu, we wouldn't have to change anything here)
* It allows for more fine grained control, e.g. in meson test,
where we can increase timeouts and print the test log to stdout,
something which we can't control when invoking it via ninja.
* We can pass --no-rebuild to test and install, so ninja doesn't
have to check if anything has to be rebuild against in the test
and install phase, when we built everything in the build phase
already
This is similiar to dd24cdf85f
, but
for meson.
496 lines
9.9 KiB
Bash
496 lines
9.9 KiB
Bash
#!/bin/sh
|
|
#
|
|
# newapkbuild - generate a new APKBUILD
|
|
# Copyright (c) 2009 Natanael Copa <natanael.copa@gmail.com>
|
|
#
|
|
# Distributed under GPL-2
|
|
#
|
|
|
|
program_version=@VERSION@
|
|
sharedir=${ABUILD_SHAREDIR:-@sharedir@}
|
|
|
|
if ! [ -f "$sharedir/functions.sh" ]; then
|
|
echo "$sharedir/functions.sh: not found" >&2
|
|
exit 1
|
|
fi
|
|
. "$sharedir/functions.sh"
|
|
|
|
|
|
is_url() {
|
|
case "$1" in
|
|
http://*|https://*|ftp://*) return 0;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
is_github_url() {
|
|
case $1 in
|
|
https://github.com/*/*/archive/*.tar.gz) return 0;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
# Build sections
|
|
build_make() {
|
|
cat >>APKBUILD<<__EOF__
|
|
make
|
|
__EOF__
|
|
}
|
|
|
|
build_autotools() {
|
|
cat >>APKBUILD<<__EOF__
|
|
./configure \\
|
|
--build=\$CBUILD \\
|
|
--host=\$CHOST \\
|
|
--prefix=/usr \\
|
|
--sysconfdir=/etc \\
|
|
--mandir=/usr/share/man \\
|
|
--localstatedir=/var
|
|
make
|
|
__EOF__
|
|
}
|
|
|
|
build_cmake() {
|
|
# References:
|
|
# http://www.cmake.org/Wiki/CMake_Useful_Variables
|
|
# http://www.vtk.org/Wiki/CMake_Cross_Compiling
|
|
# This is incomplete: CMAKE_{HOST_,}SYSTEM_PROCESSOR needs to be set,
|
|
# and likewise CMAKE_FIND_ROOT_PATH and a few other details.
|
|
|
|
cat >>APKBUILD<<__EOF__
|
|
if [ "\$CBUILD" != "\$CHOST" ]; then
|
|
CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux"
|
|
fi
|
|
cmake -B build \\
|
|
-DCMAKE_INSTALL_PREFIX=/usr \\
|
|
-DCMAKE_INSTALL_LIBDIR=lib \\
|
|
-DBUILD_SHARED_LIBS=True \\
|
|
-DCMAKE_BUILD_TYPE=None \\
|
|
\${CMAKE_CROSSOPTS} .
|
|
cmake --build build
|
|
__EOF__
|
|
}
|
|
|
|
build_meson() {
|
|
# References:
|
|
# http://mesonbuild.com/Reference-manual.html
|
|
# http://mesonbuild.com/Cross-compilation.html
|
|
# TODO For cross compilation a cross_file needs to be created.
|
|
|
|
cat >>APKBUILD<<__EOF__
|
|
meson \\
|
|
--prefix=/usr \\
|
|
--sysconfdir=/etc \\
|
|
--mandir=/usr/share/man \\
|
|
--localstatedir=/var \\
|
|
--buildtype=plain \\
|
|
. output
|
|
meson compile ${JOBS:+-j ${JOBS}} -C output
|
|
__EOF__
|
|
}
|
|
|
|
build_perl() {
|
|
cat >>APKBUILD<<__EOF__
|
|
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor
|
|
make
|
|
__EOF__
|
|
}
|
|
|
|
build_python() {
|
|
cat >>APKBUILD<<__EOF__
|
|
python3 setup.py build
|
|
__EOF__
|
|
}
|
|
|
|
build_rust() {
|
|
cat >>APKBUILD<<__EOF__
|
|
cargo build --release --locked
|
|
__EOF__
|
|
}
|
|
|
|
build_empty() {
|
|
cat >>APKBUILD<<__EOF__
|
|
# Replace with proper build command(s)
|
|
:
|
|
__EOF__
|
|
}
|
|
|
|
# Check sections
|
|
check_make() {
|
|
cat >>APKBUILD<<__EOF__
|
|
make check
|
|
__EOF__
|
|
}
|
|
|
|
check_cmake() {
|
|
cat >>APKBUILD<<__EOF__
|
|
cd build
|
|
CTEST_OUTPUT_ON_FAILURE=TRUE ctest
|
|
__EOF__
|
|
}
|
|
|
|
check_python() {
|
|
cat >>APKBUILD<<__EOF__
|
|
python3 setup.py test
|
|
__EOF__
|
|
}
|
|
|
|
check_empty() {
|
|
cat >>APKBUILD<<__EOF__
|
|
# Replace with proper check command(s)
|
|
:
|
|
__EOF__
|
|
}
|
|
|
|
check_meson() {
|
|
cat >>APKBUILD<<__EOF__
|
|
meson test --no-rebuild -v -C output
|
|
__EOF__
|
|
}
|
|
|
|
check_rust() {
|
|
cat >>APKBUILD<<__EOF__
|
|
cargo test --release --locked
|
|
__EOF__
|
|
}
|
|
|
|
# Package sections
|
|
package_make() {
|
|
cat >>APKBUILD<<__EOF__
|
|
make DESTDIR="\$pkgdir" install
|
|
__EOF__
|
|
}
|
|
|
|
package_cmake() {
|
|
cat >>APKBUILD<<__EOF__
|
|
DESTDIR="\$pkgdir" cmake --build build --target install
|
|
__EOF__
|
|
}
|
|
|
|
package_autotools() {
|
|
package_make
|
|
}
|
|
|
|
package_meson() {
|
|
cat >>APKBUILD<<__EOF__
|
|
DESTDIR="\$pkgdir" meson install --no-rebuild -C output
|
|
__EOF__
|
|
}
|
|
|
|
package_perl() {
|
|
cat >>APKBUILD<<__EOF__
|
|
make DESTDIR="\$pkgdir" install
|
|
find "\$pkgdir" \\( -name perllocal.pod -o -name .packlist \\) -delete
|
|
__EOF__
|
|
}
|
|
|
|
package_python() {
|
|
cat >>APKBUILD<<__EOF__
|
|
python3 setup.py install --prefix=/usr --root="\$pkgdir"
|
|
__EOF__
|
|
}
|
|
|
|
package_empty() {
|
|
cat >>APKBUILD<<__EOF__
|
|
# Replace with proper package command(s)
|
|
:
|
|
__EOF__
|
|
}
|
|
|
|
package_rust() {
|
|
cat >>APKBUILD<<__EOF__
|
|
cargo install --locked --path . --root="\$pkgdir/usr"
|
|
rm "\$pkgdir"/usr/.crates.toml
|
|
__EOF__
|
|
}
|
|
|
|
# Create new aport from templates
|
|
newaport() {
|
|
local newname="${1##*/}"
|
|
local pn=${newname%-[0-9]*}
|
|
local pv
|
|
local source=
|
|
is_url "$1" && source="$1"
|
|
|
|
if is_github_url $source; then
|
|
if [ -z "$pkgname" ]; then
|
|
pkgname=${source%/archive/*}
|
|
pkgname=${pkgname##*/}
|
|
fi
|
|
pv=${newname%.t*} #strip .tar.gz .tgz .tar.bz2 etc
|
|
pv=${pv#*[a-z]}
|
|
source="${source%.t*}/$pkgname-$pv.tar.gz"
|
|
elif [ "$pn" != "$newname" ]; then
|
|
pv=${newname#$pn-}
|
|
pv=${pv%.t*} #strip .tar.gz .tgz .tar.bz2 etc
|
|
fi
|
|
if [ -z "$pkgname" ]; then
|
|
pkgname=$pn
|
|
fi
|
|
if [ -e "$pkgname"/APKBUILD ] && [ -z "$force" ]; then
|
|
error "$pkgname/APKBUILD already exists"
|
|
return 1
|
|
fi
|
|
mkdir -p "$pkgname"
|
|
cd "$pkgname"
|
|
|
|
if [ -z "$source" ] && [ -n "$sourceforge" ]; then
|
|
source="https://downloads.sourceforge.net/$pn/$pn-$pv.tar.gz"
|
|
fi
|
|
|
|
if [ -z "$depends" ] &&[ "$buildtype" = "python" ]; then
|
|
depends="python3"
|
|
fi
|
|
|
|
case "$buildtype" in
|
|
python) makedepends="py3-setuptools";;
|
|
cmake) makedepends="cmake";;
|
|
meson) makedepends="meson";;
|
|
rust) makedepends="cargo";;
|
|
*) makedepends="\$depends_dev";;
|
|
esac
|
|
|
|
# Replace pkgver in $source
|
|
if [ -n "$source" ]; then
|
|
source=$(echo "$source" | sed "s/$pv/\$pkgver/g")
|
|
fi
|
|
|
|
# Copy init.d scripts if requested
|
|
if [ -n "$cpinitd" ]; then
|
|
cp "$sharedir"/sample.initd $pkgname.initd
|
|
cp "$sharedir"/sample.confd $pkgname.confd
|
|
cp "$sharedir"/sample.pre-install $pkgname.pre-install
|
|
cp "$sharedir"/sample.post-install $pkgname.post-install
|
|
install="\$pkgname.pre-install \$pkgname.post-install"
|
|
source="$source
|
|
$pkgname.initd
|
|
$pkgname.confd
|
|
"
|
|
fi
|
|
|
|
# Generate header with standard variables
|
|
cat >APKBUILD<<__EOF__
|
|
# Contributor:${PACKAGER:+" "}${PACKAGER}
|
|
# Maintainer:${MAINTAINER:+" "}${MAINTAINER}
|
|
pkgname=$pkgname
|
|
pkgver=$pv
|
|
pkgrel=0
|
|
pkgdesc="$pkgdesc"
|
|
url="$url"
|
|
arch="all"
|
|
license="$license"
|
|
depends="$depends"
|
|
depends_dev=""
|
|
makedepends="$makedepends"
|
|
install="$install"
|
|
subpackages="\$pkgname-dev \$pkgname-doc"
|
|
source="$source"
|
|
__EOF__
|
|
|
|
abuild -f fetch checksum unpack
|
|
# Figure out the builddir
|
|
for i in src/*; do
|
|
if [ -d "$i" ]; then
|
|
sdir=$i
|
|
builddir=$(echo ${i#*/} | sed "s/$pv/\$pkgver/g")
|
|
fi
|
|
done
|
|
printf 'builddir="$srcdir/%s"\n\n' "$builddir" >> APKBUILD
|
|
|
|
# Subpackage -dev is usually required only for C/C++. Since depends_dev
|
|
# confuses a lot people, remove it if there's no .h or .hpp file.
|
|
find "$sdir" -name "*.h" -o -name "*.hpp" -maxdepth 3 2>/dev/null \
|
|
| head -n 1 | grep -q ".*" \
|
|
|| sed -i -e '/^depends_dev=.*/d' -e 's/\$depends_dev\s*//' APKBUILD
|
|
|
|
# Try to autodetect the buildtype
|
|
if [ -z "$buildtype" ]; then
|
|
if [ -x "$sdir"/configure ]; then
|
|
buildtype="autotools"
|
|
elif [ -r "$sdir"/Makefile.PL ] || [ "${pn#perl-}" != "$pn" ]; then
|
|
buildtype="perl"
|
|
elif [ -r "$sdir"/waf ]; then
|
|
buildtype="waf"
|
|
elif [ -r "$sdir"/meson.build ]; then
|
|
buildtype="meson"
|
|
elif [ -d "$sdir"/cmake ] || [ -r "$sdir/CMakeLists.txt" ]; then
|
|
buildtype="cmake"
|
|
elif [ -r "$sdir"/Makefile ]; then
|
|
buildtype="make"
|
|
elif [ -r "$sdir"/setup.py ] || [ "${pn#py[0-9]-}" != "$pn" ]; then
|
|
buildtype="python"
|
|
elif [ -r "$sdir"/Cargo.toml ]; then
|
|
buildtype="rust"
|
|
fi
|
|
fi
|
|
|
|
# Create build() function
|
|
cat >>APKBUILD<<__EOF__
|
|
build() {
|
|
__EOF__
|
|
|
|
case "$buildtype" in
|
|
make)
|
|
build_make;;
|
|
cmake)
|
|
build_cmake;;
|
|
meson)
|
|
build_meson;;
|
|
autotools)
|
|
build_autotools;;
|
|
perl)
|
|
build_perl;;
|
|
python)
|
|
build_python;;
|
|
rust)
|
|
build_rust;;
|
|
*)
|
|
build_empty;;
|
|
esac
|
|
|
|
cat >>APKBUILD<<__EOF__
|
|
}
|
|
|
|
__EOF__
|
|
|
|
# Create check() function
|
|
cat >>APKBUILD<<__EOF__
|
|
check() {
|
|
__EOF__
|
|
|
|
case "$buildtype" in
|
|
make|autotools|perl)
|
|
check_make;;
|
|
cmake)
|
|
check_cmake;;
|
|
python)
|
|
check_python;;
|
|
rust)
|
|
check_rust;;
|
|
*)
|
|
check_empty;;
|
|
esac
|
|
|
|
cat >>APKBUILD<<__EOF__
|
|
}
|
|
|
|
__EOF__
|
|
|
|
# Create package() function
|
|
cat >>APKBUILD<<__EOF__
|
|
package() {
|
|
__EOF__
|
|
|
|
case "$buildtype" in
|
|
make)
|
|
package_make;;
|
|
cmake)
|
|
package_cmake;;
|
|
autotools)
|
|
package_autotools;;
|
|
meson)
|
|
package_meson;;
|
|
perl)
|
|
package_perl;;
|
|
python)
|
|
package_python;;
|
|
rust)
|
|
package_rust;;
|
|
*)
|
|
package_empty;;
|
|
esac
|
|
|
|
if [ -n "$cpinitd" ]; then
|
|
cat >>APKBUILD<<__EOF__
|
|
|
|
install -m755 -D "\$srcdir"/\$pkgname.initd \\
|
|
"\$pkgdir"/etc/init.d/\$pkgname
|
|
install -m644 -D "\$srcdir"/\$pkgname.confd \\
|
|
"\$pkgdir"/etc/conf.d/\$pkgname
|
|
__EOF__
|
|
fi
|
|
cat >>APKBUILD<<__EOF__
|
|
}
|
|
|
|
__EOF__
|
|
|
|
# regenerate checksum so they end last in APKBUILD
|
|
abuild -f checksum
|
|
}
|
|
|
|
usage() {
|
|
cat >&2 <<-__EOF__
|
|
$program $program_version - generate a new APKBUILD
|
|
Usage: $program [-n PKGNAME] [-d PKGDESC] [-l LICENSE] [-u URL]
|
|
[-a | -C | -m | -p | -y | -r] [-s] [-c] [-f] [-h]
|
|
PKGNAME[-PKGVER] | SRCURL
|
|
Options:
|
|
-n Set package name to PKGNAME (only use with SRCURL)
|
|
-d Set package description to PKGDESC
|
|
-l Set package license to LICENSE, use identifiers from:
|
|
<https://spdx.org/licenses/>
|
|
-u Set package URL
|
|
-a Create autotools package (use ./configure ...)
|
|
-C Create CMake package (Assume cmake/ is there)
|
|
-m Create meson package (Assume meson.build is there)
|
|
-p Create perl package (Assume Makefile.PL is there)
|
|
-y Create python package (Assume setup.py is there)
|
|
-r Crate rust package (Assume Cargo.toml is there)
|
|
-s Use sourceforge source URL
|
|
-c Copy a sample init.d, conf.d, and install script
|
|
-f Force even if directory already exists
|
|
-h Show this help
|
|
__EOF__
|
|
}
|
|
|
|
set_buildtype() {
|
|
if [ -n "$buildtype" ]; then
|
|
error "More than one buildtype flag specified ($buildtype and $1)"
|
|
exit 1
|
|
fi
|
|
buildtype="$1"
|
|
}
|
|
|
|
check_arguments() {
|
|
if [ $# -eq 0 ]; then
|
|
error "Missing required argument: PKGNAME[-PKGVER] | SRCURL"
|
|
exit 1
|
|
fi
|
|
if [ $# -gt 1 ]; then
|
|
shift
|
|
error "Unrecognized arguments: $*"
|
|
exit 1
|
|
fi
|
|
if [ -n "$1" ] && ! is_url "$1" && [ -n "$pkgname" ]; then
|
|
error "-n is only allowed when using SRCURL as last argument"
|
|
exit 1
|
|
fi
|
|
if is_url "$1" && [ -n "$sourceforge" ]; then
|
|
error "-s is only allowed when using PKGNAME as last argument"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
while getopts "acCmd:fhl:n:pyu:sr" opt; do
|
|
case $opt in
|
|
'a') set_buildtype "autotools";;
|
|
'c') cpinitd=1;;
|
|
'C') set_buildtype "cmake";;
|
|
'm') set_buildtype "meson";;
|
|
'd') pkgdesc="$OPTARG";;
|
|
'f') force=1;;
|
|
'h') usage; exit;;
|
|
'l') license="$OPTARG";;
|
|
'n') pkgname="$OPTARG";;
|
|
'p') set_buildtype "perl";;
|
|
'y') set_buildtype "python";;
|
|
'r') set_buildtype "rust";;
|
|
'u') url="$OPTARG";;
|
|
's') sourceforge=1;;
|
|
esac
|
|
done
|
|
shift $(( $OPTIND - 1 ))
|
|
|
|
check_arguments "$@"
|
|
newaport $1
|