abuild 8.59 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
	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() {
157
	local p="$pkgname-$pkgver-$pkgrel"
Natanael Copa's avatar
Natanael Copa committed
158
159
160
	rm -f "$PKGDEST/$p.apk" "$PKGDEST/$p.src.tar.gz"
	local i
	for i in $subpackages; do
161
		INSUB=1 subpkgdir="$pkgdir-$i" $0 $i cleanpkg
Natanael Copa's avatar
Natanael Copa committed
162
163
164
165
166
	done
}

runpart() {
	local part=$1
Natanael Copa's avatar
Natanael Copa committed
167
	msg "$part"
Natanael Copa's avatar
Natanael Copa committed
168
169
170
171
172
173
174
175
176
177
178
179
180
	$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
181
		INSUB=1 subpkgdir="$pkgdir-$i" $0 $i package || return 1
Natanael Copa's avatar
Natanael Copa committed
182
183
184
185
	done
}

package_apk() {
186
	[ -z "${pkgname##* *}" ] && die "pkgname contains spaces"
187
	local dir=${subpkgdir:-$pkgdir}
188
	local pkg="$pkgname-$pkgver-$pkgrel.apk"
Natanael Copa's avatar
Natanael Copa committed
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	
	[ ! -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
203
pkgver = $pkgver-$pkgrel
Natanael Copa's avatar
Natanael Copa committed
204
205
206
207
208
209
pkgdesc = $pkgdesc
url = $url
builddate = $builddate
packager = ${PACKAGER:-"Unknown"}
size = $size
EOF
Natanael Copa's avatar
Natanael Copa committed
210
	local i
Natanael Copa's avatar
Natanael Copa committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

	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
232
233
234
	if [ -n "$install" ]; then
		cp "$srcdir/$install" "$dir/.INSTALL" || return 1
		chmod +x "$dir/.INSTALL"
Natanael Copa's avatar
Natanael Copa committed
235
		metafiles="$metafiles .INSTALL"
Natanael Copa's avatar
Natanael Copa committed
236
	fi
Natanael Copa's avatar
Natanael Copa committed
237
238
239
240
241
242
243
244

#	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
245
246
247
248
249
250
251
252
253
254
255
256
}

package() {
	package_apk
}

# predefined subpackage doc
doc() {
	pkgname="$pkgname-doc"
	depends=""
	local i
	for i in doc man info html sgml; do
257
258
259
		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
260
261
		fi
	done
262
263
264
265

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

266
	[ -d "$subpkgdir/usr/share/man" ] && depends="man"
Natanael Copa's avatar
Natanael Copa committed
267
268
269
270
271
272
273
274
	return 0
}

# predefined subpackage mod
mod() {
	pkgname="$pkgname-mod"
	depends="$kernel"
	for i in firmware modules; do
275
276
277
		if [ -d "$pkgdir/lib/$i" ]; then
			rm -rf "$subpkgdir/lib"
			mkdir -p "$subpkgdir/lib"
278
			mv "$pkgdir/lib/$i" "$subpkgdir/lib"
Natanael Copa's avatar
Natanael Copa committed
279
280
281
282
283
284
		fi
	done
}

# predefined subpackage dev
dev() {
285
	depends="$pkgname"
Natanael Copa's avatar
Natanael Copa committed
286
	pkgname="$pkgname-dev"
287
	for i in $(cd "$pkgdir" && find usr/lib -name '*.a' -o \
Natanael Copa's avatar
Natanael Copa committed
288
289
			-name '*.la' -o -name '*.o' 2>/dev/null) \
			usr/include usr/lib/pkgconfig usr/share/aclocal; do
290
291
		if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
			d="$subpkgdir/${i%/*}"	# dirname $i
Natanael Copa's avatar
Natanael Copa committed
292
			mkdir -p "$d"
293
			mv "$pkgdir/$i" "$d"
Natanael Copa's avatar
Natanael Copa committed
294
295
296
297
298
299
		fi
	done
}

# build and package in fakeroot
rootpkg() {
Natanael Copa's avatar
Natanael Copa committed
300
	cd "$startdir"
Natanael Copa's avatar
Natanael Copa committed
301
302
303
304
	fakeroot $0 build subpkg package
}

srcpkg() {
305
	local p="$pkgname-$pkgver-$pkgrel"
Natanael Copa's avatar
Natanael Copa committed
306
	local prefix="${startdir##*/}"
Natanael Copa's avatar
Natanael Copa committed
307
308
309
310
311
	local i files="$prefix/APKBUILD"
	for i in $source; do
		files="$files $prefix/${i##*/}"
	done
	mkdir -p "$PKGDEST"
312
	(cd .. && tar -zcf "$PKGDEST/$p.src.tar.gz" $files) 
Natanael Copa's avatar
Natanael Copa committed
313
314
}

315
316
# check if package is up to date
up2date() {
317
	local pkg="$PKGDEST/$pkgname-$pkgver-$pkgrel.apk"
318
	local i s
Natanael Copa's avatar
Natanael Copa committed
319
	cd "$startdir"
320
321
322
323
324
325
326
327
328
329
	[ -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
330
331
332
333
334
335
336
337
338
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:"
339
340
341
342
343
344
345
346
347
348
349
350
351
	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
352
353
354
355
356
357
358
359
360
	echo ""
	exit 0
}

checksum() {
	local s files
	for s in $source; do
		files="$files ${s##*/}"
	done
361
362
	md5sums="$(cd "$SRCDEST" && md5sum $files)" || die "md5sum failed"
	echo "md5sums=\"$md5sums\""
Natanael Copa's avatar
Natanael Copa committed
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
}

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
389
	if up2date && [ -z "$force" ]; then
Natanael Copa's avatar
Natanael Copa committed
390
		msg "Package is up to date"
391
392
393
	else
		set $default_cmds
	fi
Natanael Copa's avatar
Natanael Copa committed
394
395
396
397
398
399
400
fi

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