#!/usr/bin/perl -w BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } use strict; use Build; use File::Basename; my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild); while (@ARGV) { if ($ARGV[0] eq '--dist') { shift @ARGV; $dist = shift @ARGV; next; } if ($ARGV[0] eq '--depfile') { shift @ARGV; $rpmdeps = shift @ARGV; next; } if ($ARGV[0] eq '--archpath') { shift @ARGV; $archs = shift @ARGV; next; } if ($ARGV[0] eq '--configdir') { shift @ARGV; $configdir = shift @ARGV; next; } if ($ARGV[0] eq '--useusedforbuild') { shift @ARGV; $useusedforbuild = 1; next; } if ($ARGV[0] eq '--define') { shift @ARGV; my $def = shift @ARGV; Build::define($def); next; } if ($ARGV[0] eq '--with') { shift @ARGV; my $def = shift @ARGV; Build::define("_with_$def --with-$def"); next; } if ($ARGV[0] eq '--without') { shift @ARGV; my $def = shift @ARGV; Build::define("_without_$def --without-$def"); next; } last; } $configdir = '.' unless defined $configdir; $archs = '' unless defined $archs; die("you must specfiy a depfile!\n") unless defined $rpmdeps; my @extradeps = grep {!/(^|\/)(?:PKGBUILD|_preinstallimage)$/ && !/\.(?:spec|dsc|kiwi)$/} @ARGV; my @specs = grep {/(^|\/)(?:PKGBUILD|_preinstallimage)$/ || /\.(?: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); if ($spec =~ /(^|\/)PKGBUILD$/) { push @archs, 'any' unless grep {$_ eq 'any'} @archs; } else { push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs; } my (%fn, %prov, %req); my %packs; my %repo; my %ids; my %packs_arch; my %packs_done; # XXX: move to separate tool if (!defined($dist) || $dist eq '') { my $rpmarch = (grep {$fn{"rpm.$_"}} @archs)[0]; if (!$rpmarch) { $dist = 'default'; } else { my $rpmfn = $fn{"rpm.$rpmarch"}; if ($rpmfn =~ /^[a-z]+:\/\//) { require File::Temp; my $tmpdir = File::Temp::tempdir('CLEANUP' => 1); $rpmfn =~ s/.*\//$tmpdir\// unless system("$INC[0]/download", $tmpdir, $rpmfn); } my $rpmdist = ''; if ($rpmfn =~ /^\// && -e $rpmfn) { my %res = Build::Rpm::rpmq($rpmfn, 1010); $rpmdist = $res{1010}->[0] || ''; } $dist = Build::dist_canon($rpmdist, $archs[0]); # need some extra work for sles11 :( if ($dist =~ /^sles11-/) { my %res = Build::Rpm::rpmq($rpmfn, 1049); $dist =~ s/^sles11-/sles11sp2-/ if grep {/^liblzma/} @{$res{1049} || []}; } } print STDERR "Warning: distribution not specified, assuming '$dist' (see $configdir).\n"; } my $cf = Build::read_config_dist($dist, $archs[0], $configdir); $cf->{'warnings'} = 1; my $dofileprovides = %{$cf->{'fileprovides'}}; my %exportfilters = %{$cf->{'exportfilter'}}; open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n"); # WARNING: the following code assumes that the 'I' tag comes last my ($pkgF, $pkgP, $pkgR); while() { chomp; if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) { my $pkgname = basename($2); $pkgF = $2; next if $fn{$1}; $fn{$1} = $2; my $pack = $1; $pack =~ /^(.*)\.([^\.]+)$/ or die; push @{$packs_arch{$2}}, $1; my $basename = $1; my $arch = $2; for(keys %exportfilters) { next if ($pkgname !~ /$_/); for (@{$exportfilters{$_}}) { my $a = $_; next if ($a eq "."); next if (! grep ($_ eq $a, @archs)); $packs{$basename} = "$basename.$arch" } } } elsif (/^P:(.*?)-\d+\/\d+\/\d+: (.*)$/) { $pkgP = $2; next if $prov{$1}; $prov{$1} = $2; } elsif (/^R:(.*?)-\d+\/\d+\/\d+: (.*)$/) { $pkgR = $2; next if $req{$1}; $req{$1} = $2; } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) { if ($ids{$1} && !$packs_done{$1} && defined($pkgF) && defined($pkgP) && defined($pkgR)) { my $i = $1; my $oldid = $ids{$1}; my $newid = $2; if (Build::Rpm::verscmp($oldid, $newid) < 0) { $ids{$i} = $newid; $fn{$i} = $pkgF; $prov{$i} = $pkgP; $req{$i} = $pkgR; } } else { next if $ids{$1}; $ids{$1} = $2; } undef $pkgF; undef $pkgP; undef $pkgR; } elsif ($_ eq 'D:') { %packs_done = %ids; } } close F; for my $arch (@archs) { $packs{$_} ||= "$_.$arch" for @{$packs_arch{$arch} || []}; } for my $pack (keys %packs) { my $r = {}; my (@s, $s, @pr, @re); @s = split(' ', $prov{$packs{$pack}} || ''); while (@s) { $s = shift @s; next if !$dofileprovides && $s =~ /^\//; if ($s =~ /^rpmlib\(/) { splice(@s, 0, 2); next; } push @pr, $s; splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/; } @s = split(' ', $req{$packs{$pack}} || ''); while (@s) { $s = shift @s; next if !$dofileprovides && $s =~ /^\//; if ($s =~ /^rpmlib\(/) { splice(@s, 0, 2); next; } push @re, $s; splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/; } $r->{'provides'} = \@pr; $r->{'requires'} = \@re; $repo{$pack} = $r; } ####################################################################### sub print_rpmlist { for (@_) { print "$_ $fn{$packs{$_}}\n"; print "rpmid: $_:$ids{$packs{$_}}\n" if exists $ids{$packs{$_}}; } print "preinstall: @{$cf->{'preinstall'} || []}\n"; print "vminstall: @{$cf->{'vminstall'} || []}\n"; print "runscripts: @{$cf->{'runscripts'} || []}\n"; print "dist: $dist\n" if defined $dist; } if ($useusedforbuild) { die("Need a specfile/dscfile for --usedforbuild\n") unless defined $spec; local *F; open(F, '<', $spec) || die("$spec: $!\n"); my @usedforbuild; my @buildrequires; while() { chomp; if (/^#\s*usedforbuild\s*(.*)$/) { push @usedforbuild, split(' ', $1); } if (/^buildrequires:\s*(.*)$/i) { push @buildrequires, split(' ', $1); } } close F; @usedforbuild = @buildrequires unless @usedforbuild; @usedforbuild = Build::unify(@usedforbuild) if @usedforbuild; my @errors; for (@usedforbuild) { push @errors, "package $_ not found" unless $packs{$_} && $fn{$packs{$_}}; } if (@errors) { print STDERR "expansion error\n"; print STDERR " $_\n" for @errors; exit(1); } print_rpmlist(@usedforbuild); exit(0); } ####################################################################### my ($packname, $packvers, $subpacks, @packdeps); $subpacks = []; if ($spec) { my $d; if ($spec =~ /\.kiwi$/) { # lets see if this is a product or image build $d = Build::parse($cf, $spec) || {}; my $type = $d->{'imagetype'} && $d->{'imagetype'}->[0] eq 'product' ? 'product' : 'image'; my @kdeps; if ($type eq 'image') { @kdeps = @{$cf->{'substitute'}->{'kiwi-setup:image'} || []}; @kdeps = ('kiwi', 'createrepo', 'tar') unless @kdeps; } else { @kdeps = @{$cf->{'substitute'}->{'kiwi-setup:product'} || []}; @kdeps = ('kiwi') unless @kdeps; } push @kdeps, grep {/^kiwi-.*:/} @{$d->{'deps'} || []}; $d = { 'deps' => \@kdeps, 'subpacks' => [] }; } else { $d = Build::parse($cf, $spec); } $packname = $d->{'name'}; $packvers = $d->{'version'}; $subpacks = $d->{'subpacks'}; @packdeps = @{$d->{'deps'} || []}; if ($d->{'prereqs'}) { my %deps = map {$_ => 1} (@packdeps, @{$d->{'subpacks'} || []}); push @packdeps, grep {!$deps{$_} && !/^%/} @{$d->{'prereqs'}}; } } Build::readdeps($cf, undef, \%repo); ####################################################################### my @bdeps = Build::get_build($cf, $subpacks, @packdeps, @extradeps); if (!shift @bdeps) { print STDERR "expansion error\n"; print STDERR " $_\n" for @bdeps; exit(1); } # make sure all preinstalls are in bdeps; # XXX: also add vmdeps? @bdeps = Build::unify(@bdeps, Build::get_preinstalls($cf)); print_rpmlist(@bdeps);