- finished support for arch linux, sample config included
authorMichael Schroeder <mls@suse.de>
Mon, 2 Apr 2012 16:53:38 +0000 (18:53 +0200)
committerMichael Schroeder <mls@suse.de>
Mon, 2 Apr 2012 16:53:38 +0000 (18:53 +0200)
Build.pm
Build/Arch.pm
build
configs/arch.conf [new file with mode: 0644]
createarchdeps
createrepomddeps
expanddeps
init_buildsystem
order

index 7d56dbe..8e1c203 100644 (file)
--- a/Build.pm
+++ b/Build.pm
@@ -874,6 +874,7 @@ sub query {
   return Build::Deb::query($handle, %opts) if $do_deb && $binname =~ /\.deb$/;
   return Build::Kiwi::queryiso($handle, %opts) if $do_kiwi && $binname =~ /\.iso$/;
   return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
+  return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.arch$/;
   return undef;
 }
 
@@ -885,6 +886,7 @@ sub queryhdrmd5 {
   return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw$/;
   return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw.install$/;
   return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
+  return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.arch$/;
   return undef;
 }
 
index a00bd71..6387509 100644 (file)
@@ -63,12 +63,22 @@ sub parse {
   return $ret;
 }
 
+sub islzma {
+  my ($fn) = @_;
+  local *F;
+  return 0 unless open(F, '<', $fn);
+  my $h;
+  return 0 unless read(F, $h, 5) == 5;
+  close F;
+  return $h eq "\3757zXZ";
+}
+
 sub query {
   my ($handle, %opts) = @_;
   if (ref($handle)) {
     die("arch pkg query not implemented for file handles\n");
   }
-  if ($handle =~ /\.xz$/) {
+  if ($handle =~ /\.xz$/ || islzma($handle)) {
     my $nh;
     open($nh, '-|', 'xzdec', '-dc', $handle) || die("$handle: $!\n");
     $handle = $nh;
@@ -87,7 +97,7 @@ sub query {
   $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
   $ret->{'hdrmd5'} = Digest::MD5::md5_hex($pkginfo);
   $ret->{'provides'} = $vars{'provides'} || [];
-  $ret->{'requires'} = $vars{'depends'} || [];
+  $ret->{'requires'} = $vars{'depend'} || [];
   if ($vars{'pkgname'}) {
     my $selfprovides = $vars{'pkgname'}->[0];
     $selfprovides .= "=$vars{'pkgver'}->[0]" if $vars{'pkgver'};
@@ -119,7 +129,7 @@ sub queryhdrmd5 {
   if (ref($handle)) {
     die("arch pkg query not implemented for file handles\n");
   }
-  if ($handle =~ /\.xz$/) {
+  if ($handle =~ /\.xz$/ || islzma($handle)) {
     my $nh;
     open($nh, '-|', 'xzdec', '-dc', $handle) || die("$handle: $!\n");
     $handle = $nh;
diff --git a/build b/build
index 32ed525..5122d1e 100755 (executable)
--- a/build
+++ b/build
@@ -456,6 +456,9 @@ create_baselibs()
 
     BASELIBS_CFG=
 
+    if test "$BUILDTYPE" == "arch" ; then
+       return
+    fi
     if test "$BUILDTYPE" == "dsc" ; then
        pkgs=($DEBS)
     else # spec and kiwi
@@ -1346,6 +1349,7 @@ for SPECFILE in "${SPECFILES[@]}" ; do
       *.spec|*.src.rpm) BUILDTYPE=spec ;;
       *.dsc) BUILDTYPE=dsc ;;
       *.kiwi) BUILDTYPE=kiwi ;;
+      PKGBUILD) BUILDTYPE=arch ;;
     esac
     if test -z "$BUILDTYPE" ; then
        echo "don't know how to build $SPECFILE"
@@ -1668,6 +1672,9 @@ for SPECFILE in "${SPECFILES[@]}" ; do
                elif test "$BUILDTYPE" = dsc ; then
                    mkdir -p DEBS
                    find . -type f | while read i; do mv "$i" DEBS/; done
+               elif test "$BUILDTYPE" = arch ; then
+                   mkdir -p ARCHPKGS
+                   find . -type f | while read i; do mv "$i" ARCHPKGS/; done
                else
                    mkdir -p KIWI
                    find . -type f | while read i; do mv "$i" KIWI/; done
@@ -1943,6 +1950,12 @@ for SPECFILE in "${SPECFILES[@]}" ; do
        chroot $BUILD_ROOT su -c "dpkg-source -x $DEB_SOURCEDIR/$DEB_DSCFILE $TOPDIR/BUILD" - $BUILD_USER
     fi
 
+    if test "$BUILDTYPE" = arch ; then
+       echo "Preparing sources..."
+       chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && makepkg -s -o 2>&1 >/dev/null" - $BUILD_USER
+       mv $BUILD_ROOT/$TOPDIR/SOURCES/* -t $BUILD_ROOT/$TOPDIR/BUILD
+    fi
+
     chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
     cd $BUILD_ROOT$TOPDIR/SOURCES || cleanup_and_exit 1
 
@@ -2079,6 +2092,14 @@ for SPECFILE in "${SPECFILES[@]}" ; do
        done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE)
     fi
 
+    if test "$BUILDTYPE" = arch ; then
+       chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && makepkg -f" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
+       mkdir -p $BUILD_ROOT/$TOPDIR/ARCHPKGS
+       for PKG in $BUILD_ROOT/$TOPDIR/BUILD/*.pkg.tar.?z ; do
+           test -e "$PKG" && mv "$PKG" "$BUILD_ROOT/$TOPDIR/ARCHPKGS"
+       done
+    fi
+
     if test "$BUILDTYPE" = kiwi ; then
        . $BUILD_DIR/build_kiwi.sh
        run_kiwi
@@ -2190,6 +2211,9 @@ if test -n "$RUNNING_IN_VM" -a -n "$VM_SWAP"; then
        kiwi)
            computeblocklists $args $TOPDIR/KIWI/* $TOPDIR/OTHER/* > "$VM_SWAP"
            ;;
+       arch)
+           computeblocklists $args $TOPDIR/ARCHPKGS/* $TOPDIR/OTHER/* > "$VM_SWAP"
+           ;;
     esac || cleanup_and_exit 1
 fi
 
diff --git a/configs/arch.conf b/configs/arch.conf
new file mode 100644 (file)
index 0000000..d2202c3
--- /dev/null
@@ -0,0 +1,16 @@
+Repotype: arch
+
+Preinstall: glibc bash perl sed grep coreutils pacman pacman-mirrorlist
+Preinstall: gawk gzip filesystem curl acl gpgme libarchive
+Preinstall: openssl libssh2 zlib libassuan libgpg-error attr
+Preinstall: expat xz bzip2
+
+VMinstall: util-linux binutils
+
+Required: binutils gcc glibc libtool
+
+Support: acl autoconf automake zlib bzip2 filesystem curl
+Support: libtool ncurses perl gpgme libarchive openssl libssh2
+Support: libassuan libgpg-error attr expat xz pacman pacman-mirrorlist
+Support: fakeroot file sudo patch make
+
index 7964e2f..a97f762 100755 (executable)
@@ -11,6 +11,9 @@ use Archive::Tar;
 use Build::Arch;
 use Digest::MD5;
 use File::Path;
+use Getopt::Long;
+
+Getopt::Long::Configure("no_ignore_case");
 
 my $cachedir = "/var/cache/build";
 
@@ -39,13 +42,15 @@ sub printpkginfo {
   print "I:$id: $d->{name}-$d->{'version'} $d->{'buildtime'}\n";
 }
 
+GetOptions("cachedir=s"  => \$cachedir) or exit(1);
+
+
 for my $url (@ARGV) {
   die("Not an Archlinux repo") unless $url =~ /^(ht|f)tp:\/\/([^\/]*)\/?/;
-  $url .= '/' unless $url =~ /\/$/;
   my $reponame = getreponame($url);
-
-  my $repoid = Digest::MD5::md5_hex($url);
+  my $repoid = Digest::MD5::md5_hex("arch\@$url");
   my $dir = "$cachedir/$repoid";
+  $url .= '/' unless $url =~ /\/$/;
   getrepodb($url, $reponame, $dir);
 
   my $repodb = Archive::Tar->iter("$dir/$reponame.db", 1);
@@ -55,7 +60,7 @@ for my $url (@ARGV) {
   while ($e = $repodb->()) {
     next unless $e->type() == Archive::Tar::Constant::FILE;
     my $fn = $e->name();
-    next unless $fn =~ s/\/(?:depends|desc)$//s;
+    next unless $fn =~ s/\/(?:depends|desc|files)$//s;
     if ($lastfn ne $fn) {
       printpkginfo($d, $url) if $d->{'name'};
       $d = {};
index aaff8fb..5273c7b 100755 (executable)
@@ -403,7 +403,7 @@ for my $url (@ARGV) {
     $baseurl .= '/' unless $baseurl =~ /\/$/;
     getmetadata($baseurl, $dir);
   } elsif ($url =~ /^arch\@/) {
-    exec ($INC[0].'/createarchdeps', substr($url, 5));
+    exec ("$INC[0]/createarchdeps", "--cachedir=$cachedir", substr($url, 5));
   } else {
     $dir = $url;
     $dir .= '/' unless $dir =~ /\/$/;
index fc453e9..c0feb04 100755 (executable)
@@ -60,13 +60,17 @@ $configdir = '.' unless defined $configdir;
 $archs = '' unless defined $archs;
 die("you must specfiy a depfile!\n") unless defined $rpmdeps;
 
-my @extradeps = grep {!/\.(?:spec|dsc|kiwi)$/} @ARGV;
-my @specs = grep {/\.(?:spec|dsc|kiwi)$/} @ARGV;
+my @extradeps = grep {!/(^|\/)PKGBUILD$/ && !/\.(?:spec|dsc|kiwi)$/} @ARGV;
+my @specs = grep {/(^|\/)PKGBUILD$/ || /\.(?:spec|dsc|kiwi)$/} @ARGV;
 die("can only work with at most one spec\n") if @specs > 1;
 my $spec = $specs[0];
 
 my @archs = split(':', $archs);
-push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
+if ($spec =~ /(^|\/)PKGBUILD$/) {
+  push @archs, 'any' unless grep {$_ eq 'any'} @archs;
+} else {
+  push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
+}
 
 my (%fn, %prov, %req);
 
@@ -159,7 +163,7 @@ my $dofileprovides = %{$cf->{'fileprovides'}};
 for my $pack (keys %packs) {
   my $r = {};
   my (@s, $s, @pr, @re);
-  @s = split(' ', $prov{$packs{$pack}});
+  @s = split(' ', $prov{$packs{$pack}} || '');
   while (@s) {
     $s = shift @s;
     next if !$dofileprovides && $s =~ /^\//;
@@ -170,7 +174,7 @@ for my $pack (keys %packs) {
     push @pr, $s;
     splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/;
   }
-  @s = split(' ', $req{$packs{$pack}});
+  @s = split(' ', $req{$packs{$pack}} || '');
   while (@s) {
     $s = shift @s;
     next if !$dofileprovides && $s =~ /^\//;
index d3db5a5..d31a839 100755 (executable)
@@ -182,6 +182,13 @@ preinstall()
            test -e .init_b_cache/scripts/control/postinst && mv .init_b_cache/scripts/control/postinst ".init_b_cache/scripts/$1.post"
        fi
        rm -rf .init_b_cache/scripts/control control.tar.gz data.tar.gz
+    elif test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.arch" ; then
+       $TAR -z -f "$BUILD_ROOT/.init_b_cache/rpms/$1.arch"
+       if test -f .INSTALL ; then
+           cat .INSTALL > ".init_b_cache/scripts/$1.post"
+           echo 'type post_install >/dev/null 2>&1 && post_install' >> ".init_b_cache/scripts/$1.post"
+       fi
+       rm -f .PKGINFO .INSTALL
     else
        echo "warning: package $1 does not exist"
     fi
@@ -225,7 +232,7 @@ init_db()
        mkdir -p $BUILD_ROOT/root
        echo '%__dbi_perms perms=0644 nofsync' > $BUILD_ROOT/.rpmmacros
        echo '%__dbi_perms perms=0644 nofsync' > $BUILD_ROOT/root/.rpmmacros
-    else
+    elif test $PSUF = deb ; then
        # force dpkg into database to make epoch test work
        if ! test "$BUILD_ROOT/.init_b_cache/rpms/dpkg.deb" -ef "$BUILD_ROOT/.init_b_cache/dpkg.deb" ; then
            rm -f $BUILD_ROOT/.init_b_cache/dpkg.deb
@@ -330,6 +337,9 @@ validate_cache_file()
            elif [ "${SRC#http://}" != "$SRC" -o "${SRC#https://}" != "$SRC" -o "${SRC#ftp://}" != "$SRC" -o "${SRC#ftps://}" != "$SRC" ]; then
                mkdir -p "$(getcachedir "$SRC")"
                set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC"
+           elif [ "${SRC#arch@http://}" != "$SRC" -o "${SRC#arch@https://}" != "$SRC" -o "${SRC#arch@ftp://}" != "$SRC" -o "${SRC#arch@ftps://}" != "$SRC" ]; then
+               mkdir -p "$(getcachedir "$SRC")"
+               set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC"
            elif [ ! -e "$SRC" ]; then
                echo "*** $SRC does not exist" >&2
                cleanup_and_exit 1
@@ -456,6 +466,7 @@ downloadpkg()
     elif [ "${url:0:7}" == "http://" -o "${url:0:8}" == "https://" -o "${url:0:6}" == "ftp://" -o "${url:0:7}" == "ftps://" ] ; then
        cachedir="$(getcachedir "$url")"
        local name="$(basename "$url")"
+       name=${name/%pkg.tar.?z/arch}
        SRC="$cachedir/$name"
     else
        echo "Invalid url: $url"
@@ -472,12 +483,16 @@ downloadpkg()
            echo "expected $destfile after download but it's missing" >&2
            cleanup_and_exit 1
        fi
-       rpm -K "$destfile" > $destfile.v || { echo "rpm verify failed" >&2; rm -rf "$destdir"; cleanup_and_exit 1; }
-       if grep "NOT OK" $destfile.v; then
-           rm -rf "$destdir"
-           cleanup_and_exit 1
-       fi
-       rm -f "$destfile.v"
+       case $destfile in
+         *.rpm)
+           rpm -K "$destfile" > $destfile.v || { echo "rpm verify failed" >&2; rm -rf "$destdir"; cleanup_and_exit 1; }
+           if grep "NOT OK" $destfile.v; then
+               rm -rf "$destdir"
+               cleanup_and_exit 1
+           fi
+           rm -f "$destfile.v"
+           ;;
+       esac
        mv "$destfile" "$SRC" || cleanup_and_exit 1
     fi
 }
@@ -485,8 +500,11 @@ downloadpkg()
 getcachedir()
 {
     url=$1
+    case $url in
+      *.pkg.tar.?z) url="arch@$url" ;;
+    esac
     for repo in "${repos[@]}" ; do
-       if [ "${url:0:${#repo}}" == "$repo" ] ; then
+       if [ "${url:0:${#repo}}" == "$repo" -o "${url:0:${#repo}}" == "$repo" ] ; then
            read repoid dummy < <(echo -n "$repo" | md5sum)
            echo "$CACHE_DIR/$repoid"
            break
@@ -699,8 +717,14 @@ else
 
     echo "$GUESSED_DIST" > $BUILD_ROOT/.guessed_dist
     test -n "$BUILD_DIST" || BUILD_DIST="$GUESSED_DIST"
-    PSUF=rpm
-    test -L $BUILD_ROOT/.init_b_cache/rpms/rpm.rpm || PSUF=deb
+    PSUF=
+    test -L $BUILD_ROOT/.init_b_cache/rpms/rpm.rpm && PSUF=rpm
+    test -L $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb && PSUF=deb
+    test -L $BUILD_ROOT/.init_b_cache/rpms/pacman.arch && PSUF=arch
+    if test -z "$PSUF" ; then
+       echo "unknown package manager" >&2
+       cleanup_and_exit 1
+    fi
 fi
 
 #
@@ -747,7 +771,7 @@ if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rp
            test -c $BUILD_ROOT/dev/null || create_devs
     fi
     test -e $BUILD_ROOT/etc/fstab || touch $BUILD_ROOT/etc/fstab
-    test -e $BUILD_ROOT/etc/ld.so.conf || cp $BUILD_ROOT/etc/ld.so.conf.in $BUILD_ROOT/etc/ld.so.conf
+    test ! -e $BUILD_ROOT/etc/ld.so.conf -a -e $BUILD_ROOT/etc/ld.so.conf.in && cp $BUILD_ROOT/etc/ld.so.conf.in $BUILD_ROOT/etc/ld.so.conf
     if test -z "$PREPARE_VM" ; then
        run_pkg_scripts
        init_db
@@ -878,17 +902,16 @@ RPMCHECKOPTS_HOST=
 test -x $BUILD_ROOT/usr/bin/rpmsign && RPMCHECKOPTS="--nodigest --nosignature"
 test -x /usr/bin/rpmsign && RPMCHECKOPTS_HOST="--nodigest --nosignature"
 
-MAIN_LIST="$PACKAGES_TO_INSTALL_FIRST RUN_LDCONFIG $PACKAGES_TO_INSTALL $PACKAGES_TO_CBINSTALL"
+MAIN_LIST="$PACKAGES_TO_INSTALL_FIRST $PACKAGES_TO_INSTALL $PACKAGES_TO_CBINSTALL"
 progress_setup MAIN_LIST
 for PKG in $PACKAGES_TO_INSTALL_FIRST RUN_LDCONFIG $PACKAGES_TO_INSTALL $PACKAGES_TO_CBINSTALL; do
-    progress_step MAIN_LIST
-
     case $PKG in
       RUN_LDCONFIG)
        test -x $BUILD_ROOT/sbin/ldconfig && chroot $BUILD_ROOT /sbin/ldconfig 2>&1
        continue
       ;;
     esac
+    progress_step MAIN_LIST
 
     test -f $BUILD_ROOT/installed-pkg/$PKG && continue
 
@@ -920,6 +943,24 @@ for PKG in $PACKAGES_TO_INSTALL_FIRST RUN_LDCONFIG $PACKAGES_TO_INSTALL $PACKAGE
        continue
     fi
 
+    if test $PSUF = arch ; then
+       test -L $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF || continue
+        if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -ef "$BUILD_ROOT/.init_b_cache/$PKG.$PSUF" ; then 
+            rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF
+            cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1
+        fi
+        PKGID=`readlink $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF`
+        PKGID="${PKGID##*/}"
+        PKGID="${PKGID%.$PSUF}"
+        echo "installing ${PKGID%_*}"
+       # -d -d disables deps checking
+       ( chroot $BUILD_ROOT pacman -Uf -d -d --noconfirm .init_b_cache/$PKG.$PSUF 2>&1 || touch $BUILD_ROOT/exit ) | \
+           perl -ne '$|=1;/^(warning: could not get filesystem information for |loading packages|looking for inter-conflicts|Targets |Total Installed Size: |Net Upgrade Size: |Proceed with installation|checking package integrity|loading package files|checking available disk space|installing |upgrading |warning: database file for |warning:.*is up to date -- reinstalling|Optional dependencies for|    )/||/^$/||print'
+       check_exit
+        echo "$PKGID $PSUF" > $BUILD_ROOT/installed-pkg/$PKG
+       continue
+    fi
+
     test -L $BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm || continue
 
     if test -f $BUILD_ROOT/.init_b_cache/rpms/$PKG.id -a -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then
@@ -1080,6 +1121,7 @@ for DIR in /usr/share/doc/packages \
 done
 
 for FILE in /var/run/utmp /var/log/wtmp /etc/fstab ; do
+    mkdir -p $BUILD_ROOT/${FILE%/*}
     touch $BUILD_ROOT/$FILE
 done
 
diff --git a/order b/order
index 8e30670..17c483d 100755 (executable)
--- a/order
+++ b/order
@@ -59,7 +59,7 @@ my %bins;
 
 for my $p (@p) {
   my $q;
-  for my $suf ('rpm', 'deb') {
+  for my $suf ('rpm', 'deb', 'arch') {
     next unless -f "$cachedir/$p.$suf";
     $q = Build::query("$cachedir/$p.$suf", 'filelist' => 1, 'alldeps' => 1);
     die("bad binary: $p.$suf\n") unless $q;