abuild 8.93 KB
Newer Older
Natanael Copa's avatar
Natanael Copa committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/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, 
#

myver=0.2

# read config
MAKEAPK_CONF=${MAKEAPK_CONF:-/etc/abuild.conf}
[ -f "$MAKEAPK_CONF" ] && . "$MAKEAPK_CONF"

startdir="$PWD"
srcdir=${srcdir:-"$startdir/src"}
pkgdir=${pkgdir:-"$startdir/pkg"}
pkgrel=0

# defaults
SRCDEST=${SRCDEST:-$startdir}
PKGDEST=${PKGDEST:-$startdir}

Natanael Copa's avatar
Natanael Copa committed
26
default_cmds="sanitycheck makedepcheck clean fetch md5check unpack rootpkg"
Natanael Copa's avatar
Natanael Copa committed
27
28
29
all_cmds="checksum fetch unpack rootpkg build package cleancache clean srcpkg"

# functions
Natanael Copa's avatar
Natanael Copa committed
30
msg() {
Natanael Copa's avatar
Natanael Copa committed
31
32
	local sub=
	[ -n "$INSUB" ] && sub="(sub)"
Natanael Copa's avatar
Natanael Copa committed
33
	[ -z "$quiet" ] && echo ">>> $pkgname $sub:" "$@" >&2
Natanael Copa's avatar
Natanael Copa committed
34
35
36
37
38
39
40
41
}

warning() {
	echo ">>> Warning:" "$@" >&2
}

die() {
	quiet=
Natanael Copa's avatar
Natanael Copa committed
42
	msg "$@" >&2
Natanael Copa's avatar
Natanael Copa committed
43
44
45
	exit 1
}

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# check if apkbuild is basicly sane
sanitycheck() {
	[ -z "$pkgname" ] && die "Missing pkgname in APKBUILD"
	[ -z "${pkgname##* *}" ] && die "pkgname contains spaces"
	[ -z "$pkgver" ] && die "Missing pkgver in APKBUILD"
	[  "${pkgver##[0-9]}" != "$pkgver" ] && \
		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"

	# common spelling errors
	[ -n "$depend" ] && die "APKBUILD contains 'depend'. It should be depends"
	[ -n "$makedepend" ] && die "APKBUILD contains 'makedepend'. It should be makedepends"

	return 0
}

Natanael Copa's avatar
Natanael Copa committed
65
# check if we have needed packages to build this thing
66
makedepcheck() {
Natanael Copa's avatar
Natanael Copa committed
67
68
69
70
71
72
73
74
75
76
	local i
	local missing=
	for i in $makedepends; do
		apk_info -e $i || missing="$missing $i"
	done
	[ -z "$missing" ] && return 0
	warning "Missing makedepends: $missing"
	return 1
}

77
md5check() {
78
79
80
	if [ -z "$source" ]; then
		return 0
	fi
81
82
83
	if [ -z "$md5sums" ]; then
		die "Use 'abuild checksum >>$APKBUILD' to generate a checksum"
	fi
84
85
86
87

	if [ "$(echo $source | wc -l)" -ne "$(echo $md5sums | wc -l)" ]; then
		die "Number of md5sums does not correspond to number of sources"
	fi
88
	cd "$srcdir" && echo "$md5sums" | md5sum -c 
Natanael Copa's avatar
Natanael Copa committed
89
90
91
92
93
}

uri_fetch() {
	local uri="$1"
	local d="${s##*/}"	# $(basename $s)
94
95
96
97
	local opts
	[ -n "$quiet" ] && opts="-q"
	[ -f "$SRCDEST/$d" ] && return 0

Natanael Copa's avatar
Natanael Copa committed
98
	mkdir -p "$SRCDEST"
99
100
101
	if [ -f "$SRCDEST/$d.part" ]; then
		msg "Partial download found. Trying to resume"
		opts="$opts -c"
Natanael Copa's avatar
Natanael Copa committed
102
	fi
103
104
	wget $opts -O "$SRCDEST/$d.part" "$uri" \
		&& mv "$SRCDEST/$d.part" "$SRCDEST/$d"
Natanael Copa's avatar
Natanael Copa committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
}

fetch() {
	local s
	mkdir -p "$srcdir"
	for s in $source; do 
		case "$s" in
			http://*|ftp://*)
				uri_fetch "$s" || return 1
				;;
		esac
		ln -sf "$SRCDEST/${s##*/}" "$srcdir"/
	done
}

# unpack the sources
unpack() {
	local u
	mkdir -p "$srcdir"
	for u in $source; do
		local s="$SRCDEST/${u##*/}"	# $(basename $s)
		case "$s" in
Natanael Copa's avatar
Natanael Copa committed
127
			*.tar.gz|*.tgz)
Natanael Copa's avatar
Natanael Copa committed
128
129
130
131
132
133
134
135
136
137
138
139
140
				tar -C "$srcdir" -zxf "$s" || return 1;;
			*.tar.bz2)
				tar -C "$srcdir" -jxf "$s" || return 1;;
		esac
	done
}

# cleanup source and package dir
clean() {
	rm -rf "$srcdir"
	rm -rf "$pkgdir"
	local i
	for i in $subpackages; do
141
		rm -rf "$pkgdir-$i"
Natanael Copa's avatar
Natanael Copa committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
	done
}

# cleanup fetched sources
cleancache() {
	local s
	for s in $source; do
		case "$s" in
			http:/*|ftp:/*)
				rm -f "$SRCDIR/$(basename $s)";;
		esac
	done
}

cleanpkg() {
	local p=$pkgname-$pkgver
	[ $pkgrel -ne 0 ] && p="$p-r$pkgrel"
	rm -f "$PKGDEST/$p.apk" "$PKGDEST/$p.src.tar.gz"
	local i
	for i in $subpackages; do
162
		INSUB=1 subpkgdir="$pkgdir-$i" $0 $i cleanpkg
Natanael Copa's avatar
Natanael Copa committed
163
164
165
166
167
	done
}

runpart() {
	local part=$1
Natanael Copa's avatar
Natanael Copa committed
168
	msg "$part"
Natanael Copa's avatar
Natanael Copa committed
169
170
171
172
173
174
175
176
177
178
179
180
181
	$part || die "$part failed"
}

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

subpkg() {
	[ -z "$subpackages" ] && return 0
	local i
	cd "$startdir"
	for i in $subpackages; do
182
		INSUB=1 subpkgdir="$pkgdir-$i" $0 $i package || return 1
Natanael Copa's avatar
Natanael Copa committed
183
184
185
186
	done
}

package_apk() {
187
	[ -z "${pkgname##* *}" ] && die "pkgname contains spaces"
188
	local dir=${subpkgdir:-$pkgdir}
Natanael Copa's avatar
Natanael Copa committed
189
190
191
	local p="$pkgname-$pkgver"
	[ "$pkgrel" -ne 0 ] && p="$p-r$pkgrel"
	local pkg="$p.apk"
Natanael Copa's avatar
Natanael Copa committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#	local db="$dir/var/db/apk/$p"
#	mkdir -p "$db"
#	echo "$arch" > "$db/ARCH"
#	echo "$pkgdesc" > "$db/DESC"
#	echo "$license" > "$db/LICENSE"
#	echo "$depends" > "$db/DEPEND"
#	echo "$url" > "$db/WWW"
	
	[ ! -d "$dir" ] && die "Missing $dir"
	cd "$dir"
	msg "Creating $pkg"
	local builddate=$(date -u "+%s")
	local size=$(du -sk | awk '{print $1 * 1024}')

	echo "# Generated by $(basename $0) $myver" >.PKGINFO
	if [ -n "$FAKEROOTKEY" ]; then
		echo "# using $(fakeroot -v)" >> .PKGINFO
	fi
	echo "# $(date -u)" >> .PKGINFO
	cat >> .PKGINFO <<EOF
pkgname = $pkgname
213
pkgver = $pkgver-$pkgrel
Natanael Copa's avatar
Natanael Copa committed
214
215
216
217
218
219
pkgdesc = $pkgdesc
url = $url
builddate = $builddate
packager = ${PACKAGER:-"Unknown"}
size = $size
EOF
Natanael Copa's avatar
Natanael Copa committed
220
	local i
Natanael Copa's avatar
Natanael Copa committed
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

	for i in $license; do
		echo "license = $i" >>.PKGINFO
	done
	for i in $replaces; do
		echo "replaces = $i" >>.PKGINFO
	done
	for i in $depends; 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
	for i in $backup; do
		echo "backup = $i" >>.PKGINFO
	done

	local metafiles=".PKGINFO"
Natanael Copa's avatar
Natanael Copa committed
242
243
244
	if [ -n "$install" ]; then
		cp "$srcdir/$install" "$dir/.INSTALL" || return 1
		chmod +x "$dir/.INSTALL"
Natanael Copa's avatar
Natanael Copa committed
245
		metafiles="$metafiles .INSTALL"
Natanael Copa's avatar
Natanael Copa committed
246
	fi
Natanael Copa's avatar
Natanael Copa committed
247
248
249
250
251
252
253
254

#	for i in pre-install post-install pre-deinstall post-deinstall; do
#		[ -f ../$i ] && cp ../$i "$db"/
#	done
	
	set *
	[ "$1" = '*' ] && set --
	( cd "$dir" && tar -zcf "$PKGDEST/$pkg" $metafiles $@ )
Natanael Copa's avatar
Natanael Copa committed
255
256
257
258
259
260
261
262
263
264
265
266
}

package() {
	package_apk
}

# predefined subpackage doc
doc() {
	pkgname="$pkgname-doc"
	depends=""
	local i
	for i in doc man info html sgml; do
267
268
269
		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
270
271
		fi
	done
272
273
274
275

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

276
	[ -d "$subpkgdir/usr/share/man" ] && depends="man"
Natanael Copa's avatar
Natanael Copa committed
277
278
279
280
281
282
283
284
	return 0
}

# predefined subpackage mod
mod() {
	pkgname="$pkgname-mod"
	depends="$kernel"
	for i in firmware modules; do
285
286
287
		if [ -d "$pkgdir/lib/$i" ]; then
			rm -rf "$subpkgdir/lib"
			mkdir -p "$subpkgdir/lib"
288
			mv "$pkgdir/lib/$i" "$subpkgdir/lib"
Natanael Copa's avatar
Natanael Copa committed
289
290
291
292
293
294
		fi
	done
}

# predefined subpackage dev
dev() {
295
	depends="$pkgname"
Natanael Copa's avatar
Natanael Copa committed
296
	pkgname="$pkgname-dev"
297
	for i in $(cd "$pkgdir" && find usr/lib -name '*.a' -o \
Natanael Copa's avatar
Natanael Copa committed
298
299
			-name '*.la' -o -name '*.o' 2>/dev/null) \
			usr/include usr/lib/pkgconfig usr/share/aclocal; do
300
301
		if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
			d="$subpkgdir/${i%/*}"	# dirname $i
Natanael Copa's avatar
Natanael Copa committed
302
			mkdir -p "$d"
303
			mv "$pkgdir/$i" "$d"
Natanael Copa's avatar
Natanael Copa committed
304
305
306
307
308
309
		fi
	done
}

# build and package in fakeroot
rootpkg() {
Natanael Copa's avatar
Natanael Copa committed
310
	cd "$startdir"
Natanael Copa's avatar
Natanael Copa committed
311
312
313
314
315
316
	fakeroot $0 build subpkg package
}

srcpkg() {
	local p="$pkgname-$pkgver"
	[ "$pkgrel" -ne 0 ] && p="$p-r$pkgrel"
Natanael Copa's avatar
Natanael Copa committed
317
	local prefix="${startdir##*/}"
Natanael Copa's avatar
Natanael Copa committed
318
319
320
321
322
323
324
325
	local i files="$prefix/APKBUILD"
	for i in $source; do
		files="$files $prefix/${i##*/}"
	done
	mkdir -p "$PKGDEST"
	(cd .. && tar -zcf $PKGDEST/$p.src.tar.gz $files) 
}

326
327
328
329
330
331
# check if package is up to date
up2date() {
	local p="$pkgname-$pkgver"
	[ "$pkgrel" -ne 0 ] && p="$p-r$pkgrel"
	local pkg="$PKGDEST/$p.apk"
	local i s
Natanael Copa's avatar
Natanael Copa committed
332
	cd "$startdir"
333
334
335
336
337
338
339
340
341
342
	[ -f "$pkg" ] || return 1
	for i in $source APKBUILD; do
		local s="$SRCDEST/${i##*/}"	# $(basename $i)
		if [ "$s" -nt "$pkg" ]; then
			return 1
		fi
	done
	return 0
}

Natanael Copa's avatar
Natanael Copa committed
343
344
345
346
347
348
349
350
351
usage() {
	echo "$(basename $0) $myver"
	echo "usage: $0 [options] [cmd] ..."
	echo "Options:"
	echo " -h  Show this help"
	echo " -f  Force specified cmd, even if they are already done"
	echo " -q  Quiet"
	echo ""
	echo "Commands:"
352
353
354
355
356
357
358
359
360
361
362
363
364
	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 "  package     Create package in \$PKGDEST"
	echo "  rootpkg     Run '$0 build package' as fakeroot"
	echo "  clean       Remove temp build and install dirs"
	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
365
366
367
368
369
370
371
372
373
	echo ""
	exit 0
}

checksum() {
	local s files
	for s in $source; do
		files="$files ${s##*/}"
	done
374
375
	md5sums="$(cd "$SRCDEST" && md5sum $files)" || die "md5sum failed"
	echo "md5sums=\"$md5sums\""
Natanael Copa's avatar
Natanael Copa committed
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
}

APKBUILD="${APKBUILD:-./APKBUILD}"

while getopts "hfq" opt; do
	case $opt in
		'h') usage;;
		'f') force=1;;
		'q') quiet=1;;
	esac
done
shift $(( $OPTIND - 1 ))

# source the buildfile
[ -f "$APKBUILD" ] || die "Could not find $APKBUILD (PWD=$PWD)"
. "$APKBUILD"

# If we are handling a sub package then reset subpackages
[ -n "$INSUB" ] && subpackages=

trap 'die "Aborted by user"' INT

[ -n "$forceunpack" ] && rm -f "$srcdir"/.unpack


if [ -z "$1" ]; then
Natanael Copa's avatar
Natanael Copa committed
402
	if up2date && [ -z "$force" ]; then
Natanael Copa's avatar
Natanael Copa committed
403
		msg "Package is up to date"
404
405
406
	else
		set $default_cmds
	fi
Natanael Copa's avatar
Natanael Copa committed
407
408
409
410
411
412
413
fi

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