3 ################################################################
5 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License version 2 or 3 as
9 # published by the Free Software Foundation.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program (see the file COPYING); if not, write to the
18 # Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 ################################################################
24 unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
32 my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild, $installonly, $noinstall, $usehigherdeps, $isvm);
34 $configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
37 if ($ARGV[0] eq '--dist') {
42 if ($ARGV[0] eq '--depfile') {
44 $rpmdeps = shift @ARGV;
47 if ($ARGV[0] eq '--archpath') {
52 if ($ARGV[0] eq '--configdir') {
54 $configdir = shift @ARGV;
57 if ($ARGV[0] eq '--useusedforbuild') {
62 if ($ARGV[0] eq '--define') {
64 my $def = shift @ARGV;
68 if ($ARGV[0] eq '--with') {
70 my $def = shift @ARGV;
71 Build::define("_with_$def --with-$def");
74 if ($ARGV[0] eq '--without') {
76 my $def = shift @ARGV;
77 Build::define("_without_$def --without-$def");
80 if ($ARGV[0] eq '--usehigherdeps') {
85 if ($ARGV[0] eq '--vm') {
93 $archs = '' unless defined $archs;
94 die("you must specfiy a depfile!\n") unless defined $rpmdeps;
96 # split args in recipe and pkgnames
100 my $buildtype = Build::recipe2buildtype($arg);
102 die("can only work with at most one recipe file\n") if defined $recipe;
105 push @extradeps, $arg;
110 my @archs = split(':', $archs);
111 if ($recipe =~ /(^|\/)PKGBUILD$/) {
112 push @archs, 'any' unless grep {$_ eq 'any'} @archs;
113 $binarytype = 'arch';
114 } elsif ($recipe =~ /\.dsc$/) {
115 push @archs, 'all' unless grep {$_ eq 'noarch'} @archs;
118 push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
122 # read dist if we can
124 if (defined($dist) && $dist ne '') {
125 $cf = Build::read_config_dist($dist, $archs[0], $configdir);
126 $binarytype = $cf->{'binarytype'} if $cf->{'binarytype'} && $cf->{'binarytype'} ne 'UNDEFINED';
129 my (%fn, %prov, %req, %con, %obs, %rec, %sup);
137 # XXX: move to separate tool
138 if (!defined($dist) || $dist eq '') {
139 my $rpmarch = (grep {$fn{"rpm.$_"}} @archs)[0];
143 my $rpmfn = $fn{"rpm.$rpmarch"};
144 if ($rpmfn =~ /^[a-z]+:\/\//) {
146 my $tmpdir = File::Temp::tempdir('CLEANUP' => 1);
147 $rpmfn =~ s/.*\//$tmpdir\// unless system("$INC[0]/download", $tmpdir, $rpmfn);
150 if ($rpmfn =~ /^\// && -e $rpmfn) {
151 my %res = Build::Rpm::rpmq($rpmfn, 1010);
152 $rpmdist = $res{1010}->[0] || '';
154 $dist = Build::dist_canon($rpmdist, $archs[0]);
155 # need some extra work for sles11 :(
156 if ($dist =~ /^sles11-/) {
157 my %res = Build::Rpm::rpmq($rpmfn, 1049);
158 $dist =~ s/^sles11-/sles11sp2-/ if grep {/^liblzma/} @{$res{1049} || []};
161 print STDERR "Warning: distribution not specified, assuming '$dist' (see $configdir).\n";
164 $cf ||= Build::read_config_dist($dist, $archs[0], $configdir);
165 $cf->{'warnings'} = 1;
167 my $dofileprovides = %{$cf->{'fileprovides'}};
168 $dofileprovides = 1 if ($binarytype || 'rpm') ne 'rpm';
169 my %exportfilters = %{$cf->{'exportfilter'}};
171 open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n");
172 # WARNING: the following code assumes that the 'I' tag comes last
173 my ($pkgF, $pkgP, $pkgR, $pkgC, $pkgO, $pkgr, $pkgs);
175 my $verscmp = \&Build::Rpm::verscmp;
177 if ($binarytype && $binarytype eq 'deb') {
178 $verscmp = \&Build::Deb::verscmp;
179 for my $arch (@archs) {
180 $arch = Build::Deb::basearch($arch) unless $arch =~ /^i[456]86$/;
186 if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
187 my $pkgname = basename($2);
192 $pack =~ /^(.*)\.([^\.]+)$/ or die;
193 push @{$packs_arch{$2}}, $1;
196 for(keys %exportfilters) {
197 next if ($pkgname !~ /$_/);
198 for (@{$exportfilters{$_}}) {
201 next if (! grep ($_ eq $a, @archs));
202 $packs{$basename} = "$basename.$arch"
205 } elsif (/^P:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
209 } elsif (/^R:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
213 } elsif (/^r:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
215 } elsif (/^C:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
219 } elsif (/^O:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
223 } elsif (/^r:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
225 } elsif (/^s:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
227 } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
229 if ($usehigherdeps) {
232 if ($packs_done{$1}) {
240 my ($i, $newid) = ($1, $2);
241 undef $i unless !$ids{$i} || $verscmp->($ids{$i}, $newid) < 0;
242 undef $i unless defined($pkgF) && defined($pkgP) && defined($pkgR);
244 $i =~ /^(.*)\.([^\.]+)$/ or die;
245 push @{$packs_arch{$2}}, $1;
256 $con{$i} = $pkgC if defined $pkgC;
257 $obs{$i} = $pkgO if defined $pkgO;
258 $rec{$i} = $pkgr if defined $pkgr;
259 $sup{$i} = $pkgs if defined $pkgs;
271 } elsif ($_ eq 'D:') {
277 for my $arch (@archs) {
278 $packs{$_} ||= "$_.$arch" for @{$packs_arch{$arch} || []};
281 for my $pack (keys %packs) {
283 my (@s, $s, @pr, @re, @co, @ob, @rc, @su);
284 @s = split(' ', $prov{$packs{$pack}} || '');
287 next if !$dofileprovides && $s =~ /^\//;
288 if ($s =~ /^rpmlib\(/) {
293 while (@s && $s[0] =~ /^[\(<=>|]/) {
294 $pr[-1] .= " $s[0] $s[1]";
295 $pr[-1] =~ s/ \((.*)\)/ $1/;
296 $pr[-1] =~ s/(<|>){2}/$1/;
300 @s = split(' ', $req{$packs{$pack}} || '');
303 next if !$dofileprovides && $s =~ /^\//;
304 if ($s =~ /^rpmlib\(/) {
309 while (@s && $s[0] =~ /^[\(<=>|]/) {
310 $re[-1] .= " $s[0] $s[1]";
311 $re[-1] =~ s/ \((.*)\)/ $1/;
312 $re[-1] =~ s/(<|>){2}/$1/;
316 @s = split(' ', $con{$packs{$pack}} || '');
319 next if !$dofileprovides && $s =~ /^\//;
321 while (@s && $s[0] =~ /^[\(<=>|]/) {
322 $co[-1] .= " $s[0] $s[1]";
323 $co[-1] =~ s/ \((.*)\)/ $1/;
324 $co[-1] =~ s/(<|>){2}/$1/;
328 @s = split(' ', $obs{$packs{$pack}} || '');
331 next if !$dofileprovides && $s =~ /^\//;
333 while (@s && $s[0] =~ /^[\(<=>|]/) {
334 $ob[-1] .= " $s[0] $s[1]";
335 $ob[-1] =~ s/ \((.*)\)/ $1/;
336 $ob[-1] =~ s/(<|>){2}/$1/;
340 @s = split(' ', $rec{$packs{$pack}} || '');
343 next if !$dofileprovides && $s =~ /^\//;
344 if ($s =~ /^rpmlib\(/) {
349 while (@s && $s[0] =~ /^[\(<=>|]/) {
350 $rc[-1] .= " $s[0] $s[1]";
351 $rc[-1] =~ s/ \((.*)\)/ $1/;
352 $rc[-1] =~ s/(<|>){2}/$1/;
356 @s = split(' ', $sup{$packs{$pack}} || '');
359 next if !$dofileprovides && $s =~ /^\//;
360 if ($s =~ /^rpmlib\(/) {
365 while (@s && $s[0] =~ /^[\(<=>|]/) {
366 $su[-1] .= " $s[0] $s[1]";
367 $su[-1] =~ s/ \((.*)\)/ $1/;
368 $su[-1] =~ s/(<|>){2}/$1/;
372 $r->{'provides'} = \@pr;
373 $r->{'requires'} = \@re;
374 $r->{'conflicts'} = \@co;
375 $r->{'obsoletes'} = \@ob;
376 $r->{'recommends'} = \@rc;
377 $r->{'supplements'} = \@su;
382 #######################################################################
386 print "$_ $fn{$packs{$_}}\n";
387 print "rpmid: $_:$ids{$packs{$_}}\n" if exists $ids{$packs{$_}};
389 print "preinstall: @{$cf->{'preinstall'} || []}\n";
390 print "vminstall: @{$cf->{'vminstall'} || []}\n";
391 print "runscripts: @{$cf->{'runscripts'} || []}\n";
392 print "dist: $dist\n" if defined $dist;
393 print "installonly: $installonly\n" if defined $installonly;
394 print "noinstall: $noinstall\n" if defined $noinstall;
397 if ($useusedforbuild) {
398 die("Need a recipe file for --usedforbuild\n") unless defined $recipe;
400 open(F, '<', $recipe) || die("$recipe: $!\n");
405 if (/^#\s*usedforbuild\s*(.*)$/) {
406 push @usedforbuild, split(' ', $1);
408 if (/^buildrequires:\s*(.*)$/i) {
409 push @buildrequires, split(' ', $1);
413 @usedforbuild = @buildrequires unless @usedforbuild;
414 @usedforbuild = Build::unify(@usedforbuild) if @usedforbuild;
416 for (@usedforbuild) {
417 push @errors, "package $_ not found" unless $packs{$_} && $fn{$packs{$_}};
420 print STDERR "expansion error\n";
421 print STDERR " $_\n" for @errors;
424 print_rpmlist(@usedforbuild);
428 #######################################################################
430 my ($packname, $packvers, $subpacks, @packdeps);
434 my $d = Build::parse($cf, $recipe) || {};
435 my $buildtype = Build::recipe2buildtype($recipe) || '';
436 $cf->{'type'} = $buildtype if $buildtype;
437 if ($buildtype eq 'kiwi') {
438 # lets see if this is a product or image build
439 my $type = $d->{'imagetype'} && $d->{'imagetype'}->[0] eq 'product' ? 'product' : 'image';
441 if ($type eq 'image') {
442 @kdeps = @{$cf->{'substitute'}->{'kiwi-setup:image'} || []};
443 @kdeps = ('kiwi', 'createrepo', 'tar') unless @kdeps;
445 @kdeps = @{$cf->{'substitute'}->{'kiwi-setup:product'} || []};
446 @kdeps = ('kiwi') unless @kdeps;
448 push @kdeps, grep {/^kiwi-.*:/} @{$d->{'deps'} || []};
449 $d = { 'deps' => \@kdeps, 'subpacks' => [] };
451 $packname = $d->{'name'};
452 $packvers = $d->{'version'};
453 $subpacks = $d->{'subpacks'};
454 @packdeps = @{$d->{'deps'} || []};
455 if ($d->{'prereqs'}) {
456 my %deps = map {$_ => 1} (@packdeps, @{$d->{'subpacks'} || []});
457 push @packdeps, grep {!$deps{$_} && !/^%/} @{$d->{'prereqs'}};
461 Build::readdeps($cf, undef, \%repo);
463 #######################################################################
466 push @packdeps, @{$cf->{'vminstall'}};
468 my @bdeps = Build::get_build($cf, $subpacks, @packdeps, @extradeps);
471 print STDERR "expansion error\n";
472 print STDERR " $_\n" for @bdeps;
476 my @sysdeps = Build::get_sysbuild($cf);
478 if (!shift @sysdeps) {
479 print STDERR "expansion error\n";
480 print STDERR " $_\n" for @sysdeps;
483 my %sysdeps = map {$_ => 1} @sysdeps;
484 my %bdeps = map {$_ => 1} @bdeps;
485 $installonly = join(' ', grep {!$bdeps{$_}} @sysdeps);
486 $noinstall = join(' ', grep {!$sysdeps{$_}} @bdeps);
487 @bdeps = Build::unify(@sysdeps, @bdeps);
490 # make sure all preinstalls are in bdeps;
491 # XXX: also add vmdeps?
492 @bdeps = Build::unify(@bdeps, Build::get_preinstalls($cf));
494 @bdeps = Build::unify(@bdeps, Build::get_vminstalls($cf));
497 print_rpmlist(@bdeps);