abuild 17.5 KB
Newer Older
Natanael Copa's avatar
Natanael Copa committed
1 2 3 4 5 6 7 8 9 10
#!/bin/sh

# script to build apk packages (light version og makepkg)
# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
#
# Distributed under GPL-2
#
# Depends on: busybox utilities, fakeroot, 
#

Natanael Copa's avatar
Natanael Copa committed
11
abuild_ver=1.10
Natanael Copa's avatar
Natanael Copa committed
12 13 14 15 16

startdir="$PWD"
srcdir=${srcdir:-"$startdir/src"}
pkgdir=${pkgdir:-"$startdir/pkg"}
pkgrel=0
Natanael Copa's avatar
Natanael Copa committed
17 18
repo=${startdir%/*}
repo=${repo##*/}
Natanael Copa's avatar
Natanael Copa committed
19 20 21 22

# defaults
SRCDEST=${SRCDEST:-$startdir}
PKGDEST=${PKGDEST:-$startdir}
23
BUILD_BASE="binutils gcc make patch uclibc-dev"
Natanael Copa's avatar
Natanael Copa committed
24

25 26
SUDO=${SUDO:-"sudo"}

27
default_cmds="sanitycheck builddeps clean fetch unpack rootpkg"
Natanael Copa's avatar
Natanael Copa committed
28

Natanael Copa's avatar
Natanael Copa committed
29 30 31 32
# read config
ABUILD_CONF=${ABUILD_CONF:-"/etc/abuild.conf"}
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"

33
# source functions
34 35
datadir=/usr/share/abuild

36 37 38
# if abuild was not run from PATH, then look for func lib at same location
if [ -z "$FUNCLIB" ]; then
	FUNCLIB="${0##/*}/functions.sh"
39
	[ -f "$FUNCLIB"	] || FUNCLIB=$datadir/functions.sh
40 41 42 43 44 45 46 47
fi

if ! [ -f "$FUNCLIB" ]; then
	echo "$FUNCLIB: not found" >&2
	exit 1
fi
. "$FUNCLIB"
	
Linux User's avatar
Linux User committed
48 49
set_xterm_title() {
	if [ "$TERM" = xterm ]; then
50
		 printf "\033]0;$1\007" >&2
Linux User's avatar
Linux User committed
51 52 53 54 55
	fi
} 

cleanup() {
	set_xterm_title ""
56
	if [ -z "$install_after" ] && [ -n "$uninstall_after" ]; then
57
		$SUDO apk del $uninstall_after
58
	fi
Linux User's avatar
Linux User committed
59 60
}

Natanael Copa's avatar
Natanael Copa committed
61
die() {
Linux User's avatar
Linux User committed
62
	error "$@"
Linux User's avatar
Linux User committed
63
	cleanup
Natanael Copa's avatar
Natanael Copa committed
64 65 66
	exit 1
}

67 68
# check if apkbuild is basicly sane
sanitycheck() {
Natanael Copa's avatar
Natanael Copa committed
69
	local i
70
	msg "Checking sanity of $APKBUILD..."
71 72 73
	[ -z "$pkgname" ] && die "Missing pkgname in APKBUILD"
	[ -z "${pkgname##* *}" ] && die "pkgname contains spaces"
	[ -z "$pkgver" ] && die "Missing pkgver in APKBUILD"
Natanael Copa's avatar
Natanael Copa committed
74
	[  "${pkgver##[0-9]}" == "$pkgver" ] && \
75 76 77 78 79 80
		die "pkgver does not start with a digit"
	[ -z "$pkgrel" ] && warning "Missing pkgrel in APKBUILD. Using pkgrel=0"
	[ -z "$pkgdesc" ] && die "Missing pkgdesc in APKBUILD"
	[ -z "$url" ] && die "Missing url in APKBUILD"
	[ -z "$license" ] && die "Missing license in APKBULID"

81 82 83 84 85
	if [ -n "$source" ]; then
		for i in $source; do
			md5sums_has ${i##*/} || die "${i##*/} is missing in md5sums"
		done
	fi
Natanael Copa's avatar
Natanael Copa committed
86

87 88 89 90 91
	if [ -n "$md5sums" ]; then
		for i in $(echo "$md5sums" | awk '{ print $2 }'); do
			source_has $i || die "$i is missing in source"
		done
	fi
92

93 94 95
	# common spelling errors
	[ -n "$depend" ] && die "APKBUILD contains 'depend'. It should be depends"
	[ -n "$makedepend" ] && die "APKBUILD contains 'makedepend'. It should be makedepends"
Natanael Copa's avatar
Natanael Copa committed
96 97

	grep '^# Maintainer:' $APKBUILD >/dev/null || warning "No maintainer"
98 99 100 101
	return 0
}

md5check() {
Natanael Copa's avatar
Natanael Copa committed
102
	local dummy f
103 104 105
	if [ -z "$source" ]; then
		return 0
	fi
106
	if [ -z "$md5sums" ]; then
107
		die "Use 'abuild checksum' to generate/update the checksum(s)"
108
	fi
109 110 111
	if [ "$(echo $source | wc -l)" -ne "$(echo $md5sums | wc -l)" ]; then
		die "Number of md5sums does not correspond to number of sources"
	fi
112
	fetch || return 1
113
	msg "Checking md5sums..."
114
	cd "$srcdir" && echo "$md5sums" | md5sum -c 
Natanael Copa's avatar
Natanael Copa committed
115 116 117 118 119
}

uri_fetch() {
	local uri="$1"
	local d="${s##*/}"	# $(basename $s)
120 121 122 123
	local opts
	[ -n "$quiet" ] && opts="-q"
	[ -f "$SRCDEST/$d" ] && return 0

Natanael Copa's avatar
Natanael Copa committed
124
	mkdir -p "$SRCDEST"
125 126 127
	if [ -f "$SRCDEST/$d.part" ]; then
		msg "Partial download found. Trying to resume"
		opts="$opts -c"
Natanael Copa's avatar
Natanael Copa committed
128
	fi
Linux User's avatar
Linux User committed
129
	msg "Fetching $uri"
130 131
	wget $opts -O "$SRCDEST/$d.part" "$uri" \
		&& mv "$SRCDEST/$d.part" "$SRCDEST/$d"
Natanael Copa's avatar
Natanael Copa committed
132 133
}

134 135 136 137 138 139 140 141
is_remote() {
	case "$1" in
		http://*|ftp://*)
			return 0;;
	esac
	return 1
}

Natanael Copa's avatar
Natanael Copa committed
142 143 144
fetch() {
	local s
	mkdir -p "$srcdir"
145 146 147 148 149 150 151
	for s in $source; do
		if is_remote "$s"; then
			uri_fetch "$s" || return 1
			ln -sf "$SRCDEST/${s##*/}" "$srcdir"/
		else		
			ln -sf "$startdir/$s" "$srcdir/"
		fi
Natanael Copa's avatar
Natanael Copa committed
152 153 154 155 156 157
	done
}

# unpack the sources
unpack() {
	local u
158
	md5check || return 1
Natanael Copa's avatar
Natanael Copa committed
159 160 161 162
	mkdir -p "$srcdir"
	for u in $source; do
		local s="$SRCDEST/${u##*/}"	# $(basename $s)
		case "$s" in
Natanael Copa's avatar
Natanael Copa committed
163
			*.tar.gz|*.tgz)
164
				msg "Unpacking $s..."
Natanael Copa's avatar
Natanael Copa committed
165 166
				tar -C "$srcdir" -zxf "$s" || return 1;;
			*.tar.bz2)
167
				msg "Unpacking $s..."
Natanael Copa's avatar
Natanael Copa committed
168
				tar -C "$srcdir" -jxf "$s" || return 1;;
169 170 171 172
			*.tar.lzma)
				msg "Unpacking $s..."
				unlzma -c "$s" | tar -C "$srcdir" -x  \
					|| return 1;;
Natanael Copa's avatar
Natanael Copa committed
173 174 175
			*.zip)
				msg "Unpacking $s..."
				unzip "$s" -d "$srcdir" || return 1;;
Natanael Copa's avatar
Natanael Copa committed
176 177 178 179 180 181
		esac
	done
}

# cleanup source and package dir
clean() {
182
	msg "Cleaning temporary build dirs..."
Natanael Copa's avatar
Natanael Copa committed
183 184 185
	rm -rf "$srcdir"
	rm -rf "$pkgdir"
	local i
186 187
	for i in $subpackages; do
		rm -rf "$pkgdir-$(get_split_func $i)"
Natanael Copa's avatar
Natanael Copa committed
188 189 190 191 192 193 194
	done
}

# cleanup fetched sources
cleancache() {
	local s
	for s in $source; do
195 196 197 198
		if is_remote "$s"; then
			msg "Cleaning downloaded ${s##*/}..."
			rm -f "$SRCDEST/${s##*/}"
		fi
Natanael Copa's avatar
Natanael Copa committed
199 200 201 202 203
	done
}

cleanpkg() {
	local i
204
	msg "Cleaning built packages..."
205
	for i in $pkgname $subpackages; do
206
		local p="$i-$pkgver-r$pkgrel"
207
		rm -f "$PKGDEST/$p.apk" "$PKGDEST/$p.src.tar.gz"
Natanael Copa's avatar
Natanael Copa committed
208 209 210
	done
}

211 212 213 214 215 216 217 218 219 220 221 222 223
# clean all packages except current
cleanoldpkg() {
	local i j
	msg "Cleaning all packages except $pkgver-r$pkgrel..."
	for i in $pkgname $subpackages; do
		for j in "$PKGDEST"/${i%:*}-[0-9]*.apk; do
			[ "$j" != "$PKGDEST/${i%:*}-$pkgver-r$pkgrel.apk" ] \
				&& rm -f "$j"
		done
	done
	return 0
}
	
Natanael Copa's avatar
Natanael Copa committed
224 225
runpart() {
	local part=$1
226
	[ -n "$DEBUG" ] && msg "$part"
Natanael Copa's avatar
Natanael Copa committed
227 228 229 230 231 232 233 234
	$part || die "$part failed"
}

# override those in your build script
build() {
	die "No build() function found in $APKBUILD"
}

235 236 237 238 239 240 241 242 243
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
}

Natanael Copa's avatar
Natanael Copa committed
244
subpkg() {
245
	if [ -z "$subpackages" ]; then
246 247
		return 0
	fi
Natanael Copa's avatar
Natanael Copa committed
248 249
	local i
	cd "$startdir"
250
	for i in $subpackages; do
251 252
		local func=$(get_split_func $i)
		# call abuild recursively, setting subpkg{dir,name}
253
		msg "Running split function $func..."
254
		subpkgdir="$startdir/pkg-$func" subpkgname="${i%:*}" \
255
			$0 $func package || return 1
Natanael Copa's avatar
Natanael Copa committed
256 257 258 259
	done
}

package_apk() {
260 261
	local name=${subpkgname:-$pkgname}
	[ -z "${name##* *}" ] && die "package name contains spaces"
262
	local dir=${subpkgdir:-$pkgdir}
263
	local pkg="$name-$pkgver-r$pkgrel.apk"
264
	local sub
Natanael Copa's avatar
Natanael Copa committed
265 266 267
	
	[ ! -d "$dir" ] && die "Missing $dir"
	cd "$dir"
268
	msg "Creating ${subpkgname:+sub}package $pkg..."
Natanael Copa's avatar
Natanael Copa committed
269 270 271
	local builddate=$(date -u "+%s")
	local size=$(du -sk | awk '{print $1 * 1024}')

272
	echo "# Generated by $(basename $0) $abuild_ver" >.PKGINFO
Natanael Copa's avatar
Natanael Copa committed
273 274 275 276 277
	if [ -n "$FAKEROOTKEY" ]; then
		echo "# using $(fakeroot -v)" >> .PKGINFO
	fi
	echo "# $(date -u)" >> .PKGINFO
	cat >> .PKGINFO <<EOF
278
pkgname = $name
279
pkgver = $pkgver-r$pkgrel
Natanael Copa's avatar
Natanael Copa committed
280 281 282 283 284 285
pkgdesc = $pkgdesc
url = $url
builddate = $builddate
packager = ${PACKAGER:-"Unknown"}
size = $size
EOF
286 287
	local i deps
	deps="$depends"
288
	if [ -n "$install" ] && head -n 1 "$srcdir/$install" | grep '^#' >/dev/null && ! depends_has busybox && [ "$pkgname" != "busybox" ]; then
289 290 291 292
		msg "Adding busybox to depends since we have an install script"
		deps="$deps busybox"
	fi
	
Natanael Copa's avatar
Natanael Copa committed
293 294 295 296 297 298
	for i in $license; do
		echo "license = $i" >>.PKGINFO
	done
	for i in $replaces; do
		echo "replaces = $i" >>.PKGINFO
	done
299
	for i in $deps; do
Natanael Copa's avatar
Natanael Copa committed
300 301 302 303 304 305 306 307 308 309 310 311 312
		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
	for i in $backup; do
		echo "backup = $i" >>.PKGINFO
	done

	local metafiles=".PKGINFO"
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
	for i in $install; do
		script=${i#$name}
		case "$script" in
			.install)
				warning "Deprecated .install script found."
				script=.INSTALL
				;;
			.pre-install|.post-install|.pre-upgrade|.post-upgrade|.pre-deinstall|.post-deinstall)
				msg "Adding $script"
				;;
			*) 	error "$script: Invalid install script"
				return 1
				;;
		esac
		cp "$srcdir/$i" "$dir/$script" || return 1
		chmod +x "$dir/$script"
		metafiles="$metafiles $script"
	done
Natanael Copa's avatar
Natanael Copa committed
331 332 333 334
	
	set *
	[ "$1" = '*' ] && set --
	( cd "$dir" && tar -zcf "$PKGDEST/$pkg" $metafiles $@ )
Natanael Copa's avatar
Natanael Copa committed
335 336 337
}

package() {
338
	options_has "!strip" ||	stripbin
Natanael Copa's avatar
Natanael Copa committed
339 340 341
	package_apk
}

342
# predefined splitfunc doc
343
default_doc() {
344
	depends="$depends_doc"
345
	install="$install_doc"
Natanael Copa's avatar
Natanael Copa committed
346
	local i
347
	for i in doc man info html sgml licenses; do
348 349 350
		if [ -d "$pkgdir/usr/share/$i" ]; then
			mkdir -p "$subpkgdir/usr/share"
			mv "$pkgdir/usr/share/$i" "$subpkgdir/usr/share/"
Natanael Copa's avatar
Natanael Copa committed
351 352
		fi
	done
353 354 355
	
	rm -f "$subpkgdir/usr/share/info/dir"

356 357 358
#	# compress info and man pages
#	find "$subpkgdir/usr/share" \( -name '*.info' -o -name '*.info-[1-9]' \
#		-o -name '*.[1-9]' \) -exec gzip {} \;
359 360 361 362

	# remove if empty, ignore error (not empty)
	rmdir "$pkgdir/usr/share" "$pkgdir/usr" 2>/dev/null

Natanael Copa's avatar
Natanael Copa committed
363
#	[ -d "$subpkgdir/usr/share/man" ] && depends="man"
Natanael Copa's avatar
Natanael Copa committed
364 365 366
	return 0
}

367 368 369 370
doc() {
	default_doc
}

371
# predefined splitfunc mod
372
default_mod() {
373
	depends="$kernel $depends_mod"
374
	install="$install_mod"
Natanael Copa's avatar
Natanael Copa committed
375
	for i in firmware modules; do
376 377 378
		if [ -d "$pkgdir/lib/$i" ]; then
			rm -rf "$subpkgdir/lib"
			mkdir -p "$subpkgdir/lib"
379
			mv "$pkgdir/lib/$i" "$subpkgdir/lib"
Natanael Copa's avatar
Natanael Copa committed
380 381 382 383
		fi
	done
}

384 385 386 387
mod() {
	default_mod
}

388
# predefined splitfunc dev
389
default_dev() {
390
	depends="$pkgname $depends_dev"
391
	install="$install_dev"
392
	cd "$pkgdir" || return 0
393 394 395 396 397
	for i in usr/include usr/lib/pkgconfig usr/share/aclocal\
			usr/share/gettext usr/bin/*-config	\
			$(find -name include -type d) 		\
			$(find usr/ -name '*.[acho]' -o -name '*.la' \
			2>/dev/null); do
398 399
		if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
			d="$subpkgdir/${i%/*}"	# dirname $i
Natanael Copa's avatar
Natanael Copa committed
400
			mkdir -p "$d"
401
			mv "$pkgdir/$i" "$d"
402
			rmdir "$pkgdir/${i%/*}" 2>/dev/null
Natanael Copa's avatar
Natanael Copa committed
403 404
		fi
	done
Natanael Copa's avatar
Natanael Copa committed
405
	return 0
Natanael Copa's avatar
Natanael Copa committed
406 407
}

408 409 410 411
dev() {
	default_dev
}

Natanael Copa's avatar
Natanael Copa committed
412 413
# build and package in fakeroot
rootpkg() {
Natanael Copa's avatar
Natanael Copa committed
414
	cd "$startdir"
415
	msg "Entering fakeroot..."
Natanael Copa's avatar
Natanael Copa committed
416 417 418 419
	fakeroot $0 build subpkg package
}

srcpkg() {
420
	local p="$pkgname-$pkgver-$pkgrel"
Natanael Copa's avatar
Natanael Copa committed
421
	local prefix="${startdir##*/}"
Natanael Copa's avatar
Natanael Copa committed
422 423 424 425 426
	local i files="$prefix/APKBUILD"
	for i in $source; do
		files="$files $prefix/${i##*/}"
	done
	mkdir -p "$PKGDEST"
427
	msg "Creating source package $p.src.tar.gz..."
428
	(cd .. && tar -zcf "$PKGDEST/$p.src.tar.gz" $files) 
Natanael Copa's avatar
Natanael Copa committed
429 430
}

431 432
# check if package is up to date
up2date() {
433
	local pkg="$PKGDEST/$pkgname-$pkgver-r$pkgrel.apk"
434
	local i s
Natanael Copa's avatar
Natanael Copa committed
435
	cd "$startdir"
436 437 438 439 440
	for i in $pkgname $subpackages; do
		[ -f "$PKGDEST/$pkgname-$pkgver-r$pkgrel.apk" ] || return 1
	done
	[ -n "$keep" ] && return 0

441
	for i in $source APKBUILD; do
442 443 444 445 446 447
		local s
		if is_remote "$i"; then
			s="$SRCDEST/${i##*/}"	# $(basename $i)
		else
			s="$startdir/${i##*/}"
		fi
448 449 450 451 452 453 454
		if [ "$s" -nt "$pkg" ]; then
			return 1
		fi
	done
	return 0
}

455 456 457 458 459 460 461 462 463 464 465 466 467
# 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=
468
		. $i
469
		dir=${i%/APKBUILD}
470
		for j in $pkgname $subpackages; do
471 472 473 474 475 476 477 478 479
			echo "o ${j%%:*} $dir"
			set -- $depends $makedepends
			echo -n "d ${j%%:*} $1"
			shift
			while [ $# -gt 0 ]; do
				echo -n ",$1"
				shift
			done
			echo
480 481
		done
	done
482
	)
483 484
}

485
deptrace() {
486 487
	local deps="$@"
	[ -z "$deps" ] && deps="$BUILD_BASE $depends $makedepends"
488 489 490
	( 	depparse_aports 
		if [ -z "$upgrade" ]; then
			# list installed pkgs and prefix with 'i '
Natanael Copa's avatar
Natanael Copa committed
491
			apk info -q | sort |  sed 's/^/i /'
492
		fi
493
	) | awk -v pkgs="$deps" '
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518

	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() {
519
	local deps alldeps pkg i dir ver missing
520
	msg "Building dependencies..."
521 522 523 524 525 526 527 528
	deps="$BUILD_BASE $makedepends"

	# add depends unless it is a subpackage
	for i in $depends; do
		subpackages_has $i || deps="$deps $i"
	done

	# find which deps are missing
529 530 531 532 533 534 535 536 537 538 539 540 541
	for i in $deps; do
		if ! apk info -e $i; then
			if [ -z "$install_deps" ] && [ -z "$recursive" ]; then
				die "Missing dependency $i. Use -r to autoinstall or -R to build"
			fi
			missing="$missing $i"
		fi
	done

	[ -z "$missing" ] && return 0

	if [ -n "$install_deps" ] &&  $SUDO apk add $missing; then
		uninstall_after="$missing $uninstall_after"
542 543
		return 0
	fi
544 545 546 547
	
	[ -z "$recursive" ] && return 1
	
	for i in $(deptrace $missing); do
548 549 550 551 552
		# i = pkg:dir
		local dir=${i#*:}
		local pkg=${i%:*}
		msg "Entering $dir"
		cd "$dir" || return 1
553
		$0 -k -i $pkg || return 1
554
		uninstall_after="$pkg $uninstall_after"
555 556 557
	done
}

558
# replace the md5sums in the APKBUILD
Natanael Copa's avatar
Natanael Copa committed
559 560
checksum() {
	local s files
561
	[ -z "$source" ] && return 0
Natanael Copa's avatar
Natanael Copa committed
562
	fetch
563
	msg "Updating the md5sums in APKBUILD..."
Natanael Copa's avatar
Natanael Copa committed
564 565 566 567
	for s in $source; do
		files="$files ${s##*/}"
	done
	md5sums="$(cd "$srcdir" && md5sum $files)" || die "md5sum failed"
568 569
	sed -i -e '/^md5sums="/,/"\$/d; /^md5sums=''/,/''\$/d' "$APKBUILD"
	echo "md5sums=\"$md5sums\"" >>"$APKBUILD"
Natanael Copa's avatar
Natanael Copa committed
570 571
}

572
stripbin() {
573
	local bin
574 575
	cd "${subpkgdir:-$pkgdir}" || return 1
	msg "Stripping binaries"
576
	find . -type f 2>/dev/null | while read bin; do
577 578 579 580 581 582 583 584 585 586 587
		local opt=
		case "$(file -biz "$bin")" in
			*/x-sharedlib*|*/x-archive*)
				strip --strip-debug "$bin";;
			*/x-executable*)
				strip "$bin";;
		esac
	done
	return 0
}

588 589 590 591 592 593 594 595
# simply list target apks
listpkg() {
	local i 
	for i in $pkgname $subpackages; do
		echo "${i%:*}-$pkgver-r$pkgrel.apk"
	done
}

Natanael Copa's avatar
Natanael Copa committed
596 597 598 599 600 601 602 603
source_has() {
	local i
	for i in $source; do
		[ "$1" = "${i##*/}" ] && return 0
	done
	return 1
}

Natanael Copa's avatar
Natanael Copa committed
604 605 606 607 608 609 610 611
subpackages_has() {
	local i
	for i in $subpackages; do
		[ "$1" = "${i%:*}" ] && return 0
	done
	return 1
}

612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
list_has() {
	local needle="$1"
	local i
	shift
	for i in $@; do
		[ "$needle" = "$i" ] && return 0
		[ "$needle" = "!$i" ] && return 1
	done
	return 1
}

options_has() {
	list_has "$1" $options
}

627 628 629 630
depends_has() {
	list_has "$1" $depends
}

Natanael Copa's avatar
Natanael Copa committed
631 632 633 634
md5sums_has() {
	list_has "$1" $md5sums
}

Natanael Copa's avatar
Natanael Copa committed
635 636 637 638 639 640 641 642 643 644 645 646 647 648
# install package after build
post_add() {
	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
649
	$SUDO apk add -u "$pkgf" || die "Failed to install $1"
Natanael Copa's avatar
Natanael Copa committed
650 651
}

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
# create new aport from templates
newaport() {
	local pn=${newname%-[0-9]*}
	local pv
	if [ "$pn" != "$newname" ]; then
		pv=${newname#$pn-}
	fi
	if [ -e "$pn"/APKBUILD ]; then
		error "$pn/APKBUILD already exist"
		return 1
	fi
	mkdir -p "$pn"
	cd "$pn"
	sed 	-e '1,/^\#*$/d' \
		-e "s/^\(# Contributor: \).*/\1$PACKAGER/" \
		-e "s/^\(# Maintainer: \).*/\1$PACKAGER/" \
		-e "s/^pkgname=.*/pkgname=$pn/" \
		-e "s/^pkgver=.*/pkgver=$pv/" \
		"$datadir"/sample.APKBUILD > APKBUILD || return 1
	#-e '1,/^\#$/d' \
	if [ -n "$cpinitd" ]; then
		cp "$datadir"/sample.initd $pn.initd
		cp "$datadir"/sample.confd $pn.confd
		cp "$datadir"/sample.install $pn.install
		sed -i -e "s/^install=.*/install=\"$pn.install\"/" \
			-e "s/^source=\"\(.*\)\"/source=\"\1\n\t$pn.initd\n\t$pn.confd\n\t\$install\n\t\"/" \
			APKBUILD
		
	fi
}
	
Natanael Copa's avatar
Natanael Copa committed
683
usage() {
684
	echo "$(basename $0) $abuild_ver"
685 686
	echo "usage: ${0##*/} [options] [-i PKG] [-P REPODEST] [-p PKGDEST]"
	echo "              [-s SRCDEST] [cmd] ..."
687
	echo "       ${0##*/} [-c] -n PKGNAME[-PKGVER]"
Natanael Copa's avatar
Natanael Copa committed
688 689
	echo "Options:"
	echo " -f  Force specified cmd, even if they are already done"
690 691
	echo " -h  Show this help"
	echo " -i  Install PKG after successul build"
692
	echo " -k  Keep built packages, even if APKBUILD or sources are newer"
693
	echo " -p  Set package destination directory"
694
	echo " -P  Set PKGDEST to REPODEST/<repo>, where repo is the parents dir name" 
Natanael Copa's avatar
Natanael Copa committed
695
	echo " -q  Quiet"
696 697
	echo " -r  Install missing dependencies from system repository (using sudo)"
	echo " -R  Recursively build and install missing dependencies (using sudo)"
698
	echo " -s  Set source package destination directory"
699
	echo " -u  Recursively build and upgrade all dependencies (using sudo)"
Natanael Copa's avatar
Natanael Copa committed
700
	echo ""
701 702 703
	echo " -n  Create a new APKBUILD in a directory named PKGNAME"
	echo " -c  Copy a sample init.d, conf.d and install script to new directory"
	echo ""
Natanael Copa's avatar
Natanael Copa committed
704
	echo "Commands:"
705
	echo "  checksum    Generate checksum to be included in APKBUILD"
706 707 708 709 710
	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"
711
	echo "  listpkg     List target packages"
712 713 714
	echo "  package     Create package in \$PKGDEST"
	echo "  rootpkg     Run '$0 build package' as fakeroot"
	echo "  clean       Remove temp build and install dirs"
715
	echo "  cleanoldpkg Remove binary packages except current version"
716 717 718 719
	echo "  cleanpkg    Remove already built binary and source package"
	echo "  cleancache  Remove downloaded files from \$SRCDEST"
	echo "  srcpkg      Make a source package"
	echo "  up2date     Compare target and sources dates"
Natanael Copa's avatar
Natanael Copa committed
720 721 722 723 724
	echo ""
	exit 0
}

APKBUILD="${APKBUILD:-./APKBUILD}"
725 726
unset force
unset recursive
727
while getopts "cfhi:kin:p:P:qrRs:u" opt; do
Natanael Copa's avatar
Natanael Copa committed
728
	case $opt in
729
		'c') cpinitd=1;;
Natanael Copa's avatar
Natanael Copa committed
730
		'f') force=1;;
731 732
		'h') usage;;
		'i') install_after="$install_after $OPTARG";;
733
		'k') keep=1;;
734
		'n') newname=$OPTARG;;
735
		'p') PKGDEST=$OPTARG;;
736
		'P') REPODEST=$OPTARG;;
Natanael Copa's avatar
Natanael Copa committed
737
		'q') quiet=1;;
738 739
		'r') install_deps=1;;
		'R') recursive=1;;
740
		's') SRCDEST=$OPTARG;;
741 742
		'u') upgrade=1
		     recursive=1;;
Natanael Copa's avatar
Natanael Copa committed
743 744 745 746
	esac
done
shift $(( $OPTIND - 1 ))

747 748 749 750 751
# If REPODEST is set then it will override the PKGDEST
if [ -n "$REPODEST" ]; then
	PKGDEST="$REPODEST/$repo"
fi

752
# source the buildfile
753 754 755 756
if [ -z "$newname" ]; then
	[ -f "$APKBUILD" ] || die "Could not find $APKBUILD (PWD=$PWD)"
	. "$APKBUILD"
fi
757

758
# If we are handling a sub package then reset subpackages
759 760 761
if [ -n "$subpkgname" ]; then
	subpackages=
fi
Natanael Copa's avatar
Natanael Copa committed
762 763

trap 'die "Aborted by user"' INT
Linux User's avatar
Linux User committed
764
set_xterm_title "abuild: $pkgname"
Natanael Copa's avatar
Natanael Copa committed
765

766 767 768
if [ -z "$1" ] && [ -n "$newname" ]; then
	set "newaport"
fi
Natanael Copa's avatar
Natanael Copa committed
769 770

if [ -z "$1" ]; then
Natanael Copa's avatar
Natanael Copa committed
771
	if up2date && [ -z "$force" ]; then
Natanael Copa's avatar
Natanael Copa committed
772
		msg "Package is up to date"
773 774 775
	else
		set $default_cmds
	fi
Natanael Copa's avatar
Natanael Copa committed
776 777 778 779 780 781
fi

while [ $# -gt 0 ]; do
	runpart $1
	shift
done
782 783

for i in $install_after; do
Natanael Copa's avatar
Natanael Copa committed
784
	post_add $i
785 786
done

Linux User's avatar
Linux User committed
787
cleanup
Natanael Copa's avatar
Natanael Copa committed
788