the dependencies to produce a correct build order.
Rewrite top-level scripts to use the new smock.
*.cmi
*.cmx
*.o
-buildall.log
+*.src.rpm
SDL/SDL-1.2.13.tar.gz
atk/atk-1.23.5.tar.bz2
Note that once built and installed, these last two replace the
files built from binaries in mingw32-{runtime,w32api}-bootstrap.
-
-Then for the rest, use ./show-build-order.pl which 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.
-
-(Note that show-build-order.pl doesn't actually build anything - it
-just prints suggested commands).
#!/bin/bash -
-DIST=fedora-9
-SKIP_BUILT_RPMS=1
-
-LOCALREPO=$HOME/public_html/smock/yum
-ARCHES="i386 x86_64"
-
-export DIST SKIP_BUILT_SRPMS LOCALREPO ARCHES
-
-specs=`perl show-build-order.pl |
- grep -v '^#' |
- grep -Eo '[^[:space:]]+/mingw32-[^[:space:]]+\.spec'`
-
-rm -f buildall.log
-echo -e "Specfiles in build order:\n$specs\n\n" >> buildall.log
-
-pwd=`pwd`
-
-for spec in $specs
-do
- set -e
- dir=`dirname $spec`
- srcrpm=`rpmbuild --define "_sourcedir $pwd/$dir" -bs $spec`
- if [ $? != 0 ]; then exit 1; fi
- srcrpm=`echo $srcrpm | awk '{print $2}'`
-
- # Test if all the output RPMs exist already.
- skip=
- if [ $SKIP_BUILT_RPMS ]; then
- skip=1
- baserpm=`basename $srcrpm | sed 's/\.fc[[:digit:]]*\.src\.rpm//g'`
- for arch in $ARCHES; do
- if [ ! -f $LOCALREPO/$DIST/$arch/RPMS/$baserpm.* ]; then
- skip=
- fi
- done
+# These are the packages we don't want to build yet:
+nobuild="example
+cyrus-sasl
+gdb
+pidgin
+python
+nspr
+nss
+ocaml-lablgl
+wix"
+
+rm -f */*.src.rpm
+
+for dir in *; do
+ if ! echo "$nobuild" | grep -sq "^$dir\$"; then
+ if [ -d $dir -a -f $dir/*.spec ]; then
+ (
+ cd $dir
+ rpmbuild -bs --define "_sourcedir $(pwd)" --define "_srcrpmdir $(pwd)" *.spec
+ )
+ fi
fi
+done
- if [ $skip ]; then
- echo "skipping $srcrpm"
- else
- smock/smock.sh $DIST $srcrpm
- fi
-done 2>&1 | tee -a buildall.log
+smock/smock.pl --arch=i386 --arch=x86_64 --distro=fedora-10 */*.src.rpm
+++ /dev/null
-#!/usr/bin/perl -w
-#
-# Show the order to build Fedora MinGW spec files.
-# By Richard Jones <rjones@redhat.com>
-
-use strict;
-
-my $debug = 0;
-chomp (my $pwd = `pwd`);
-
-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{"mingw32-cyrus-sasl"};
- delete $br{"mingw32-wix"};
- delete $br{"mingw32-example"};
- delete $br{"mingw32-gdb"};
- delete $br{"mingw32-python"};
- delete $br{"mingw32-pidgin"};
- delete $br{"mingw32-nspr"};
- delete $br{"mingw32-nss"};
- delete $br{"mingw32-ocaml-lablgl"};
-
- # There is a dependency loop (gcc -> runtime/w32api -> gcc)
- # which has to be manually resolved below. Break that loop.
- my @gcc_brs = @{$br{"mingw32-gcc"}};
- @gcc_brs = grep { $_ ne "mingw32-runtime" && $_ ne "mingw32-w32api" } @gcc_brs;
- $br{"mingw32-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";
- }
-
- my %installed;
-
- while (<PACKAGES>) {
- chomp;
- if (/^mingw32-(.*)/ && exists $br{$_}) {
- $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) && !exists $installed{$br}) {
- print "# as root: rpm -Uvh $br*.rpm\n";
- $installed{$br} = 1;
- }
- }
-
- # Special case for mingw32-gcc deps.
- if ($packagename eq "mingw32-gcc" &&
- (!rpm_installed ("mingw32-runtime") ||
- !rpm_installed ("mingw32-w32api"))) {
- print "rpmbuild -ba --define \"_sourcedir $pwd/runtime-bootstrap\" runtime-bootstrap/mingw32-runtime-bootstrap.spec\n";
- print "# as root: rpm -Uvh mingw32-runtime-bootstrap*.rpm\n";
- $installed{"mingw32-runtime-bootstrap"} = 1;
-
- print "rpmbuild -ba --define \"_sourcedir $pwd/w32api-bootstrap\" w32api-bootstrap/mingw32-w32api-bootstrap.spec\n";
- print "# as root: rpm -Uvh mingw32-w32api-bootstrap*.rpm\n";
- $installed{"mingw32-w32api-bootstrap"} = 1;
- }
-
- # Spec file.
- my $specfile = "$dirname/$packagename.spec";
- die "$specfile: file missing" unless -f $specfile;
-
- my $rpmbuild =
- "rpmbuild -ba --define \"_sourcedir $pwd/$dirname\"";
- print "$rpmbuild $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$//;
-
- # mingw32-gcc-c++ etc.
- s/^mingw32-gcc-.*/mingw32-gcc/;
-
- return $_;
-}
-
-&main()
SMOCK - Simpler Mock
====================
+by Dan Berrange and Richard W.M. Jones.
Smock is a thin wrapper around mock to let you build up a whole
set of dependant RPMs against an external distro.
Now you can run
- ./smock.sh fedora-9 /path/to/srpm
+ ./smock.pl --arch=i386 --arch=x86_64 --distro=fedora-9 list of srpms
-And it'll build the RPM against the fedora-9-XXX distro for each 'XXX'
-arch you listed.
+And it'll build the all the SRPMs listed on the command line, using
+previously built SRPMs as dependencies for later ones. You don't need
+to list them in the proper order - the build order is worked out using
+the dependencies.
The resulting src RPMs, binary RPMs and build logs wil be put into
$HOME/public_html/smock, and a Yum repo created. Further RPMs you
--- /dev/null
+#!/usr/bin/perl -w
+#
+# SMOCK - Simpler Mock
+# by Dan Berrange and Richard W.M. Jones.
+
+use strict;
+
+use Getopt::Long;
+use Pod::Usage;
+use File::Temp qw(tempfile);
+
+my @arches = ();
+my @distros = ();
+my $localrepo = $ENV{HOME} . "/public_html/smock/yum";
+my $help = 0;
+my $man = 0;
+
+GetOptions (
+ "arch=s" => \@arches,
+ "distro=s" => \@distros,
+ "localrepo=s" => \$localrepo,
+ "help|?" => \$help,
+ "man" => \$man
+ ) or pod2usage (2);
+pod2usage (1) if $help;
+pod2usage (-exitstatus => 0, -verbose => 2) if $man;
+
+=pod
+
+=head1 NAME
+
+ smock - Simpler mock
+
+=head1 SYNOPSIS
+
+ smock.pl --arch=i386 --arch=x86_64 --distro=fedora-10 list of SRPMs ...
+
+=head1 DESCRIPTION
+
+This is a wrapper around I<mock> which lets you build a whole group of
+mutually dependent SRPMs in one go.
+
+The smock command will work out the correct order in which to build
+the SRPMs, and makes the result of previous RPM builds available as
+dependencies for later builds.
+
+Smock also works incrementally. It won't rebuild RPMs which were
+built already in a previous run, which means if a package fails to
+build, you can just fix it and rerun the same smock command. (In the
+unlikely case that you want to force smock to rebuild RPMs then you
+must bump the release number or delete the binary RPM from the
+localrepo directory).
+
+B<NOTE:> Please read the README file first. You need to set up mock
+and a web server before you can use this command.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--arch>
+
+Specify the architecture(s) to build, eg. i386, x86_64. You can
+list this option several times to build several architectures.
+
+=item B<--distro>
+
+Specify the distribution(s) to build, eg. fedora-9, fedora-10.
+You can list this option several times to build several distributions.
+
+=item B<--localrepo>
+
+Local repository. Defaults to C<$HOME/public_html/smock/yum>
+
+=back
+
+=cut
+
+my @srpms = @ARGV;
+
+if (0 == @arches) {
+ die "smock: specify one or more architectures using --arch=<arch>\n"
+}
+
+if (0 == @distros) {
+ die "smock: specify one or more distros using --distro=<distro>\n"
+}
+
+if (0 == @srpms) {
+ die "smock: specify one or more SRPMs to build on the command line\n"
+}
+
+# Resolve the names, dependency list, etc. of the SRPMs that were
+# specified.
+
+sub get_one_line
+{
+ open PIPE, "$_[0] |" or die "$_[0]: $!";
+ my $line = <PIPE>;
+ chomp $line;
+ close PIPE;
+ return $line;
+}
+
+sub get_lines
+{
+ local $_;
+ open PIPE, "$_[0] |" or die "$_[0]: $!";
+ my @lines;
+ foreach (<PIPE>) {
+ chomp;
+ push @lines, $_;
+ }
+ close PIPE;
+ return @lines;
+}
+
+my %srpms = ();
+foreach my $srpm (@srpms) {
+ my $name = get_one_line "rpm -q --qf '%{name}' -p '$srpm'";
+ my $version = get_one_line "rpm -q --qf '%{version}' -p '$srpm'";
+ my $release = get_one_line "rpm -q --qf '%{release}' -p '$srpm'";
+
+ my @buildrequires = get_lines "rpm -q --requires -p '$srpm' |
+ grep -Eo '^[^[:space:]]+'";
+
+ #print "Filename: $srpm\n";
+ #print " name = $name\n";
+ #print " version = $version\n";
+ #print " release = $release\n";
+ #print " buildrequires = ", join (",", @buildrequires), "\n";
+
+ $srpms{$name} = {
+ name => $name,
+ version => $version,
+ release => $release,
+ buildrequires => \@buildrequires,
+ filename => $srpm
+ }
+}
+
+# We don't care about buildrequires unless they refer to other
+# packages that we are building. So filter them on this condition.
+
+sub is_member_of
+{
+ my $item = shift;
+
+ foreach (@_) {
+ return 1 if $item eq $_;
+ }
+ 0;
+}
+
+my @names = keys %srpms;
+foreach my $name (@names) {
+ my @buildrequires = @{$srpms{$name}->{buildrequires}};
+ @buildrequires = grep { is_member_of ($_, @names) } @buildrequires;
+ $srpms{$name}{buildrequires} = \@buildrequires;
+}
+
+# Now sort the SRPMs into the correct order for building
+
+my ($fh, $filename) = tempfile ();
+
+foreach my $name (@names) {
+ my @buildrequires = @{$srpms{$name}->{buildrequires}};
+ foreach (@buildrequires) {
+ print $fh "$_ $name\n"
+ }
+}
+close $fh;
+
+my @buildorder = get_lines "tsort $filename";
+
+#foreach (@buildorder) {
+# print "$_\n";
+#}
+
+# Now we can build each SRPM.
+
+sub my_mkdir
+{
+ local $_ = $_[0];
+
+ if (! -d $_) {
+ mkdir ($_, 0755) or die "mkdir $_: $!"
+ }
+}
+
+sub createrepo
+{
+ my $arch = shift;
+ my $distro = shift;
+
+ my_mkdir "$localrepo/$distro";
+ my_mkdir "$localrepo/$distro/src";
+ my_mkdir "$localrepo/$distro/src/SRPMS";
+ system ("cd $localrepo/$distro/src && rm -rf repodata && createrepo -q .") == 0
+ or die "createrepo failed: $?\n";
+
+ my_mkdir "$localrepo/$distro/$arch";
+ my_mkdir "$localrepo/$distro/$arch/RPMS";
+ my_mkdir "$localrepo/$distro/$arch/logs";
+
+ system ("cd $localrepo/$distro/$arch && rm -rf repodata && createrepo -q --exclude 'logs/*rpm' .") == 0
+ or die "createrepo failed: $?\n";
+}
+
+if (! -d "$localrepo/scratch") {
+ mkdir "$localrepo/scratch"
+ or die "mkdir $localrepo/scratch: $!\nIf you haven't set up a local repository yet, you must read the README file.\n";
+}
+
+system "rm -f $localrepo/scratch/*";
+
+foreach my $name (@buildorder) {
+ my $version = $srpms{$name}->{version};
+ my $release = $srpms{$name}->{release};
+ my $srpm_filename = $srpms{$name}->{filename};
+
+ $release =~ s/\.fc?\d+$//; # "1.fc9" -> "1"
+
+ foreach my $arch (@arches) {
+ foreach my $distro (@distros) {
+ # Does the built (binary) package exist already?
+ my $pattern = "$localrepo/$distro/$arch/RPMS/$name-$version-$release.*.rpm";
+ #print "pattern = $pattern\n";
+ my @binaries = glob $pattern;
+
+ if (@binaries == 0)
+ {
+ # Rebuild the package.
+ print "*** building $name-$version-$release $arch $distro ***\n";
+
+ createrepo ($arch, $distro);
+ system ("mock -r $distro-$arch --resultdir $localrepo/scratch $srpm_filename") == 0
+ or die "Build failed, return code $?\nLeaving the logs in $localrepo/scratch\n";
+
+ # Build was a success so move the final RPMs into the
+ # mock repo for next time.
+ system ("mv $localrepo/scratch/*.src.rpm $localrepo/$distro/src/SRPMS") == 0 or die "mv";
+ system ("mv $localrepo/scratch/*.rpm $localrepo/$distro/$arch/RPMS") == 0 or die "mv";
+ my_mkdir "$localrepo/$distro/$arch/logs/$name-$version-$release";
+ system ("mv $localrepo/scratch/*.log $localrepo/$distro/$arch/logs/$name-$version-$release/") == 0 or die "mv";
+
+ createrepo ($arch, $distro);
+ }
+ else
+ {
+ print "skipping $name-$version-$release $arch $distro\n";
+ }
+ }
+ }
+}
+++ /dev/null
-#!/bin/sh
-
-if [ -z "$LOCALREPO" -o -z "$ARCHES" ]; then
- echo '$LOCALREPO must point to local repository'
- echo '$ARCHES must contain list of architectures to build'
- exit 1
-fi
-
-help() {
- echo "syntax: $0 DIST SRPM"
-}
-
-if [ -z "$1" ]; then
- help
- exit
-fi
-
-
-if [ -z "$2" ]; then
- help
- exit
-fi
-
-DIST=$1
-SRPM=$2
-
-createrepos() {
-
- (
- mkdir -p $LOCALREPO/$DIST/src/SRPMS
- cd $LOCALREPO/$DIST/src
- rm -rf repodata
- createrepo .
- )
-
- for ARCH in $ARCHES
- do
- (
- mkdir -p $LOCALREPO/$DIST/$ARCH/RPMS
- mkdir -p $LOCALREPO/$DIST/$ARCH/logs
- cd $LOCALREPO/$DIST/$ARCH
- rm -rf repodata
- createrepo --exclude "logs/*rpm" .
- )
- done
-}
-
-createrepos
-
-mkdir -p $LOCALREPO/scratch
-rm -f $LOCALREPO/scratch/*
-
-for ARCH in $ARCHES
-do
- mkdir -p $LOCALREPO/$DIST/$ARCH/logs/$SRPM
-
- mock -r $DIST-$ARCH --resultdir $LOCALREPO/scratch $SRPM
-
- if [ $? != 0 ]; then
- echo "Build failed, leaving logs in $LOCALREPO/scratch"
- exit 1
- fi
- mv $LOCALREPO/scratch/*.src.rpm $LOCALREPO/$DIST/src/SRPMS
- mv $LOCALREPO/scratch/*.rpm $LOCALREPO/$DIST/$ARCH/RPMS
- mv $LOCALREPO/scratch/*.log $LOCALREPO/$DIST/$ARCH/logs/$SRPM/
-done
-
-createrepos
-