Build script.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 10 Sep 2008 11:14:31 +0000 (12:14 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 10 Sep 2008 11:14:31 +0000 (12:14 +0100)
BUILD.pl [new file with mode: 0755]
README

diff --git a/BUILD.pl b/BUILD.pl
new file mode 100755 (executable)
index 0000000..5a65199
--- /dev/null
+++ b/BUILD.pl
@@ -0,0 +1,159 @@
+#!/usr/bin/perl -w
+#
+# Build Fedora MinGW spec files in correct order.
+# By Richard Jones <rjones@redhat.com>
+
+use strict;
+
+my $debug = 0;
+
+sub main {
+    my %br;
+    my $specfile;
+    my $packagename;
+
+    my @specfiles = <*/*.spec>;
+
+    # Get BRs for each specfile.
+    foreach $specfile (@specfiles) {
+       $packagename = $specfile;
+       $packagename =~ s{^.*/}{};
+       $packagename =~ s{\.spec$}{};
+
+       $br{$packagename} = [];
+
+       open SPEC,$specfile or die "$specfile: $!";
+       while (<SPEC>) {
+           if (m/^BuildRequires:(.*)/) {
+               my $brs = $1;
+               my @brs = eval 'split /,/, $brs';
+               @brs = map { trim ($_) } @brs;
+               @brs = map { remove_trailers ($_) } @brs;
+               unshift @{$br{$packagename}}, @brs;
+           }
+       }
+
+       if ($debug) {
+           print "BRs for $packagename = [";
+           print (join "],[", @{$br{$packagename}});
+           print "]\n";
+       }
+    }
+
+    foreach $packagename (keys %br) {
+       my @brs = @{$br{$packagename}};
+       @brs = uniq (sort @brs);
+       $br{$packagename} = \@brs;
+
+       if ($debug) {
+           print "uniq BRs for $packagename = [";
+           print (join "],[", @{$br{$packagename}});
+           print "]\n";
+       }
+    }
+
+    # Some packages we want to ignore for now.
+    delete $br{"mingw-cyrus-sasl"};
+    delete $br{"mingw-nsis"};
+    delete $br{"mingw-wix"};
+
+    # There is a dependency loop (gcc -> runtime/w32api -> gcc)
+    # which has to be manually resolved below.  Break that loop.
+    my @gcc_brs = @{$br{"mingw-gcc"}};
+    @gcc_brs = grep { $_ ne "mingw-runtime" && $_ ne "mingw-w32api" } @gcc_brs;
+    $br{"mingw-gcc"} = \@gcc_brs;
+
+    # Use tsort to generate a topological ordering.
+    open TSORT,">/tmp/tsort.tmp" or die "/tmp/tsort.tmp: $!";
+    foreach $packagename (keys %br) {
+       my $br;
+       foreach $br (@{$br{$packagename}}) {
+           print "writing $br $packagename\n" if $debug;
+           print TSORT $br, " ", $packagename, "\n";
+       }
+    }
+    close TSORT;
+
+    system ("tsort < /tmp/tsort.tmp > /tmp/tsort2.tmp") == 0
+       or die "system: tsort: $?";
+
+    # Read in list of packages.
+    open PACKAGES,"/tmp/tsort2.tmp" or die "/tmp/tsort2.tmp: $!";
+    unless ($debug) {
+       unlink "/tmp/tsort.tmp";
+       unlink "/tmp/tsort2.tmp";
+    }
+
+    while (<PACKAGES>) {
+       chomp;
+       if (/^mingw-(.*)/) {
+           $packagename = $_;
+           my $dirname = $1;
+
+           print "considering $packagename\n" if $debug;
+
+           my @brs = @{$br{$packagename}};
+
+           # Are all BR RPMs installed?
+           my $br;
+           foreach $br (@brs) {
+               if (! rpm_installed ($br)) {
+                   print "as root # rpm -Uvh $br*.rpm\n";
+               }
+           }
+
+           # Special case for mingw-gcc deps.
+           if ($packagename eq "mingw-gcc" &&
+               (!rpm_installed ("mingw-runtime") ||
+                !rpm_installed ("mingw-w32api"))) {
+               print "rpmbuild -ba bootstrap/mingw-bootstrap.spec\n";
+               print "as root # rpm -Uvh mingw-bootstrap*.rpm\n"
+           }
+
+           # Spec file.
+           my $specfile = "$dirname/$packagename.spec";
+           die "$specfile: file missing" unless -f $specfile;
+
+           print "rpmbuild -ba $specfile\n";
+       }
+    }
+}
+
+sub rpm_installed {
+    local $_ = shift;
+    return (system ("rpm -q $_ > /dev/null") == 0);
+}
+
+sub trim {
+    local $_ = shift;
+    s/^\s+//;
+    s/\s+$//;
+    return $_;
+}
+
+sub uniq {
+    my %hash;
+    local $_;
+
+    $hash{$_} = 1 foreach (@_);
+    return sort keys %hash;
+}
+
+# foo >= 3.1 --> foo
+# foo-devel --> foo
+# and a few other exceptions
+sub remove_trailers {
+    local $_ = shift;
+    s/\s*[<>=].*$//;
+
+    # -devel & -doc come from the base package.
+    s/-devel$//;
+    s/-doc$//;
+
+    # mingw-gcc-c++ etc.
+    s/^mingw-gcc-.*/mingw-gcc/;
+
+    return $_;
+}
+
+&main()
diff --git a/README b/README
index 6565930..f545bcd 100644 (file)
--- a/README
+++ b/README
@@ -8,6 +8,10 @@ Other useful information:
 
  * https://fedoraproject.org/wiki/SIGs/MinGW
 
+./BUILD.pl is a script which works out the correct order to build
+packages and will display the list of commands that you have to invoke
+to do this.
+
 Build order & package notes:
 
  ( 1) mingw-filesystem
@@ -40,21 +44,3 @@ Build order & package notes:
 
       Note that once built and installed, these last two replace the
       files built from binaries in mingw-bootstrap.
-
- ( 7) mingw-zlib
-
- ( 8) mingw-libgpg-error
-
- ( 9) mingw-libgcrypt
-
- (10) mingw-iconv
-
- (11) mingw-gettext
-
- (12) mingw-gnutls
-
- (13) mingw-libxml2
-
- (14) mingw-portablexdr
-
- (15) mingw-libvirt