diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | abuild-tar.c | 199 | ||||
-rw-r--r-- | abuild.conf | 10 | ||||
-rw-r--r-- | abuild.in | 363 | ||||
-rw-r--r-- | abump.in | 4 | ||||
-rw-r--r-- | apkbuild-gem-resolver.in | 386 | ||||
-rw-r--r-- | buildrepo.in | 206 | ||||
-rw-r--r-- | functions.sh.in | 4 | ||||
-rw-r--r-- | newapkbuild.in | 32 |
10 files changed, 860 insertions, 355 deletions
@@ -8,10 +8,10 @@ abuild-tar abump ap apkbuild-cpan +apkbuild-gem-resolver apkgrel buildlab -buildrepo checkapk devbuild -newapkbuild functions.sh +newapkbuild @@ -1,6 +1,6 @@ PACKAGE := abuild -VERSION := 2.20.1 +VERSION := 2.23.0_rc3 prefix ?= /usr bindir ?= $(prefix)/bin @@ -8,8 +8,9 @@ sysconfdir ?= /etc datadir ?= $(prefix)/share/$(PACKAGE) abuildrepo ?= ~/.cache/abuild -SCRIPTS := abuild buildrepo abuild-keygen abuild-sign newapkbuild \ - abump apkgrel buildlab apkbuild-cpan checkapk +SCRIPTS := abuild abuild-keygen abuild-sign newapkbuild \ + abump apkgrel buildlab apkbuild-cpan checkapk \ + apkbuild-gem-resolver USR_BIN_FILES := $(SCRIPTS) abuild-tar abuild-sudo SAMPLES := sample.APKBUILD sample.initd sample.confd \ sample.pre-install sample.post-install diff --git a/abuild-tar.c b/abuild-tar.c index 4a88882..2f29d30 100644 --- a/abuild-tar.c +++ b/abuild-tar.c @@ -1,6 +1,6 @@ /* abuild-tar.c - A TAR mangling utility for .APK packages * - * Copyright (C) 2009 Timo Teräs <timo.teras@iki.fi> + * Copyright (C) 2009-2014 Timo Teräs <timo.teras@iki.fi> * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -89,6 +89,19 @@ static void put_octal(char *s, size_t l, size_t value) *(ptr--) = '0'; } +static void tarhdr_checksum(struct tar_header *hdr) +{ + const unsigned char *src; + size_t chksum, i; + + /* Recalculate checksum */ + memset(hdr->chksum, ' ', sizeof(hdr->chksum)); + src = (const unsigned char *) hdr; + for (i = chksum = 0; i < sizeof(*hdr); i++) + chksum += src[i]; + put_octal(hdr->chksum, sizeof(hdr->chksum)-1, chksum); +} + static int usage(void) { fprintf(stderr, @@ -120,7 +133,7 @@ static ssize_t full_read(int fd, void *buf, size_t count) } while (1); if (total == 0 && n < 0) - return -1; + return -errno; return total; } @@ -142,7 +155,7 @@ static ssize_t full_write(int fd, const void *buf, size_t count) } while (1); if (total == 0 && n < 0) - return -1; + return -errno; return total; } @@ -163,82 +176,182 @@ static ssize_t full_splice(int from_fd, int to_fd, size_t count) } while (1); if (total == 0 && n < 0) - return -1; + return -errno; return total; } -static int do_it(const EVP_MD *md, int cut) +#define BUF_INITIALIZER {0} +struct buf { + char *ptr; + size_t size; + size_t alloc; +}; + +static void buf_free(struct buf *b) +{ + free(b->ptr); +} + +static int buf_resize(struct buf *b, size_t newsize) { - struct tar_header hdr; - size_t size, aligned_size; void *ptr; - int dohash = 0, r; + + if (b->alloc >= newsize) return 0; + ptr = realloc(b->ptr, newsize); + if (!ptr) return -ENOMEM; + b->ptr = ptr; + b->alloc = newsize; + return 0; +} + +static int buf_padto(struct buf *b, size_t alignment) +{ + size_t oldsize, newsize; + oldsize = b->size; + newsize = (oldsize + alignment - 1) & -alignment; + if (buf_resize(b, newsize)) return -ENOMEM; + b->size = newsize; + memset(b->ptr + oldsize, 0, newsize - oldsize); + return 0; +} + +static int buf_read_fd(struct buf *b, int fd, size_t size) +{ + ssize_t r; + + r = buf_resize(b, size); + if (r) return r; + + r = full_read(fd, b->ptr, size); + if (r == size) { + b->size = r; + return 0; + } + b->size = 0; + if (r < 0) return r; + return -EIO; +} + +static int buf_write_fd(struct buf *b, int fd) +{ + ssize_t r; + r = full_write(fd, b->ptr, b->size); + if (r == b->size) return 0; + if (r < 0) return r; + return -ENOSPC; +} + +static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const char *value, int valuelen) +{ + size_t oldsize = b->size; + int i, len; + + /* "%u %s=%s\n" */ + len = 1 + 1 + strlen(hdr) + 1 + valuelen*2 + 1; + for (i = len; i > 9; i /= 10) len++; + + if (buf_resize(b, b->size + len)) return -ENOMEM; + b->size += snprintf(&b->ptr[b->size], len, "%u %s=", len, hdr); + for (i = 0; i < valuelen; i++) + b->size += snprintf(&b->ptr[b->size], 3, "%02x", (int)(unsigned char)value[i]); + b->ptr[b->size++] = '\n'; + + return 0; +} + +static void add_legacy_checksum(struct tar_header *hdr, const EVP_MD *md, const char *digest) +{ struct { char id[4]; uint16_t nid; uint16_t size; } mdinfo; - if (md != NULL) { - memcpy(mdinfo.id, "APK2", 4); - mdinfo.nid = EVP_MD_nid(md); - mdinfo.size = EVP_MD_size(md); - } + memcpy(mdinfo.id, "APK2", 4); + mdinfo.nid = EVP_MD_nid(md); + mdinfo.size = EVP_MD_size(md); + memcpy(&hdr->linkname[3], &mdinfo, sizeof(mdinfo)); + memcpy(&hdr->linkname[3+sizeof(mdinfo)], digest, mdinfo.size); + tarhdr_checksum(hdr); +} + +static int do_it(const EVP_MD *md, int cut) +{ + char checksumhdr[32], digest[EVP_MAX_MD_SIZE]; + struct buf data = BUF_INITIALIZER, pax = BUF_INITIALIZER; + struct tar_header hdr, paxhdr; + size_t size, aligned_size; + int dohash = 0, r, ret = 1; + + if (md) snprintf(checksumhdr, sizeof(checksumhdr), "APK-TOOLS.checksum.%s", EVP_MD_name(md)); do { if (full_read(STDIN_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) - return 0; + goto err; if (cut && hdr.name[0] == 0) - return 0; + break; size = GET_OCTAL(hdr.size); aligned_size = (size + 511) & ~511; - if (md != NULL) - dohash = (hdr.typeflag == '0' || hdr.typeflag == '7'); + if (hdr.typeflag == 'x') { + memcpy(&paxhdr, &hdr, sizeof(hdr)); + if (buf_read_fd(&pax, STDIN_FILENO, aligned_size)) goto err; + pax.size = size; + continue; + } + + dohash = md && (hdr.typeflag == '0' || hdr.typeflag == '7' || hdr.typeflag == '2'); if (dohash) { - const unsigned char *src; - int chksum, i; - - ptr = malloc(aligned_size); - if (full_read(STDIN_FILENO, ptr, aligned_size) != aligned_size) - return 1; - - memcpy(&hdr.linkname[3], &mdinfo, sizeof(mdinfo)); - EVP_Digest(ptr, size, &hdr.linkname[3+sizeof(mdinfo)], - NULL, md, NULL); - - /* Recalculate checksum */ - memset(hdr.chksum, ' ', sizeof(hdr.chksum)); - src = (const unsigned char *) &hdr; - for (i = chksum = 0; i < sizeof(hdr); i++) - chksum += src[i]; - put_octal(hdr.chksum, sizeof(hdr.chksum)-1, chksum); + if (buf_read_fd(&data, STDIN_FILENO, aligned_size)) goto err; + + if (hdr.typeflag != '2') { + EVP_Digest(data.ptr, size, digest, NULL, md, NULL); + add_legacy_checksum(&hdr, md, digest); + } else { + EVP_Digest(hdr.linkname, strlen(hdr.linkname), digest, NULL, md, NULL); + } + + buf_add_ext_header_hexdump(&pax, checksumhdr, digest, EVP_MD_size(md)); + PUT_OCTAL(paxhdr.size, pax.size); + tarhdr_checksum(&paxhdr); + } + + if (pax.size) { + /* write pax header + content */ + if (full_write(STDOUT_FILENO, &paxhdr, sizeof(paxhdr)) != sizeof(paxhdr) || + buf_padto(&pax, 512) || + buf_write_fd(&pax, STDOUT_FILENO)) goto err; } - if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) - return 2; + if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) goto err; if (dohash) { - if (full_write(STDOUT_FILENO, ptr, aligned_size) != aligned_size) - return 2; - free(ptr); + if (buf_write_fd(&data, STDOUT_FILENO)) goto err; } else if (aligned_size != 0) { r = full_splice(STDIN_FILENO, STDOUT_FILENO, aligned_size); if (r == -1) { while (aligned_size > 0) { if (full_read(STDIN_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) - return 1; + goto err; if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) - return 2; + goto err; aligned_size -= sizeof(hdr); } - } else if (r != aligned_size) - return 2; + } else if (r != aligned_size) goto err; } + + memset(&paxhdr, 0, sizeof(paxhdr)); + pax.size = 0; } while (1); + + ret = 0; +err: + buf_free(&data); + buf_free(&pax); + return ret; } int main(int argc, char **argv) diff --git a/abuild.conf b/abuild.conf index fee09a2..1a3af9f 100644 --- a/abuild.conf +++ b/abuild.conf @@ -1,10 +1,10 @@ -CHOST=i486-alpine-linux-uclibc +CHOST=i486-alpine-linux-musl # for x86_64 we want: -# CHOST=x86_64-alpine-linux-uclibc +# CHOST=x86_64-alpine-linux-musl # for powerpc we want: -# CHOST=powerpc-alpine-linux-uclibc +# CHOST=powerpc-alpine-linux-musl export CFLAGS="-Os -fomit-frame-pointer" export CXXFLAGS="$CFLAGS" @@ -24,8 +24,10 @@ SRCDEST=/var/cache/distfiles # where $repo is the name of the parent directory of $startdir. REPODEST=$HOME/packages/ -# PACKAGER is used to create new aports with 'newapkbuild ...' +# PACKAGER and MAINTAINER are used by newapkbuild when creating new aports for +# the APKBUILD's "Contributor:" and "Maintainer:" comments, respectively. #PACKAGER="Your Name <your@email.address>" +#MAINTAINER="$PACKAGER" # what to clean up after a successful build CLEANUP="srcdir pkgdir deps" @@ -1,7 +1,7 @@ #!/bin/sh # abuild - build apk packages (light version of makepkg) -# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com> +# Copyright (c) 2008-2015 Natanael Copa <ncopa@alpinelinux.org> # # Distributed under GPL-2 # @@ -179,6 +179,16 @@ default_sanitycheck() { esac list_has ${i##*/} $md5sums $sha256sums $sha512sums \ || die "${i##*/} is missing in checksums" + + # verify that our source does not have git tag version + # name as tarball (typicallly github) + if is_remote "$i" && [ "${i#*::}" = "$i" ]; then + case ${i##*/} in + v$pkgver.tar.*|$pkgver.tar.*) + die "source ${i##*/} needs to be renamed to avoid possible collisions" + ;; + esac + fi done fi @@ -414,13 +424,20 @@ fetch() { # verify that all init.d scripts are openrc runscripts initdcheck() { - local i + local i line for i in $source; do case $i in - *.initd) - head -n 1 "$srcdir"/$i | grep -q '/sbin/runscript' \ - && continue - error "$i is not an openrc #!/sbin/runscript" + *.initd) line=$(head -n 1 "$srcdir"/$i);; + *) continue ;; + esac + + case "$line" in + *sbin/openrc-run) + ;; + *sbin/runscript) + warning "$i is not an openrc #!/sbin/openrc-run" + ;; + *) error "$i is not an openrc #!/sbin/openrc-run" return 1 ;; esac @@ -520,6 +537,7 @@ cleanoldpkg() { rm -f "$j" "$abuildrepo"/*/${j##*/} done done + update_abuildrepo_index return 0 } @@ -615,13 +633,12 @@ postcheck() { return 1 fi fi - # look for *.la files - i=$(find "$dir" -name '*.la' | sed "s|^$dir|\t|") - if [ -n "$i" ] && ! options_has "libtool"; then - error "Libtool archives (*.la) files found and \$options has no 'libtool' flag:" - echo "$i" - return 1 + + # remove *.la files if libtool is not set + if ! options_has "libtool"; then + find "$dir" -name '*.la' -type f -delete fi + # look for /usr/lib/charset.alias if [ -e "$dir"/usr/lib/charset.alias ] \ && ! options_has "charset.alias"; then @@ -634,7 +651,7 @@ postcheck() { warning "World writeable directories found:" echo "$i" fi - # check so we dont have any suid root binaries that are not + # check so we dont have any suid root binaries that are not PIE i=$(find "$dir" -type f -perm +6000 \ | xargs scanelf --nobanner --etype ET_EXEC \ | sed "s|ET_EXEC $dir|\t|") @@ -643,6 +660,17 @@ postcheck() { echo "$i" return 1 fi + # test suid bit on executable + if ! options_has "suid"; then + i=$(find "$dir" \( -perm -u+s -o -perm -g+s \) -a -type f \ + -a -perm -o+x) + if [ -n "$i" ]; then + error "Found executable files with SUID bit set:" + echo "$i" + return 1 + fi + fi + # test for textrels if ! options_has "textrels"; then local res="$(scanelf --recursive --textrel --quiet "$dir")" @@ -655,6 +683,15 @@ postcheck() { return 0 } +pre_split() { + if [ -z "$subpkgname" ]; then + return 0 + fi + # the subpackages should not inherit those form main package + provides="" + install_if="" +} + prepare_subpackages() { local i cd "$startdir" @@ -664,7 +701,7 @@ prepare_subpackages() { msg "Running split function $func..." local dir="$pkgbasedir/${i%:*}" name="${i%:*}" ( subpkgdir="$dir" subpkgname="$name" \ - $0 $func prepare_package \ + $0 pre_split $func prepare_package \ && postcheck "$dir" "$name" ) || return 1 done postcheck "$pkgdir" "$pkgname" || return 1 @@ -804,18 +841,13 @@ EOF echo "replaces_priority = $replaces_priority" >> "$pkginfo" fi - for i in $license; do - echo "license = $i" >> "$pkginfo" - done + echo "license = $license" >> "$pkginfo" for i in $replaces; do echo "replaces = $i" >> "$pkginfo" done for i in $deps; 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 @@ -845,7 +877,7 @@ EOF echo $metafiles | tr ' ' '\n' > "$controldir"/.metafiles } -prepare_tracedeps() { +prepare_trace_rpaths() { local dir=${subpkgdir:-$pkgdir} local etype= soname= file= sover= [ "$arch" = "noarch" ] && return 0 @@ -863,6 +895,34 @@ prepare_tracedeps() { fi } +# search for broken symlinks so we later can pull in proper depends +prepare_symlinks() { + local dir="${subpkgdir:-$pkgdir}" + options_has "!tracedeps" && return 0 + cd "$dir" || return 1 + find -type l | while read symlink; do + if ! [ -e "$symlink" ]; then + echo "$symlink $(readlink $symlink)" \ + >> "$controldir"/.symlinks + fi + done +} + +prepare_pkgconfig_provides() { + local dir="${subpkgdir:-$pkgdir}" + options_has "!tracedeps" && return 0 + cd "$dir" || return 1 + for i in usr/lib/pkgconfig/*.pc; do + if ! [ -e "$i" ]; then + continue + fi + local f=${i##*/} + local v=$(PKG_CONFIG_PATH="$dir"/usr/lib/pkgconfig pkg-config \ + --modversion ${f%.pc}) + echo "${f%.pc}=${v:-0}" >> "$controldir"/.provides-pc + done +} + # check if dir has arch specific binaries dir_has_arch_binaries() { local dir="$1" @@ -897,7 +957,11 @@ archcheck() { prepare_package() { msg "Preparing ${subpkgname:+sub}package ${subpkgname:-$pkgname}..." stripbin - prepare_metafiles && prepare_tracedeps || return 1 + prepare_metafiles \ + && prepare_trace_rpaths \ + && prepare_symlinks \ + && prepare_pkgconfig_provides \ + || return 1 archcheck } @@ -930,10 +994,15 @@ find_so_files() { return 0 } -subpkg_provides() { +subpkg_provides_so() { grep -q -w "^$1" "$pkgbasedir"/.control.*/.provides-so 2>/dev/null } +subpkg_provides_pc() { + grep -q -w "^${1%%[<>=]*}" "$pkgbasedir"/.control.*/.provides-pc \ + 2>/dev/null +} + trace_apk_deps() { local name="$1" local dir="$2" @@ -942,21 +1011,22 @@ trace_apk_deps() { # add pkgconfig if usr/lib/pkgconfig is found if [ -d "$pkgbasedir"/$name/usr/lib/pkgconfig ] \ && ! grep -q '^depend = pkgconfig' "$dir"/.PKGINFO; then - msg " added pkgconfig (found /usr/lib/pkgconfig)" autodeps="$autodeps pkgconfig" fi # special case for libpthread: we need depend on libgcc - if [ -f "$dir"/.needs-so ] && grep -q -w '^libpthread.so.*' "$dir"/.needs-so \ + if [ "$CLIBC" = "uclibc" ] && [ -f "$dir"/.needs-so ] \ + && grep -q -w '^libpthread.so.*' "$dir"/.needs-so \ && ! grep -q -w "^depend = libgcc" "$dir"/.PKGINFO; then autodeps="$autodeps libgcc" msg " added libgcc (due to libpthread)" fi + [ -f "$dir"/.needs-so ] && for i in $(cat "$dir"/.needs-so); do # first check if its provided by same apkbuild grep -q -w "^$i" "$dir"/.provides-so 2>/dev/null && continue - if subpkg_provides "$i" || cross_compiling \ + if subpkg_provides_so "$i" || cross_compiling \ || $APK info --quiet --installed "so:$i"; then autodeps="$autodeps so:$i" else @@ -979,11 +1049,39 @@ trace_apk_deps() { autodeps="$autodeps $found" done + # symlink targets + for i in $(sort -u "$dir"/.symlinks-needs 2>/dev/null); do + autodeps="$autodeps $i" + done + + # pkg-config depends + for i in $(sort -u "$dir"/.needs-pc 2>/dev/null); do + if subpkg_provides_pc "$i" || cross_compiling \ + || $APK info --quiet --installed "pc:$i"; then + local provider=$(apk search --quiet "pc:$i") + if list_has "$provider" $depends_dev; then + warning "$provider should be removed from depends_dev" + fi + autodeps="$autodeps pc:$i" + else + warning "Could not find any provider for pc:$i" + local pcfile=/usr/lib/pkgconfig/"${i%%[<>=]*}".pc + if [ -e "$pcfile" ]; then + local owner=$($APK info --quiet --who-owns $pcfile) + warning "${owner:-package providing $pcfile} needs to be rebuilt" + fi + fi + done + echo "# automatically detected:" >> "$dir"/.PKGINFO if [ -f "$dir"/.provides-so ]; then sed 's/^\(.*\) \([0-9].*\)/provides = so:\1=\2/' "$dir"/.provides-so \ >> "$dir"/.PKGINFO fi + if [ -f "$dir"/.provides-pc ]; then + sed 's/^/provides = pc:/' "$dir"/.provides-pc | sort -u \ + >> "$dir"/.PKGINFO + fi [ -z "$autodeps" ] && return 0 for i in $autodeps; do echo "depend = $i" @@ -1017,6 +1115,10 @@ scan_shared_objects() { local name="$1" controldir="$2" datadir="$3" local opt= i= + if [ "$arch" = "noarch" ]; then + return 0 + fi + # allow spaces in paths IFS=: set -- $(find_scanelf_paths "$datadir") @@ -1087,6 +1189,66 @@ scan_shared_objects() { done > "$controldir"/.needs-so } +# normalize a path string +normalize_path() { + local oifs="$IFS" pathstr= i= + IFS='/' + set -- $1 + for i; do + case "$i" in + "."|"") continue;; + "..") pathstr="${pathstr%%/${pathstr##*/}}";; + *) pathstr="${pathstr}/$i";; + esac + done + echo "$pathstr" +} + +# find which package provides file that symlink points to +scan_symlink_targets() { + local name="$1" dir="$2" datadir="$3" + local symfile= targetpath= + cd "$datadir" + for symfile in "$pkgbasedir"/.control.*/.symlinks; do + local d="${symfile%/.symlinks}" + if ! [ -e "$symfile" ] || [ "$d" = "$dir" ]; then + continue + fi + + while read symlink target; do + if [ "${target#/}" = "$target" ]; then + target="${symlink%/*}/$target" + fi + targetpath="$datadir"/$(normalize_path "$target") + if [ -e "$targetpath" ] || [ -L "$targetpath" ]; then + echo "$name=$pkgver-r$pkgrel" \ + >> "$d"/.symlinks-needs + fi + done < "$symfile" + done +} + +#find pkg-config dependencies +scan_pkgconfig_depends() { + local provides_pc="$1" controldir= name= datadir= + [ -e "$provides_pc" ] || return 0 + controldir="${provides_pc%/*}" + name="$(pkginfo_val pkgname "$controldir"/.PKGINFO)" + datadir="$pkgbasedir"/$name + for i in $(sort -u "$provides_pc"); do + PKG_CONFIG_PATH="$datadir"/usr/lib/pkgconfig pkg-config \ + --print-requires \ + --print-requires-private ${i%=*} \ + | sed -E 's/\s*([<>=]+)\s*/\1/' \ + | while read pc; do + # only add files that are not self provided + if ! grep -q -w "^${pc%%[<>=]*}" "$provides_pc"; then + echo "$pc" >> "$controldir"/.needs-pc + fi + done + done +} + # read size in bytes from stdin and show as human readable human_size() { awk '{ split("B KB MB GB TB PB", type) @@ -1099,15 +1261,20 @@ create_apks() { local file= dir= name= ver= apk= datadir= size= getpkgver || return 1 mkdir -p "$PKGDEST" - if [ "$arch" != "noarch" ] && ! options_has "!tracedeps"; then + if ! options_has "!tracedeps"; then for file in "$pkgbasedir"/.control.*/.PKGINFO; do dir="${file%/.PKGINFO}" name="$(pkginfo_val pkgname $file)" datadir="$pkgbasedir"/$name subpkgname=$name scan_shared_objects "$name" "$dir" "$datadir" + scan_symlink_targets "$name" "$dir" "$datadir" + done + for file in "$pkgbasedir"/.control.*/.provides-pc; do + scan_pkgconfig_depends "$file" done fi + for file in "$pkgbasedir"/.control.*/.PKGINFO; do dir="${file%/.PKGINFO}" name=$(pkginfo_val pkgname $file) @@ -1128,7 +1295,7 @@ create_apks() { touch .dummy set -- .dummy fi - tar -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz + tar --xattrs -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz msg "Create checksum..." # append the hash for data.tar.gz @@ -1224,6 +1391,7 @@ default_doc() { depends="$depends_doc" pkgdesc="$pkgdesc (documentation)" arch=${arch_doc:-"noarch"} + install_if="docs $pkgname=$pkgver-r$pkgrel" local i for i in doc man info html sgml licenses gtk-doc ri help; do @@ -1233,6 +1401,11 @@ default_doc() { fi done + # compress man pages + find "$subpkgdir"/usr/share/man/*[1-9] \ + -type f \! -name \*.gz \! -name \*.bz2 2>/dev/null | + xargs -r gzip -9 + rm -f "$subpkgdir/usr/share/info/dir" # remove if empty, ignore error (not empty) @@ -1273,14 +1446,12 @@ dbg() { # predefined splitfunc dev default_dev() { local i= j= - depends="$pkgname=$pkgver-r$pkgrel $depends_dev" + depends="$depends_dev" pkgdesc="$pkgdesc (development files)" - for i in $origsubpackages; do - [ "${i%:*}" = "$subpkgname" ] || depends="$depends ${i%:*}=$pkgver-r$pkgrel" - done - cd "$pkgdir" || return 0 + local libdirs=usr/ + [ -d lib/ ] && libdirs="lib/ $libdirs" for i in usr/include usr/lib/pkgconfig usr/share/aclocal\ usr/share/gettext usr/bin/*-config \ usr/share/vala/vapi usr/share/gir-[0-9]*\ @@ -1288,7 +1459,7 @@ default_dev() { usr/lib/qt*/mkspecs \ usr/lib/cmake \ $(find . -name include -type d) \ - $(find lib/ usr/ -name '*.[acho]' \ + $(find $libdirs -name '*.[acho]' \ -o -name '*.prl' 2>/dev/null); do if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then d="$subpkgdir/${i%/*}" # dirname $i @@ -1443,11 +1614,12 @@ abuildindex() { # 1) origin of package # 2) all dependencies # the output is i in a format easy parseable for awk -depparse_aports() { +parse_aports_makedepends() { # lets run this in a subshell since we source all APKBUILD here ( aportsdir=$(realpath ${APKBUILD%/APKBUILD}/..) for i in $aportsdir/*/APKBUILD; do + # no forks in this loop or it will be painfully slow! pkgname= subpackages= depends= @@ -1477,14 +1649,14 @@ depparse_aports() { ) } -deptrace() { +trace_makedepends() { local deps= i= # strip versions from deps for i in "$@"; do deps="$deps ${i%%[<>=]*}" done [ -z "$deps" ] && return 0 - ( depparse_aports + ( parse_aports_makedepends if [ -z "$upgrade" ]; then # list installed pkgs and prefix with 'i ' $APK info --quiet | sort | sed 's/^/i /' @@ -1515,7 +1687,7 @@ deptrace() { # build and install dependencies builddeps() { - local pkg= i= missing= conflicts= + local pkg= i= missing= local hostdeps= builddeps= installed_hostdeps= installed_builddeps= [ -n "$nodeps" ] && return 0 msg "Analyzing dependencies..." @@ -1545,27 +1717,20 @@ builddeps() { # find which deps are missing for i in $builddeps; do - if [ "${i#\!}" != "$i" ]; then - $APK info --quiet --installed "${i#\!}" \ - && conflicts="$conflicts ${i#\!}" + if [ "${i#\!}" != "$i" ] && $APK info --quiet --installed "${i#\!}"; then + error "Conflicting package installed: ${i#\!}" elif ! deplist_has $i $installed_builddeps || [ -n "$upgrade" ]; then missing="$missing $i" fi done for i in $hostdeps; do - if [ "${i#\!}" != "$i" ]; then - $APK info --quiet --installed --root "$CBUILDROOT" "${i#\!}" \ - && conflicts="$conflicts ${i#\!}" + if [ "${i#\!}" != "$i" ] && $APK info --quiet --installed --root "$CBUILDROOT" "${i#\!}"; then + error "Conflicting package installed: ${i#\!}" elif ! deplist_has $i $installed_hostdeps || [ -n "$upgrade" ]; then missing="$missing $i" fi done - if [ -n "$conflicts" ]; then - error "Conflicting package(s) installed:$conflicts" - return 1 - fi - if [ -z "$install_deps" ] && [ -z "$recursive" ]; then # if we dont have any missing deps we are done now [ -z "$missing" ] && return 0 @@ -1577,7 +1742,6 @@ builddeps() { if [ -n "$install_deps" ] && [ -z "$recursive" ]; then # make a --simulate run first to detect missing deps # apk-tools --virtual is no goot at reporting those. - msg "Installing packages on builder: $builddeps" $SUDO_APK add --repository "$abuildrepo" $apk_opt_wait \ --simulate --quiet $builddeps || return 1 $SUDO_APK add --repository "$abuildrepo" $apk_opt_wait \ @@ -1605,7 +1769,7 @@ builddeps() { fi done - for i in $(deptrace $missing); do + for i in $(trace_makedepends $missing); do # i = pkg:dir local dir=${i#*:} local pkg=${i%:*} @@ -1671,7 +1835,11 @@ stripbin() { msg "Stripping binaries" scanelf --recursive --nobanner --etype "ET_DYN,ET_EXEC" . \ | sed -e 's:^ET_DYN ::' -e 's:^ET_EXEC ::' \ - | xargs -r ${CROSS_COMPILE}strip + | while read filename; do + XATTR=$(getfattr --match="*" --dump "${filename}") + ${CROSS_COMPILE}strip "${filename}" + [ -n "$XATTR" ] && (echo "$XATTR" | setfattr --restore=-) + done } # simply list target apks @@ -1794,6 +1962,7 @@ undeps (){ # compat installdeps() { deps; } uninstalldeps() { undeps; } +index() { update_abuildrepo_index; } all() { if ! [ -n "$force" ]; then @@ -1869,49 +2038,52 @@ snapshot() { usage() { echo "$program $program_version" - echo "usage: $program [options] [-i PKG] [-P REPODEST] [-p PKGDEST]" - echo " [-s SRCDEST] [cmd] ..." - echo " $program [-c] -n PKGNAME[-PKGVER]" - echo "Options:" - echo " -a Print CARCH and exit" - echo " -c Enable colored output" - echo " -d Disable dependency checking" - echo " -f Force specified cmd, even if they are already done" - echo " -F Force run as root" - echo " -h Show this help" - echo " -i Install PKG after successful build" - echo " -k Keep built packages, even if APKBUILD or sources are newer" - echo " -m Disable colors (monochrome)" - echo " -p Set package destination directory" - echo " -P Set PKGDEST to REPODEST/<repo>/\$CARCH, where repo is the parents dir name" - echo " -q Quiet" - echo " -r Install missing dependencies from system repository (using sudo)" - echo " -R Recursively build and install missing dependencies (using sudo)" - echo " -s Set source package destination directory" - echo " -u Recursively build and upgrade all dependencies (using sudo)" - echo "" - echo "Commands:" - 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 " verify Verify checksums" - echo " unpack Unpack sources to \$srcdir" - echo " prepare Apply patches" - echo " build Compile and install package into \$pkgdir" - echo " listpkg List target packages" - echo " package Create package in \$PKGDEST" - echo " rootpkg Run 'package', the split functions and create apks as fakeroot" - echo " clean Remove temp build and install dirs" - echo " cleanoldpkg Remove binary packages except current version" - echo " cleanpkg Remove already built binary and source package" - echo " cleancache Remove downloaded files from \$SRCDEST" - echo " srcpkg Make a source package" - echo " sourcecheck Check if remote source package exists upstream" - echo " up2date Compare target and sources dates" - echo " deps Install packages listed in makedepends and depends" - echo " undeps Uninstall packages listed in makedepends and depends" - echo " snapshot Create a \$giturl or \$svnurl snapshot and upload to \$disturl" - echo "" + cat << EOF +usage: $program [options] [-i PKG] [-P REPODEST] [-p PKGDEST] + [-s SRCDEST] [cmd] ... + $program [-c] -n PKGNAME[-PKGVER] +Options: + -A Print CARCH and exit + -c Enable colored output + -d Disable dependency checking + -f Force specified cmd, even if they are already done + -F Force run as root + -h Show this help + -i Install PKG after successful build + -k Keep built packages, even if APKBUILD or sources are newer + -m Disable colors (monochrome) + -p Set package destination directory + -P Set PKGDEST to REPODEST/<repo>/\$CARCH, where repo is the parents dir name + -q Quiet + -r Install missing dependencies from system repository (using sudo) + -R Recursively build and install missing dependencies (using sudo) + -s Set source package destination directory + -u Recursively build and upgrade all dependencies (using sudo) + +Commands: + build Compile and install package into \$pkgdir + checksum Generate checksum to be included in APKBUILD + clean Remove temp build and install dirs + cleancache Remove downloaded files from \$SRCDEST + cleanoldpkg Remove binary packages except current version + cleanpkg Remove already built binary and source package + deps Install packages listed in makedepends and depends + fetch Fetch sources to \$SRCDEST and verify checksums + index Regenerate the APKINDEX for abuildrepo + listpkg List target packages + package Create package in \$PKGDEST + prepare Apply patches + rootpkg Run 'package', the split functions and create apks as fakeroot + sanitycheck Basic sanity check of APKBUILD + snapshot Create a \$giturl or \$svnurl snapshot and upload to \$disturl + sourcecheck Check if remote source package exists upstream + srcpkg Make a source package + undeps Uninstall packages listed in makedepends and depends + unpack Unpack sources to \$srcdir + up2date Compare target and sources dates + verify Verify checksums + +EOF exit 0 } @@ -1984,6 +2156,7 @@ fi # if we want build debug package if [ -n "$DEBUG" ] || subpackage_types_has "dbg"; then CFLAGS="$CFLAGS -g" + CXXFLAGS="$CXXFLAGS -g" options="$options !strip" fi @@ -28,6 +28,9 @@ do_bump() { fi name=${p%-[0-9]*} ver=${p#${name}-} + if [ "$name" = "$ver" ]; then + die "version missing for $p" + fi ( set -e @@ -41,6 +44,7 @@ do_bump() { # verify APKBUILD . "$a" || exit 1 + name=${name#*/} [ "$pkgname" = "$name" ] \ || die "APKBUILD has different \$pkgname for $name" type package | grep -q function \ diff --git a/apkbuild-gem-resolver.in b/apkbuild-gem-resolver.in new file mode 100644 index 0000000..d6782e1 --- /dev/null +++ b/apkbuild-gem-resolver.in @@ -0,0 +1,386 @@ +#!/usr/bin/ruby + +# APKBUILD dependency resolver for RubyGems +# Copyright (C) 2014-2015 Kaarle Ritvanen + +require 'augeas' +require 'optparse' +require 'rubygems/dependency' +require 'rubygems/resolver' +require 'rubygems/spec_fetcher' + +class Package + @@packages = {} + + def self.initialize testing + @@augeas = Augeas::open(nil, nil, Augeas::NO_MODL_AUTOLOAD) + dir = Dir.pwd + @@augeas.transform( + :lens => 'Shellvars.lns', :incl => dir + '/*/ruby*/APKBUILD' + ) + @@augeas.load + + apath = '/files' + dir + fail unless @@augeas.match("/augeas#{apath}//error").empty? + + repos = ['main'] + repos << 'testing' if testing + for repo in repos + for pkg in @@augeas.match "#{apath}/#{repo}/*" + Aport.new(pkg) unless pkg.end_with? '/ruby' + end + end + + Subpackage.initialize @@augeas.get("#{apath}/main/ruby/APKBUILD/pkgver") + + @@packages.each_value do |pkg| + pkg.depends do |dep| + dep.add_user pkg + end + end + end + + def self.get name + pkg = @@packages[name] + raise 'Invalid package name: ' + name unless pkg + pkg + end + + def self.save + fail unless @@augeas.save + end + + def initialize name + @name = name + @depends = [] + @users = [] + @@packages[name] = self + end + + def add_dependency name + @depends << name + end + + attr_reader :name + + def depends + for dep in @depends + # ruby-gems: workaround for v2.6 + if dep.start_with?('ruby-') && dep != 'ruby-gems' + unless @@packages.has_key? dep + raise "Dependency for #{@name} does not exist: #{dep}" + end + yield @@packages[dep] + end + end + end + + def users + for user in @users + yield user + end + end + + def add_user user + @users << user + end +end + +class Aport < Package + def initialize path + super path.split('/')[-1] + + @path = path[6..-1] + @apath = path + '/APKBUILD/' + + for dep in `echo #{get_param 'depends'}`.split + add_dependency dep + end + end + + attr_reader :path + + def gem + get_param '_gemname' + end + + def version + get_param 'pkgver' + end + + def version= version + set_param 'pkgver', version + set_param 'pkgrel', '0' + end + + def del_dependency name + @depends.delete name + set_param 'depends', "\"#{@depends.join ' '}\"" + end + + private + + def get_param name + value = @@augeas.get(@apath + name) + raise name + ' not defined for ' + @name unless value + value + end + + def set_param name, value + @@augeas.set(@apath + name, value) + end +end + +class Subpackage < Package + RUBY_SUBPACKAGES = { + '2.0.0_p353' => { + 'ruby-minitest' => ['minitest', '4.3.2'], + 'ruby-rake' => ['rake', '0.9.6'], + 'ruby-rdoc' => ['rdoc', '4.0.0', 'ruby-json'] + }, + '2.0.0_p481' => { + 'ruby-minitest' => ['minitest', '4.3.2'], + 'ruby-rake' => ['rake', '0.9.6'], + 'ruby-rdoc' => ['rdoc', '4.0.0', 'ruby-json'] + }, + '2.1.5' => { + 'ruby-json' => ['json', '1.8.1'], + 'ruby-minitest' => ['minitest', '4.7.5'], + 'ruby-rake' => ['rake', '10.1.0'], + 'ruby-rdoc' => ['rdoc', '4.1.0', 'ruby-json'] + }, + '2.2.1' => { + # it's actually 0.4.3 but that version is not published on network + 'ruby-io-console' => ['io-console', '0.4.2'], + 'ruby-json' => ['json', '1.8.1'], + 'ruby-minitest' => ['minitest', '5.4.3'], + 'ruby-rake' => ['rake', '10.4.2'], + 'ruby-rdoc' => ['rdoc', '4.2.0', 'ruby-json'] + }, + '2.2.2' => { + # it's actually 0.4.3 but that version is not published on network + 'ruby-io-console' => ['io-console', '0.4.2'], + 'ruby-json' => ['json', '1.8.1'], + 'ruby-minitest' => ['minitest', '5.4.3'], + 'ruby-rake' => ['rake', '10.4.2'], + 'ruby-rdoc' => ['rdoc', '4.2.0', 'ruby-json'] + } + } + + @@subpackages = [] + + def self.initialize version + for name, attrs in RUBY_SUBPACKAGES[version] + new name, attrs + end + end + + def self.each + for pkg in @@subpackages + yield pkg + end + end + + def initialize name, attrs + super name + @gem, @version, *deps = attrs + for dep in deps + add_dependency dep + end + @@subpackages << self + end + + attr_reader :gem, :version +end + + +class Update + def initialize + @gems = {} + @deps = [] + end + + def require_version name, version + gem = assign(Package.get(name).gem, name) + @deps << gem.dependency if gem.require_version version + end + + def resolve + for pkg in Subpackage + require_version pkg.name, pkg.version unless @gems[pkg.gem] + end + + def check_deps + @gems.clone.each_value do |gem| + gem.check_deps + end + end + + check_deps + + for req in Gem::Resolver.new(@deps).resolve + spec = req.spec + gem = @gems[spec.name] + gem.require_version spec.version.version if gem + end + + check_deps + + for name, gem in @gems + if gem.updated? + gem.package.users do |user| + ugem = @gems[user.gem] + if !ugem || ugem.package.name != user.name + Gem::Resolver.new( + [gem.dependency, Gem::Dependency.new(user.gem, user.version)] + ).resolve + end + end + end + end + end + + def each + @gems.each_value do |gem| + update = gem.update + yield update if update + end + end + + def assign name, package + pkg = Package.get package + + if @gems.has_key? name + gem = @gems[name] + return gem if pkg == gem.package + raise "Conflicting packages for gem #{name}: #{gem.package.name} and #{pkg.name}" + end + + gem = PackagedGem.new self, name, pkg + @gems[name] = gem + gem + end + + private + + class PackagedGem + def initialize update, name, package + @update = update + @name = name + @package = package + end + + attr_reader :package + + def require_version version + if @version + return false if version == @version + raise "Conflicting versions for gem #{@name}: #{@version} and #{version}" + end + @version = version + true + end + + def version + @version || @package.version + end + + def updated? + version != @package.version + end + + def dependency + Gem::Dependency.new(@name, version) + end + + def check_deps + specs, errors = Gem::SpecFetcher::fetcher.spec_for_dependency(dependency) + raise "Invalid gem: #{@name}-#{version}" if specs.empty? + fail if specs.length > 1 + deps = specs[0][0].runtime_dependencies + + @obsolete_deps = [] + + @package.depends do |dep| + gem = @update.assign(dep.gem, dep.name) + gem.check_deps + unless deps.reject! { |sdep| sdep.match? dep.gem, gem.version } + @obsolete_deps << dep.name + end + end + + unless deps.empty? + raise 'Undeclared dependencies in ' + @package.name + deps.inject('') { + |s, dep| "#{s}\n#{dep.name} #{dep.requirements_list.join ' '}" + } + end + end + + def update + updated? || !@obsolete_deps.empty? ? ( + { + :name => @package.name, + :version => version, + :obsolete_deps => @obsolete_deps.clone, + :path => @package.path + } + ) : nil + end + end +end + + +testing = false +update_files = nil +OptionParser.new do |opts| + opts.on('-t', '--testing') do |t| + testing = t + end + opts.on('-u', '--update') do |u| + update_files = [] + end +end.parse! ARGV +Package.initialize testing + +latest = {} +for source, gems in Gem::SpecFetcher::fetcher.available_specs(:latest)[0] + for gem in gems + latest[gem.name] = gem.version.version + end +end + +update = Update.new +for arg in ARGV + match = /^(([^-]|-[^\d])+)(-(\d.*))?/.match arg + name = match[1] + update.require_version name, match[4] || latest[Package.get(name).gem] +end + +update.resolve + +for pkg in update + obsolete = pkg[:obsolete_deps] + + obs = obsolete.empty? ? + nil : " (obsolete dependencies: #{obsolete.join ', '})" + puts "#{pkg[:name]}-#{pkg[:version]}#{obs}" + + if update_files + package = Package.get(pkg[:name]) + package.version = pkg[:version] + for dep in obsolete + package.del_dependency dep + end + update_files << pkg[:path] + end +end + +if update_files + Package.save + + for path in update_files + Dir.chdir(path) do + fail unless system('abuild checksum') + end + end +end diff --git a/buildrepo.in b/buildrepo.in deleted file mode 100644 index f489908..0000000 --- a/buildrepo.in +++ /dev/null @@ -1,206 +0,0 @@ -#!/bin/sh - -program=${0##*/} - -aportsdir=${APORTSDIR:-$HOME/aports} -repodir=${REPODIR:-$HOME/packages} - -if [ -f /etc/abuild.conf ]; then - . /etc/abuild.conf -fi - -if [ -z "$CARCH" ]; then - machine=$(uname -m) - case $machine in - i[3-9]86) CARCH=x86;; - *) CARCH=$machine;; - esac -fi - -usage() { - echo "usage: $program [-a APORTSDIR] [-d REPODIR] [-hp] [-l LOGPREFIX ]" - echo " [-r DEPREPO] REPOSITORY..." - - echo "options:" - echo " -a Set the aports base dir to APORTSDIR instead of $aportsdir" - echo " -d Set destination repository base dir to REPODIR instead of $repodir" - echo " -h Show this help and exit" - echo " -l Send build to logfile, prefixed by LOGPREFIX" - echo " -k Keep going, even if packages fails" - echo " -p Purge obsolete packages from REPODIR after build" - echo " -r Dependencies are found in DEPREPO" - exit 1 -} - -is_in() { - local needle="$1" arg= - shift - for arg; do - [ "$needle" = "$arg" ] && return 0 - done - return 1 -} - -check_arch() { - [ "$1" = "all" ] || [ "$1" = "noarch" ] || is_in "$CARCH" $@ -} - -listpackages() { - local repo="$1" i= pkgname= pkgver= pkgrel= subpackage= arch= subpkg= linguas= - local lang= suffix= - cd "$aportsdir/$repo" - for i in */APKBUILD; do - cd "$aportsdir/$repo"/${i%/*} || return 1 - pkgname= - pkgver= - pkgrel=0 - subpackages= - arch= - linguas= - . ./APKBUILD - suffix="$pkgver-r$pkgrel.apk" - - if ! check_arch $arch; then - continue - fi - for subpkg in $pkgname $subpackages; do - echo ${subpkg%:*}-$suffix - done - for lang in $linguas; do - echo $pkgname-lang-$lang-$suffix - done - done -} - -all_exist() { - while [ $# -gt 0 ]; do - [ -e "$1" ] || return 1 - shift 1 - done - return 0 -} - -list_needbuild() { - local repo="$1" i= - - cd "$aportsdir/$repo" || return 0 - - # first we try copy everything possible and find out which we need - # to rebuild. By doing this we might save us for rebuilding - # needed when running 'abuild -R' - for apkbuild in */APKBUILD; do - [ -f "$aportsdir/$repo/$apkbuild" ] || continue - export REPODEST="$repodir" - cd "$aportsdir/$repo"/${apkbuild%/*} || return 1 - pkgname= - pkgver= - pkgrel=0 - subpackages= - arch= - . ./APKBUILD - - if ! check_arch $arch; then - continue - fi - - pkgs= - for subpkg in $pkgname $subpackages; do - pkgfile=${subpkg%:*}-$pkgver-r$pkgrel.apk - if ! [ -f "$REPODEST/$repo/$CARCH/$pkgfile" ]; then - pkgs="$pkgs $pkgfile" - fi - done - if [ -z "$pkgs" ]; then - continue - fi - - # try link or copy the files if they are in the ports dir - if all_exist $pkgs; then - echo ">>> Copying " $pkgs >&2 - cp -p -l $pkgs "$repodir/$repo/$CARCH"/ 2>/dev/null \ - || cp -p $pkgs "$repodir/$repo/$CARCH"/ \ - || echo "$apkbuild" - else - echo "$apkbuild" - fi - done -} - -do_build() { - local repo="$1" i= - cd "$aportsdir/$repo" || return 0 - local needbuild="$(list_needbuild $repo)" - - export REPODEST="$repodir" - export ABUILD_BLACKLIST - # build the postponed packages if any - if [ -n "$needbuild" ]; then - for i in $needbuild; do - cd "$aportsdir/$repo"/${i%/*} || return 1 - if ! abuild -k -R; then - [ -n "$keep_going" ] || return 1 - ABUILD_BLACKLIST="$ABUILD_BLACKLIST $i" - fi - done - fi - - # kill old packages in repo - if [ -n "$dopurge" ]; then - echo ">>> Removing old packages from $repo..." - local tmp=$(mktemp /tmp/$program-XXXXXX) - local purgefiles - cd "$repodir/$repo/$CARCH" || return 1 - trap 'rm -f "$tmp"; exit 1' INT - ( listpackages "$1") >$tmp || return 1 - purge=$(ls *.apk 2>/dev/null | grep -v -w -f $tmp) - if [ -n "$purge" ]; then - rm -f $purge - fi - rm -f "$tmp" - fi - - # generate the repository index - echo ">>> Generating Index for $repo..." - cd "$repodir/$repo/$CARCH" - local deps - for i in $deprepo; do - deps="--repo $repodir/$i" - done - oldindex= - if [ -f APKINDEX.tar.gz ]; then - oldindex="--index APKINDEX.tar.gz" - fi - tmpindex=$(mktemp).tar.gz - apk index --rewrite-arch $CARCH $oldindex -o $tmpindex \ - --description "$repo $(cd $aportsdir && git describe)" \ - -- *.apk - abuild-sign $tmpindex && mv $tmpindex APKINDEX.tar.gz - chmod 644 APKINDEX.tar.gz - rm -f tmp.* -} - -while getopts "a:d:hkl:pr:" opt; do - case "$opt" in - a) aportsdir=$OPTARG;; - d) repodir=$OPTARG;; - h) usage >&2;; - k) keep_going=1;; - l) logprefix=$OPTARG;; - p) dopurge=1;; - r) deprepo="$deprepo $OPTARG";; - esac -done -shift $(($OPTIND - 1)) - -[ $# -eq 0 ] && usage >&2 - -while [ $# -gt 0 ]; do - if [ -n "$logprefix" ]; then - do_build $1 >$logprefix.$1.log 2>&1 || exit 1 - else - do_build $1 || exit 1 - fi - deprepo="$deprepo $1" - shift -done - diff --git a/functions.sh.in b/functions.sh.in index 4bdda5d..e9b7280 100644 --- a/functions.sh.in +++ b/functions.sh.in @@ -17,8 +17,8 @@ hostspec_to_libc() { case "$1" in *-*-*-uclibc*) echo "uclibc" ;; *-*-*-musl*) echo "musl" ;; - *-*-*-gnu*) echo "eglibc" ;; - *) echo "uclibc" ;; + *-*-*-gnu*) echo "glibc" ;; + *) echo "unknown" ;; esac } diff --git a/newapkbuild.in b/newapkbuild.in index 952980f..d2951e4 100644 --- a/newapkbuild.in +++ b/newapkbuild.in @@ -52,6 +52,34 @@ build_autotools() { __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. + + sed -i -e 's/^\(makedepends="\)/\1cmake /' APKBUILD + cat >>APKBUILD<<__EOF__ + if [ "$CBUILD" != "$CHOST" ] + then + CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux" + fi + cmake \\ + -DCMAKE_INSTALL_PREFIX=/usr \\ + -DCMAKE_INSTALL_LIBDIR=lib \\ + -DBUILD_SHARED_LIBS=True \\ + -DCMAKE_BUILD_TYPE=Release \\ + -DCMAKE_CXX_COMPILER="\${CXX:-g++}" \\ + -DCMAKE_C_COMPILER="\${CC:-gcc}" \\ + -DCMAKE_CXX_FLAGS="\$CXXFLAGS" \\ + -DCMAKE_CXX_FLAGS="\$CFLAGS" \\ + ${CMAKE_CROSSOPTS} \\ + || return 1 + make || return 1 +__EOF__ +} + build_perl() { cat >>APKBUILD<<__EOF__ PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1 @@ -224,6 +252,8 @@ __EOF__ case "$buildtype" in make) build_make;; + cmake) + build_cmake;; autotools) build_autotools;; perl) @@ -281,6 +311,7 @@ Options: -l Set package license to LICENSE -u Set package URL -a Create autotools (use ./configure ...) + -C Create CMake pakckage (Assume cmake/ is there) -p Create perl package (Assume Makefile.PL is there) -y Create python package (Assume setup.py is there) -s Use sourceforge source URL @@ -295,6 +326,7 @@ while getopts "acd:fhl:n:pyu:s" opt; do case $opt in 'a') buildtype="autotools";; 'c') cpinitd=1;; + 'C') buildtype="cmake";; 'd') pkgdesc="$OPTARG";; 'f') force=1;; 'h') usage; exit;; |