newapkbuild.in 9.9 KB
Newer Older
1
#!/bin/sh
2
#
3
# newapkbuild - generate a new APKBUILD
4 5 6 7 8
# Copyright (c) 2009 Natanael Copa <natanael.copa@gmail.com>
#
# Distributed under GPL-2
#

9
program_version=@VERSION@
10
sharedir=${ABUILD_SHAREDIR:-@sharedir@}
11

Natanael Copa's avatar
Natanael Copa committed
12 13
if ! [ -f "$sharedir/functions.sh" ]; then
	echo "$sharedir/functions.sh: not found" >&2
14 15
	exit 1
fi
Natanael Copa's avatar
Natanael Copa committed
16
. "$sharedir/functions.sh"
17 18


19 20
is_url() {
	case "$1" in
21
	http://*|https://*|ftp://*) return 0;;
22
	esac
23
	return 1
24 25
}

26 27 28 29 30 31 32
is_github_url() {
	case $1 in
	https://github.com/*/*/archive/*.tar.gz) return 0;;
	esac
	return 1
}

33
# Build sections
34 35
build_make() {
	cat >>APKBUILD<<__EOF__
36
	make
37 38 39
__EOF__
}

40
build_autotools() {
41
	cat >>APKBUILD<<__EOF__
42 43 44 45
	./configure \\
		--build=\$CBUILD \\
		--host=\$CHOST \\
		--prefix=/usr \\
46 47
		--sysconfdir=/etc \\
		--mandir=/usr/share/man \\
48 49
		--localstatedir=/var
	make
50 51 52
__EOF__
}

Isaac Dunham's avatar
Isaac Dunham committed
53 54 55
build_cmake() {
# References:
# http://www.cmake.org/Wiki/CMake_Useful_Variables
56 57
# http://www.vtk.org/Wiki/CMake_Cross_Compiling
# This is incomplete: CMAKE_{HOST_,}SYSTEM_PROCESSOR needs to be set,
Isaac Dunham's avatar
Isaac Dunham committed
58 59 60
# and likewise CMAKE_FIND_ROOT_PATH and a few other details.

	cat >>APKBUILD<<__EOF__
61
	if [ "\$CBUILD" != "\$CHOST" ]; then
Isaac Dunham's avatar
Isaac Dunham committed
62 63
		CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux"
	fi
64
	cmake -B build \\
Isaac Dunham's avatar
Isaac Dunham committed
65 66 67
		-DCMAKE_INSTALL_PREFIX=/usr \\
		-DCMAKE_INSTALL_LIBDIR=lib \\
		-DBUILD_SHARED_LIBS=True \\
68
		-DCMAKE_BUILD_TYPE=None \\
69
		\${CMAKE_CROSSOPTS} .
70
	cmake --build build
Isaac Dunham's avatar
Isaac Dunham committed
71 72 73
__EOF__
}

74 75 76 77 78 79 80 81 82 83 84 85
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 \\
86
		--buildtype=plain \\
87
		. output
88
	meson compile ${JOBS:+-j ${JOBS}} -C output
89 90 91
__EOF__
}

92
build_perl() {
93
	cat >>APKBUILD<<__EOF__
94 95
	PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor
	make
96 97 98
__EOF__
}

99
build_python() {
100
	cat >>APKBUILD<<__EOF__
101
	python3 setup.py build
102 103 104
__EOF__
}

Rasmus Thomsen's avatar
Rasmus Thomsen committed
105 106
build_rust() {
	cat >>APKBUILD<<__EOF__
107
	cargo build --release --locked
Rasmus Thomsen's avatar
Rasmus Thomsen committed
108 109 110
__EOF__
}

111 112 113 114 115 116 117
build_empty() {
	cat >>APKBUILD<<__EOF__
	# Replace with proper build command(s)
	:
__EOF__
}

118
# Check sections
119 120 121 122 123 124
check_make() {
	cat >>APKBUILD<<__EOF__
	make check
__EOF__
}

125 126
check_cmake() {
	cat >>APKBUILD<<__EOF__
127 128
	cd build
	CTEST_OUTPUT_ON_FAILURE=TRUE ctest
129 130 131
__EOF__
}

132 133
check_python() {
	cat >>APKBUILD<<__EOF__
134
	python3 setup.py test
135 136 137
__EOF__
}

138 139 140 141 142 143 144
check_empty() {
	cat >>APKBUILD<<__EOF__
	# Replace with proper check command(s)
	:
__EOF__
}

145 146
check_meson() {
	cat >>APKBUILD<<__EOF__
147
	meson test --no-rebuild -v -C output
148 149 150
__EOF__
}

Rasmus Thomsen's avatar
Rasmus Thomsen committed
151 152
check_rust() {
	cat >>APKBUILD<<__EOF__
153
	cargo test --release --locked
Rasmus Thomsen's avatar
Rasmus Thomsen committed
154 155 156
__EOF__
}

157
# Package sections
158
package_make() {
159
	cat >>APKBUILD<<__EOF__
160
	make DESTDIR="\$pkgdir" install
161 162 163
__EOF__
}

164 165
package_cmake() {
	cat >>APKBUILD<<__EOF__
166
	DESTDIR="\$pkgdir" cmake --build build --target install
167 168 169
__EOF__
}

170 171 172 173
package_autotools() {
	package_make
}

174 175
package_meson() {
	cat >>APKBUILD<<__EOF__
176
	DESTDIR="\$pkgdir" meson install --no-rebuild -C output
177 178 179
__EOF__
}

180
package_perl() {
181
	cat >>APKBUILD<<__EOF__
182
	make DESTDIR="\$pkgdir" install
183 184 185 186
	find "\$pkgdir" \\( -name perllocal.pod -o -name .packlist \\) -delete
__EOF__
}

187 188
package_python() {
	cat >>APKBUILD<<__EOF__
189
	python3 setup.py install --prefix=/usr --root="\$pkgdir"
190 191 192
__EOF__
}

193 194 195 196 197 198 199
package_empty() {
	cat >>APKBUILD<<__EOF__
	# Replace with proper package command(s)
	:
__EOF__
}

Rasmus Thomsen's avatar
Rasmus Thomsen committed
200 201
package_rust() {
	cat >>APKBUILD<<__EOF__
202
	cargo install --locked --path . --root="\$pkgdir/usr"
Rasmus Thomsen's avatar
Rasmus Thomsen committed
203 204 205 206
	rm "\$pkgdir"/usr/.crates.toml
__EOF__
}

207
# Create new aport from templates
208
newaport() {
209
	local newname="${1##*/}"
210 211
	local pn=${newname%-[0-9]*}
	local pv
212 213 214
	local source=
	is_url "$1" && source="$1"

215 216 217 218 219 220 221
	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]}
222
		source="${source%.t*}/$pkgname-$pv.tar.gz"
223
	elif [ "$pn" != "$newname" ]; then
224
		pv=${newname#$pn-}
225
		pv=${pv%.t*} #strip .tar.gz .tgz .tar.bz2 etc
226
	fi
227 228 229 230
	if [ -z "$pkgname" ]; then
		pkgname=$pn
	fi
	if [ -e "$pkgname"/APKBUILD ] && [ -z "$force" ]; then
A. Wilcox's avatar
A. Wilcox committed
231
		error "$pkgname/APKBUILD already exists"
232 233
		return 1
	fi
234 235
	mkdir -p "$pkgname"
	cd "$pkgname"
Natanael Copa's avatar
Natanael Copa committed
236

237
	if [ -z "$source" ] && [ -n "$sourceforge" ]; then
238
		source="https://downloads.sourceforge.net/$pn/$pn-$pv.tar.gz"
239 240
	fi

241
	if [ -z "$depends" ] &&[ "$buildtype" = "python" ]; then
242
		depends="python3"
243 244
	fi

245
	case "$buildtype" in
246
	python) makedepends="py3-setuptools";;
247 248
	cmake)  makedepends="cmake";;
	meson)  makedepends="meson";;
Rasmus Thomsen's avatar
Rasmus Thomsen committed
249
	rust)   makedepends="cargo";;
250 251
	*)      makedepends="\$depends_dev";;
	esac
252 253

	# Replace pkgver in $source
254
	if [ -n "$source" ]; then
255
		source=$(echo "$source" | sed "s/$pv/\$pkgver/g")
256
	fi
Natanael Copa's avatar
Natanael Copa committed
257

258
	# Copy init.d scripts if requested
259
	if [ -n "$cpinitd" ]; then
Natanael Copa's avatar
Natanael Copa committed
260 261 262 263
		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
Natanael Copa's avatar
Natanael Copa committed
264 265
		install="\$pkgname.pre-install \$pkgname.post-install"
		source="$source
266 267
	$pkgname.initd
	$pkgname.confd
Natanael Copa's avatar
Natanael Copa committed
268 269 270
	"
	fi

271
	# Generate header with standard variables
Natanael Copa's avatar
Natanael Copa committed
272 273 274
	cat >APKBUILD<<__EOF__
# Contributor:${PACKAGER:+" "}${PACKAGER}
# Maintainer:${MAINTAINER:+" "}${MAINTAINER}
275 276
pkgname=$pkgname
pkgver=$pv
Natanael Copa's avatar
Natanael Copa committed
277 278 279 280 281
pkgrel=0
pkgdesc="$pkgdesc"
url="$url"
arch="all"
license="$license"
282 283 284
depends="$depends"
depends_dev=""
makedepends="$makedepends"
Natanael Copa's avatar
Natanael Copa committed
285 286 287 288 289
install="$install"
subpackages="\$pkgname-dev \$pkgname-doc"
source="$source"
__EOF__

290
	abuild -f fetch checksum unpack
291
	# Figure out the builddir
Natanael Copa's avatar
Natanael Copa committed
292 293 294
	for i in src/*; do
		if [ -d "$i" ]; then
			sdir=$i
295
			builddir=$(echo ${i#*/} | sed "s/$pv/\$pkgver/g")
Natanael Copa's avatar
Natanael Copa committed
296 297
		fi
	done
298
	printf 'builddir="$srcdir/%s"\n\n' "$builddir" >> APKBUILD
Natanael Copa's avatar
Natanael Copa committed
299

300 301
	# 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.
302
	find "$sdir" -name "*.h" -o -name "*.hpp" -maxdepth 3 2>/dev/null \
303 304 305
		| head -n 1 | grep -q ".*" \
		|| sed -i -e '/^depends_dev=.*/d' -e 's/\$depends_dev\s*//' APKBUILD

306
	# Try to autodetect the buildtype
307 308 309
	if [ -z "$buildtype" ]; then
		if [ -x "$sdir"/configure ]; then
			buildtype="autotools"
310
		elif [ -r "$sdir"/Makefile.PL ] || [ "${pn#perl-}" != "$pn" ]; then
311 312 313
			buildtype="perl"
		elif [ -r "$sdir"/waf ]; then
			buildtype="waf"
314 315
		elif [ -r "$sdir"/meson.build ]; then
			buildtype="meson"
316
		elif [ -d "$sdir"/cmake ] || [ -r "$sdir/CMakeLists.txt" ]; then
317 318 319
			buildtype="cmake"
		elif [ -r "$sdir"/Makefile ]; then
			buildtype="make"
320
		elif [ -r "$sdir"/setup.py ] || [ "${pn#py[0-9]-}" != "$pn" ]; then
321
			buildtype="python"
Rasmus Thomsen's avatar
Rasmus Thomsen committed
322 323
		elif [ -r "$sdir"/Cargo.toml ]; then
			buildtype="rust"
324 325 326
		fi
	fi

327
	# Create build() function
Natanael Copa's avatar
Natanael Copa committed
328 329 330
	cat >>APKBUILD<<__EOF__
build() {
__EOF__
331 332

	case "$buildtype" in
333 334
	make)
		build_make;;
Isaac Dunham's avatar
Isaac Dunham committed
335 336
	cmake)
		build_cmake;;
337 338
	meson)
		build_meson;;
339
	autotools)
340
		build_autotools;;
341
	perl)
342
		build_perl;;
343
	python)
344
		build_python;;
Rasmus Thomsen's avatar
Rasmus Thomsen committed
345 346
	rust)
		build_rust;;
347 348
	*)
		build_empty;;
349 350
	esac

Natanael Copa's avatar
Natanael Copa committed
351 352 353
	cat >>APKBUILD<<__EOF__
}

354 355 356 357 358 359 360 361
__EOF__

	# Create check() function
	cat >>APKBUILD<<__EOF__
check() {
__EOF__

	case "$buildtype" in
362
	make|autotools|perl)
363
		check_make;;
364 365
	cmake)
		check_cmake;;
366 367
	python)
		check_python;;
Rasmus Thomsen's avatar
Rasmus Thomsen committed
368 369
	rust)
		check_rust;;
370 371
	*)
		check_empty;;
372 373 374 375 376
	esac

	cat >>APKBUILD<<__EOF__
}

Natanael Copa's avatar
Natanael Copa committed
377 378
__EOF__

379
	# Create package() function
Natanael Copa's avatar
Natanael Copa committed
380 381 382
	cat >>APKBUILD<<__EOF__
package() {
__EOF__
383 384

	case "$buildtype" in
385
	make)
386
		package_make;;
387 388
	cmake)
		package_cmake;;
389 390
	autotools)
		package_autotools;;
391 392
	meson)
		package_meson;;
393 394 395 396
	perl)
		package_perl;;
	python)
		package_python;;
Rasmus Thomsen's avatar
Rasmus Thomsen committed
397 398
	rust)
		package_rust;;
399 400
	*)
		package_empty;;
401 402
	esac

403 404 405 406
	if [ -n "$cpinitd" ]; then
		cat >>APKBUILD<<__EOF__

	install -m755 -D "\$srcdir"/\$pkgname.initd \\
407
		"\$pkgdir"/etc/init.d/\$pkgname
408
	install -m644 -D "\$srcdir"/\$pkgname.confd \\
409
		"\$pkgdir"/etc/conf.d/\$pkgname
410 411
__EOF__
	fi
Natanael Copa's avatar
Natanael Copa committed
412 413 414 415
	cat >>APKBUILD<<__EOF__
}

__EOF__
416 417 418

	# regenerate checksum so they end last in APKBUILD
	abuild -f checksum
419 420 421
}

usage() {
Jakub Jirutka's avatar
Jakub Jirutka committed
422 423
	cat >&2 <<-__EOF__
		$program $program_version - generate a new APKBUILD
424
		Usage: $program [-n PKGNAME] [-d PKGDESC] [-l LICENSE] [-u URL]
Rasmus Thomsen's avatar
Rasmus Thomsen committed
425
		       [-a | -C | -m | -p | -y | -r] [-s] [-c] [-f] [-h]
426
		       PKGNAME[-PKGVER] | SRCURL
Jakub Jirutka's avatar
Jakub Jirutka committed
427
		Options:
428 429 430 431
		  -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/>
Jakub Jirutka's avatar
Jakub Jirutka committed
432
		  -u  Set package URL
433
		  -a  Create autotools package (use ./configure ...)
Oliver Smith's avatar
Oliver Smith committed
434
		  -C  Create CMake package (Assume cmake/ is there)
435
		  -m  Create meson package (Assume meson.build is there)
Jakub Jirutka's avatar
Jakub Jirutka committed
436 437
		  -p  Create perl package (Assume Makefile.PL is there)
		  -y  Create python package (Assume setup.py is there)
Rasmus Thomsen's avatar
Rasmus Thomsen committed
438
		  -r  Crate rust package (Assume Cargo.toml is there)
Jakub Jirutka's avatar
Jakub Jirutka committed
439
		  -s  Use sourceforge source URL
440 441
		  -c  Copy a sample init.d, conf.d, and install script
		  -f  Force even if directory already exists
Jakub Jirutka's avatar
Jakub Jirutka committed
442 443
		  -h  Show this help
	__EOF__
444 445
}

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
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
464
	if [ -n "$1" ] && ! is_url "$1" && [ -n "$pkgname" ]; then
465 466 467 468 469 470 471 472 473
		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
}

Rasmus Thomsen's avatar
Rasmus Thomsen committed
474
while getopts "acCmd:fhl:n:pyu:sr" opt; do
475
	case $opt in
476
		'a') set_buildtype "autotools";;
477
		'c') cpinitd=1;;
478 479
		'C') set_buildtype "cmake";;
		'm') set_buildtype "meson";;
Natanael Copa's avatar
Natanael Copa committed
480
		'd') pkgdesc="$OPTARG";;
481
		'f') force=1;;
482
		'h') usage; exit;;
Natanael Copa's avatar
Natanael Copa committed
483
		'l') license="$OPTARG";;
484
		'n') pkgname="$OPTARG";;
485 486
		'p') set_buildtype "perl";;
		'y') set_buildtype "python";;
Rasmus Thomsen's avatar
Rasmus Thomsen committed
487
		'r') set_buildtype "rust";;
Natanael Copa's avatar
Natanael Copa committed
488
		'u') url="$OPTARG";;
489
		's') sourceforge=1;;
490 491 492 493
	esac
done
shift $(( $OPTIND - 1 ))

494 495
check_arguments "$@"
newaport $1