- Need to run autoreconf after patching src/Makefile.am.
[fedora-mingw.git] / BUILD.pl
1 #!/usr/bin/perl -w
2 #
3 # Build Fedora MinGW spec files in correct order.
4 # By Richard Jones <rjones@redhat.com>
5
6 use strict;
7
8 my $debug = 0;
9
10 sub main {
11     my %br;
12     my $specfile;
13     my $packagename;
14
15     my @specfiles = <*/*.spec>;
16
17     # Get BRs for each specfile.
18     foreach $specfile (@specfiles) {
19         $packagename = $specfile;
20         $packagename =~ s{^.*/}{};
21         $packagename =~ s{\.spec$}{};
22
23         $br{$packagename} = [];
24
25         open SPEC,$specfile or die "$specfile: $!";
26         while (<SPEC>) {
27             if (m/^BuildRequires:(.*)/) {
28                 my $brs = $1;
29                 my @brs = eval 'split /,/, $brs';
30                 @brs = map { trim ($_) } @brs;
31                 @brs = map { remove_trailers ($_) } @brs;
32                 unshift @{$br{$packagename}}, @brs;
33             }
34         }
35
36         if ($debug) {
37             print "BRs for $packagename = [";
38             print (join "],[", @{$br{$packagename}});
39             print "]\n";
40         }
41     }
42
43     foreach $packagename (keys %br) {
44         my @brs = @{$br{$packagename}};
45         @brs = uniq (sort @brs);
46         $br{$packagename} = \@brs;
47
48         if ($debug) {
49             print "uniq BRs for $packagename = [";
50             print (join "],[", @{$br{$packagename}});
51             print "]\n";
52         }
53     }
54
55     # Some packages we want to ignore for now.
56     delete $br{"mingw-cyrus-sasl"};
57     delete $br{"mingw-nsis"};
58     delete $br{"mingw-wix"};
59     delete $br{"mingw-example"};
60
61     # There is a dependency loop (gcc -> runtime/w32api -> gcc)
62     # which has to be manually resolved below.  Break that loop.
63     my @gcc_brs = @{$br{"mingw-gcc"}};
64     @gcc_brs = grep { $_ ne "mingw-runtime" && $_ ne "mingw-w32api" } @gcc_brs;
65     $br{"mingw-gcc"} = \@gcc_brs;
66
67     # Use tsort to generate a topological ordering.
68     open TSORT,">/tmp/tsort.tmp" or die "/tmp/tsort.tmp: $!";
69     foreach $packagename (keys %br) {
70         my $br;
71         foreach $br (@{$br{$packagename}}) {
72             print "writing $br $packagename\n" if $debug;
73             print TSORT $br, " ", $packagename, "\n";
74         }
75     }
76     close TSORT;
77
78     system ("tsort < /tmp/tsort.tmp > /tmp/tsort2.tmp") == 0
79         or die "system: tsort: $?";
80
81     # Read in list of packages.
82     open PACKAGES,"/tmp/tsort2.tmp" or die "/tmp/tsort2.tmp: $!";
83     unless ($debug) {
84         unlink "/tmp/tsort.tmp";
85         unlink "/tmp/tsort2.tmp";
86     }
87
88     my %installed;
89
90     while (<PACKAGES>) {
91         chomp;
92         if (/^mingw-(.*)/) {
93             $packagename = $_;
94             my $dirname = $1;
95
96             print "considering $packagename\n" if $debug;
97
98             my @brs = @{$br{$packagename}};
99
100             # Are all BR RPMs installed?
101             my $br;
102             foreach $br (@brs) {
103                 if (! rpm_installed ($br) && !exists $installed{$br}) {
104                     print "as root # rpm -Uvh $br*.rpm\n";
105                     $installed{$br} = 1;
106                 }
107             }
108
109             # Special case for mingw-gcc deps.
110             if ($packagename eq "mingw-gcc" &&
111                 (!rpm_installed ("mingw-runtime") ||
112                  !rpm_installed ("mingw-w32api"))) {
113                 print "rpmbuild -ba bootstrap/mingw-bootstrap.spec\n";
114                 print "as root # rpm -Uvh mingw-bootstrap*.rpm\n";
115                 $installed{"mingw-bootstrap"} = 1;
116             }
117
118             # Spec file.
119             my $specfile = "$dirname/$packagename.spec";
120             die "$specfile: file missing" unless -f $specfile;
121
122             print "rpmbuild -ba $specfile\n";
123         }
124     }
125 }
126
127 sub rpm_installed {
128     local $_ = shift;
129     return (system ("rpm -q $_ > /dev/null") == 0);
130 }
131
132 sub trim {
133     local $_ = shift;
134     s/^\s+//;
135     s/\s+$//;
136     return $_;
137 }
138
139 sub uniq {
140     my %hash;
141     local $_;
142
143     $hash{$_} = 1 foreach (@_);
144     return sort keys %hash;
145 }
146
147 # foo >= 3.1 --> foo
148 # foo-devel --> foo
149 # and a few other exceptions
150 sub remove_trailers {
151     local $_ = shift;
152     s/\s*[<>=].*$//;
153
154     # -devel & -doc come from the base package.
155     s/-devel$//;
156     s/-doc$//;
157
158     # mingw-gcc-c++ etc.
159     s/^mingw-gcc-.*/mingw-gcc/;
160
161     return $_;
162 }
163
164 &main()