17 $do_rpm = 1 if $_ eq ':rpm';
18 $do_deb = 1 if $_ eq ':deb';
19 $do_kiwi = 1 if $_ eq ':kiwi';
20 $do_arch = 1 if $_ eq ':arch';
22 $do_rpm = $do_deb = $do_kiwi = $do_arch = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch;
34 package Build::Features;
35 our $preinstallimage = 1; # on sale now
40 %define ix86 i386 i486 i586 i686 athlon
41 %define arm armv4l armv5l armv6l armv7l armv4b armv5l armv5b armv5el armv5eb armv5tel armv5teb armv6el armv6eb armv7el armv7eb armv7hl armv7nhl armv8el
42 %define arml armv4l armv5l armv6l armv7l armv5tel armv5el armv6el armv7el armv7hl armv7nhl armv8el
43 %define armb armv4b armv5b armv5teb armv5eb armv6eb armv7eb
44 %define sparc sparc sparcv8 sparcv9 sparcv9v sparc64 sparc64v
46 my $extra_macros = '';
49 my %h = map {$_ => 1} @_;
50 return grep(delete($h{$_}), @_);
56 $extra_macros .= '%define '.$def."\n";
59 sub init_helper_hashes {
62 $config->{'preferh'} = { map {$_ => 1} @{$config->{'prefer'}} };
65 for (@{$config->{'ignore'}}) {
70 my @s = split(/[,:]/, $_);
72 $ignore{"$s:$_"} = 1 for @s;
74 $config->{'ignoreh'} = \%ignore;
77 for (@{$config->{'conflict'}}) {
78 my @s = split(/[,:]/, $_);
80 push @{$conflicts{$s}}, @s;
81 push @{$conflicts{$_}}, $s for @s;
83 for (keys %conflicts) {
84 $conflicts{$_} = [ unify(@{$conflicts{$_}}) ]
86 $config->{'conflicth'} = \%conflicts;
89 # 'canonicalize' dist string as found in rpm dist tags
91 my ($rpmdist, $arch) = @_;
92 $rpmdist = lc($rpmdist);
94 $rpmdist =~ s/opensuse/suse linux/;
96 if ($rpmdist =~ /\(/) {
98 $rpmdista =~ s/.*\(//;
99 $rpmdista =~ s/\).*//;
103 $rpmdista =~ s/i[456]86/i386/;
104 $rpmdist = '' unless $rpmdista =~ /^(i386|x86_64|ia64|ppc|ppc64|s390|s390x)$/;
105 my $dist = 'default';
106 if ($rpmdist =~ /unitedlinux 1\.0.*/) {
107 $dist = "ul1-$rpmdista";
108 } elsif ($rpmdist =~ /suse sles_(\d+)/) {
109 $dist = "sles$1-$rpmdista";
110 } elsif ($rpmdist =~ /suse linux enterprise (\d+)/) {
111 $dist = "sles$1-$rpmdista";
112 } elsif ($rpmdist =~ /suse linux (\d+)\.(\d+)\.[4-9]\d/) {
114 $dist = "$1.".($2 + 1)."-$rpmdista";
115 } elsif ($rpmdist =~ /suse linux (\d+\.\d+)/) {
116 $dist = "$1-$rpmdista";
121 sub read_config_dist {
122 my ($dist, $archpath, $configdir) = @_;
124 my $arch = $archpath;
125 $arch = 'noarch' unless defined $arch;
127 $arch = 'noarch' if $arch eq '';
128 die("Please specify a distribution!\n") unless defined $dist;
131 $configdir = '.' unless defined $configdir;
133 $dist = "sl$dist" if $dist =~ /^\d/;
134 $dist = "$configdir/$dist.conf";
137 $dist = "sl$dist" if $dist =~ /^\d/;
138 $dist = "$configdir/$dist.conf";
141 warn "$saved.conf not found, using default.conf\n" unless $saved eq 'default';
142 $dist = "$configdir/default.conf";
145 die("$dist: $!\n") unless -e $dist;
146 my $cf = read_config($arch, $dist);
147 die("$dist: parse error\n") unless $cf;
152 my ($arch, $cfile) = @_;
153 my @macros = split("\n", $std_macros.$extra_macros);
154 push @macros, "%define _target_cpu $arch";
155 push @macros, "%define _target_os linux";
156 my $config = {'macros' => \@macros, 'arch' => $arch};
160 } elsif (defined($cfile)) {
162 return undef unless open(CONF, '<', $cfile);
167 # create verbatim macro blobs
170 push @newconfig, shift @config;
171 next unless $newconfig[-1] =~ /^\s*macros:\s*$/si;
172 $newconfig[-1] = "macros:\n";
174 my $l = shift @config;
175 last if $l =~ /^\s*:macros\s*$/si;
176 $newconfig[-1] .= "$l\n";
180 $config->{'save_expanded'} = 1;
181 Build::Rpm::parse($config, \@newconfig, \@spec);
182 delete $config->{'save_expanded'};
183 $config->{'preinstall'} = [];
184 $config->{'vminstall'} = [];
185 $config->{'cbpreinstall'} = [];
186 $config->{'cbinstall'} = [];
187 $config->{'runscripts'} = [];
188 $config->{'required'} = [];
189 $config->{'support'} = [];
190 $config->{'keep'} = [];
191 $config->{'prefer'} = [];
192 $config->{'ignore'} = [];
193 $config->{'conflict'} = [];
194 $config->{'substitute'} = {};
195 $config->{'substitute_vers'} = {};
196 $config->{'optflags'} = {};
197 $config->{'order'} = {};
198 $config->{'exportfilter'} = {};
199 $config->{'publishfilter'} = [];
200 $config->{'rawmacros'} = '';
201 $config->{'release'} = '<CI_CNT>.<B_CNT>';
202 $config->{'repotype'} = [];
203 $config->{'patterntype'} = [];
204 $config->{'fileprovides'} = {};
205 $config->{'constraint'} = [];
207 $l = $l->[1] if ref $l;
208 next unless defined $l;
209 my @l = split(' ', $l);
213 if ($l0 eq 'macros:') {
216 $config->{'rawmacros'} = substr($l, 2);
218 $config->{'rawmacros'} .= $l;
222 if ($l0 eq 'preinstall:' || $l0 eq 'vminstall:' || $l0 eq 'cbpreinstall:' || $l0 eq 'cbinstall:' || $l0 eq 'required:' || $l0 eq 'support:' || $l0 eq 'keep:' || $l0 eq 'prefer:' || $l0 eq 'ignore:' || $l0 eq 'conflict:' || $l0 eq 'runscripts:') {
223 my $t = substr($l0, 0, -1);
227 } elsif ($l =~ /^!/) {
228 $config->{$t} = [ grep {"!$_" ne $l} @{$config->{$t}} ];
230 push @{$config->{$t}}, $l;
233 } elsif ($l0 eq 'substitute:') {
237 $config->{'substitute'} = {};
238 } elsif ($ll =~ /^!(.*)$/) {
239 delete $config->{'substitute'}->{$1};
241 $config->{'substitute'}->{$ll} = [ @l ];
243 } elsif ($l0 eq 'fileprovides:') {
247 $config->{'fileprovides'} = {};
248 } elsif ($ll =~ /^!(.*)$/) {
249 delete $config->{'fileprovides'}->{$1};
251 $config->{'fileprovides'}->{$ll} = [ @l ];
253 } elsif ($l0 eq 'exportfilter:') {
256 $config->{'exportfilter'}->{$ll} = [ @l ];
257 } elsif ($l0 eq 'publishfilter:') {
258 $config->{'publishfilter'} = [ @l ];
259 } elsif ($l0 eq 'optflags:') {
262 $config->{'optflags'}->{$ll} = join(' ', @l);
263 } elsif ($l0 eq 'order:') {
266 $config->{'order'} = {};
267 } elsif ($l =~ /^!(.*)$/) {
268 delete $config->{'order'}->{$1};
270 $config->{'order'}->{$l} = 1;
273 } elsif ($l0 eq 'repotype:') { #type of generated repository data
274 $config->{'repotype'} = [ @l ];
275 } elsif ($l0 eq 'type:') { #kind of packaging system (spec,dsc,arch,kiwi,...)
276 $config->{'type'} = $l[0];
277 } elsif ($l0 eq 'binarytype:') { #rpm,deb,arch,...
278 $config->{'binarytype'} = $l[0];
279 } elsif ($l0 eq 'patterntype:') { #kind of generated patterns in repository
280 $config->{'patterntype'} = [ @l ];
281 } elsif ($l0 eq 'release:') {
282 $config->{'release'} = $l[0];
283 } elsif ($l0 eq 'cicntstart:') {
284 $config->{'cicntstart'} = $l[0];
285 } elsif ($l0 eq 'releaseprg:') {
286 $config->{'releaseprg'} = $l[0];
287 } elsif ($l0 eq 'changetarget:' || $l0 eq 'target:') {
288 $config->{'target'} = join(' ', @l);
289 push @macros, "%define _target_cpu ".(split('-', $config->{'target'}))[0] if $config->{'target'};
290 } elsif ($l0 eq 'hostarch:') {
291 $config->{'hostarch'} = join(' ', @l);
292 } elsif ($l0 eq 'constraint:') {
293 my $l = join(' ', @l);
295 $config->{'constraint'} = [];
297 push @{$config->{'constraint'}}, $l;
299 } elsif ($l0 !~ /^[#%]/) {
300 warn("unknown keyword in config: $l0\n");
303 for my $l (qw{preinstall vminstall cbpreinstall cbinstall required support keep runscripts repotype patterntype}) {
304 $config->{$l} = [ unify(@{$config->{$l}}) ];
306 for my $l (keys %{$config->{'substitute'}}) {
307 $config->{'substitute_vers'}->{$l} = [ map {/^(.*?)(=)?$/g} unify(@{$config->{'substitute'}->{$l}}) ];
308 $config->{'substitute'}->{$l} = [ unify(@{$config->{'substitute'}->{$l}}) ];
309 s/=$// for @{$config->{'substitute'}->{$l}};
311 init_helper_hashes($config);
312 if (!$config->{'type'}) {
313 # Fallback to old guessing method if no type (spec, dsc or kiwi) is defined
314 if (grep {$_ eq 'rpm'} @{$config->{'preinstall'} || []}) {
315 $config->{'type'} = 'spec';
316 } elsif (grep {$_ eq 'debianutils'} @{$config->{'preinstall'} || []}) {
317 $config->{'type'} = 'dsc';
318 } elsif (grep {$_ eq 'pacman'} @{$config->{'preinstall'} || []}) {
319 $config->{'type'} = 'arch';
321 $config->{'type'} = 'UNDEFINED';
324 if (!$config->{'binarytype'}) {
325 $config->{'binarytype'} = 'rpm' if $config->{'type'} eq 'spec' || $config->{'type'} eq 'kiwi';
326 $config->{'binarytype'} = 'deb' if $config->{'type'} eq 'dsc';
327 $config->{'binarytype'} = 'arch' if $config->{'type'} eq 'arch';
328 $config->{'binarytype'} ||= 'UNDEFINED';
330 # add rawmacros to our macro list
331 if ($config->{'rawmacros'} ne '') {
332 for my $rm (split("\n", $config->{'rawmacros'})) {
333 if (@macros && $macros[-1] =~ /\\$/) {
335 push @macros, '...\\';
339 } elsif ($rm !~ /^%/) {
342 push @macros, "%define ".substr($rm, 1);
350 my ($config, @deps) = @_;
353 my $subst = $config->{'substitute'};
358 $ds =~ s/\s*[<=>].*$//s;
360 unshift @deps, @{$subst->{$ds}};
361 push @res, $d if grep {$_ eq $ds} @{$subst->{$ds}};
371 my ($config, @deps) = @_;
374 my $subst = $config->{'substitute_vers'};
376 my ($d, $dv) = splice(@deps, 0, 2);
379 unshift @deps, map {defined($_) && $_ eq '=' ? $dv : $_} @{$subst->{$d}};
380 push @res, $d, $dv if grep {defined($_) && $_ eq $d} @{$subst->{$d}};
389 # Delivers all packages which get used for building
391 my ($config, $subpacks, @deps) = @_;
392 my @ndeps = grep {/^-/} @deps;
393 my @support = @{$config->{'support'}};
394 if (@{$config->{'keep'} || []}) {
395 my %keep = map {$_ => 1} (@deps, @{$config->{'keep'} || []}, @{$config->{'preinstall'}});
396 for (@{$subpacks || []}) {
397 push @ndeps, "-$_" unless $keep{$_};
400 # new "empty keep" mode, filter subpacks from support
401 my %subpacks = map {$_ => 1} @{$subpacks || []};
402 @support = grep {!$subpacks{$_}} @support;
404 my %ndeps = map {$_ => 1} @ndeps;
405 @deps = grep {!$ndeps{$_}} @deps;
406 push @deps, @{$config->{'preinstall'}};
407 push @deps, @{$config->{'required'}};
408 push @deps, @support;
409 @deps = grep {!$ndeps{"-$_"}} @deps;
410 @deps = do_subst($config, @deps);
411 @deps = grep {!$ndeps{"-$_"}} @deps;
412 @deps = expand($config, @deps, @ndeps);
416 # Delivers all packages which shall have an influence to other package builds (get_build reduced by support packages)
418 my ($config, $subpacks, @deps) = @_;
419 my @ndeps = grep {/^-/} @deps;
420 my %keep = map {$_ => 1} (@deps, @{$config->{'keep'} || []}, @{$config->{'preinstall'}});
421 %keep = () unless @{$config->{'keep'} || []};
422 for (@{$subpacks || []}) {
423 push @ndeps, "-$_" unless $keep{$_};
425 my %ndeps = map {$_ => 1} @ndeps;
426 @deps = grep {!$ndeps{$_}} @deps;
427 push @deps, @{$config->{'required'}};
428 @deps = grep {!$ndeps{"-$_"}} @deps;
429 @deps = do_subst($config, @deps);
430 @deps = grep {!$ndeps{"-$_"}} @deps;
431 my %bdeps = map {$_ => 1} (@{$config->{'preinstall'}}, @{$config->{'support'}});
432 delete $bdeps{$_} for @deps;
433 @deps = expand($config, @deps, @ndeps);
434 if (@deps && $deps[0]) {
436 @deps = grep {!$bdeps{$_}} @deps;
442 sub get_preinstalls {
444 return @{$config->{'preinstall'}};
449 return @{$config->{'vminstall'}};
452 sub get_cbpreinstalls {
454 return @{$config->{'cbpreinstall'}};
459 return @{$config->{'cbinstall'}};
464 return @{$config->{'runscripts'}};
467 ###########################################################################
470 my ($config, $pkginfo, @depfiles) = @_;
475 my $dofileprovides = %{$config->{'fileprovides'}};
476 for my $depfile (@depfiles) {
477 if (ref($depfile) eq 'HASH') {
478 for my $rr (keys %$depfile) {
479 $provides{$rr} = $depfile->{$rr}->{'provides'};
480 $requires{$rr} = $depfile->{$rr}->{'requires'};
484 # XXX: we don't support different architectures per file
485 open(F, "<$depfile") || die("$depfile: $!\n");
487 my @s = split(' ', $_);
491 if (!$dofileprovides && $s[0] =~ /^\//) {
495 if ($s[0] =~ /^rpmlib\(/) {
501 if ($s[0] =~ /^[\(<=>|]/) {
502 $ss[-1] .= " $s[0] $s[1]";
503 $ss[-1] =~ s/ \((.*)\)/ $1/;
504 $ss[-1] =~ s/(<|>){2}/$1/;
512 @ss = grep {!$ss{$_}++} @ss;
513 if ($s =~ /^(P|R):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
517 $requires{$pkgid} = \@ss;
518 $pkginfo->{$pkgid}->{'requires'} = \@ss if $pkginfo;
522 $provides{$pkgid} = \@ss;
524 # extract ver and rel from self provides
525 my ($v, $r) = map { /\Q$pkgid\E = ([^-]+)(?:-(.+))?$/ } @ss;
526 die("$pkgid: no self provides\n") unless $v;
527 $pkginfo->{$pkgid}->{'name'} = $pkgid;
528 $pkginfo->{$pkgid}->{'version'} = $v;
529 $pkginfo->{$pkgid}->{'release'} = $r if defined($r);
530 $pkginfo->{$pkgid}->{'arch'} = $arch;
531 $pkginfo->{$pkgid}->{'provides'} = \@ss;
537 $config->{'providesh'} = \%provides;
538 $config->{'requiresh'} = \%requires;
539 makewhatprovidesh($config);
542 sub makewhatprovidesh {
546 my $provides = $config->{'providesh'};
548 for my $p (keys %$provides) {
549 my @pp = @{$provides->{$p}};
550 s/[ <=>].*// for @pp;
551 push @{$whatprovides{$_}}, $p for unify(@pp);
553 for my $p (keys %{$config->{'fileprovides'}}) {
554 my @pp = map {@{$whatprovides{$_} || []}} @{$config->{'fileprovides'}->{$p}};
555 @{$whatprovides{$p}} = unify(@{$whatprovides{$p} || []}, @pp) if @pp;
557 $config->{'whatprovidesh'} = \%whatprovides;
561 my ($config, $provides, $whatprovides, $requires) = @_;
562 $config->{'providesh'} = $provides;
563 $config->{'whatprovidesh'} = $whatprovides;
564 $config->{'requiresh'} = $requires;
569 delete $config->{'providesh'};
570 delete $config->{'whatprovidesh'};
571 delete $config->{'requiresh'};
574 my %addproviders_fm = (
583 my ($config, $r) = @_;
586 my $whatprovides = $config->{'whatprovidesh'};
587 $whatprovides->{$r} = \@p;
589 for my $or (split(/\s*\|\s*/, $r)) {
590 push @p, @{$whatprovides->{$or} || addproviders($config, $or)};
592 @p = unify(@p) if @p > 1;
595 return \@p if $r !~ /^(.*?)\s*([<=>]{1,2})\s*(.*?)$/;
598 my $rf = $addproviders_fm{$2};
599 return \@p unless $rf;
600 my $provides = $config->{'providesh'};
601 my @rp = @{$whatprovides->{$rn} || []};
603 for my $pp (@{$provides->{$rp} || []}) {
605 # debian: unversioned provides do not match
606 # kiwi: supports only rpm, so we need to hand it like it
607 next if $config->{'binarytype'} eq 'deb';
611 next unless $pp =~ /^\Q$rn\E\s*([<=>]{1,2})\s*(.*?)$/;
613 my $pf = $addproviders_fm{$1};
620 next unless $pf & $rf & 2;
624 my $rr = $rf == 2 ? $pf : ($rf ^ 5);
625 $rr &= 5 unless $pf & 2;
626 # verscmp for spec and kiwi types
628 if ($config->{'binarytype'} eq 'deb') {
629 $vv = Build::Deb::verscmp($pv, $rv, 1);
631 $vv = Build::Rpm::verscmp($pv, $rv, 1);
633 if ($rr & (1 << ($vv + 1))) {
639 @p = unify(@p) if @p > 1;
644 my ($config, @p) = @_;
646 my $conflicts = $config->{'conflicth'};
647 my $prefer = $config->{'preferh'};
648 my $ignore = $config->{'ignoreh'};
650 my $whatprovides = $config->{'whatprovidesh'};
651 my $requires = $config->{'requiresh'};
653 my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
654 @p = grep {!/^-/} @p;
656 my %p; # expanded packages
657 my %aconflicts; # packages we are conflicting with
659 # add direct dependency packages. this is different from below,
660 # because we add packages even if to dep is already provided and
661 # we break ambiguities if the name is an exact match.
662 for my $p (splice @p) {
663 my @q = @{$whatprovides->{$p} || addproviders($config, $p)};
667 @q = grep {$_ eq $pn} @q;
673 print "added $q[0] because of $p (direct dep)\n" if $expand_dbg;
676 $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []};
684 for my $p (splice @p) {
685 for my $r (@{$requires->{$p} || [$p]}) {
686 my $ri = (split(/[ <=>]/, $r, 2))[0];
687 next if $ignore->{"$p:$ri"} || $xignore{"$p:$ri"};
688 next if $ignore->{$ri} || $xignore{$ri};
689 my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
690 next if grep {$p{$_}} @q;
691 next if grep {$xignore{$_}} @q;
692 next if grep {$ignore->{"$p:$_"} || $xignore{"$p:$_"}} @q;
693 @q = grep {!$aconflicts{$_}} @q;
696 push @rerror, "nothing provides $r";
699 push @rerror, "nothing provides $r needed by $p";
703 if (@q > 1 && !$doamb) {
704 push @pamb, $p unless @pamb && $pamb[-1] eq $p;
705 print "undecided about $p:$r: @q\n" if $expand_dbg;
709 my @pq = grep {!$prefer->{"-$_"} && !$prefer->{"-$p:$_"}} @q;
711 @pq = grep {$prefer->{$_} || $prefer->{"$p:$_"}} @q;
713 my %pq = map {$_ => 1} @pq;
714 @q = (grep {$pq{$_}} @{$config->{'prefer'}})[0];
719 if (@q > 1 && $r =~ /\|/) {
720 # choice op, implicit prefer of first match...
721 my %pq = map {$_ => 1} @q;
722 for my $rr (split(/\s*\|\s*/, $r)) {
723 next unless $whatprovides->{$rr};
724 my @pq = grep {$pq{$_}} @{$whatprovides->{$rr}};
732 push @error, "have choice for $r needed by $p: @q";
734 push @error, "have choice for $r: @q";
736 push @pamb, $p unless @pamb && $pamb[-1] eq $p;
740 print "added $q[0] because of $p:$r\n" if $expand_dbg;
742 $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []};
747 return undef, @rerror if @rerror;
748 next if @p; # still work to do
750 # only ambig stuff left
751 if (@pamb && !$doamb) {
755 print "now doing undecided dependencies\n" if $expand_dbg;
758 return undef, @error if @error;
760 return 1, (sort keys %p);
764 my ($config, @p) = @_;
766 my $requires = $config->{'requiresh'};
767 my $whatprovides = $config->{'whatprovidesh'};
771 my %p = map {$_ => 1} @p;
774 for my $r (@{$requires->{$p} || []}) {
775 my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
776 push @r, grep {$_ ne $p && $p{$_}} @q;
778 if (%{$config->{'order'} || {}}) {
779 push @r, grep {$_ ne $p && $config->{'order'}->{"$_:$p"}} @p;
784 push @{$rdeps{$_}}, $p for @r;
786 @p = sort {$needed{$a} <=> $needed{$b} || $a cmp $b} @p;
791 @good = grep {$needed{$_} == 0} @p;
793 @p = grep {$needed{$_}} @p;
796 $needed{$_}-- for @{$rdeps{$p}};
800 # uh oh, cycle alert. find and remove all cycles.
801 my %notdone = map {$_ => 1} @p;
802 $notdone{$_} = 0 for @res; # already did those
807 $notdone{$$v} = 0; # finished this one
810 my $s = $notdone{$v};
812 my @e = grep {$notdone{$_}} @{$deps{$v}};
814 $notdone{$v} = 0; # all deps done, mark as finished
818 $notdone{$v} = 2; # now under investigation
819 unshift @todo, @e, \$v;
822 # reached visited package, found a cycle!
825 # go back till $v is reached again
831 $notdone{$v} = 1 if $notdone{$v} == 2;
835 unshift @todo, $cycv;
836 print STDERR "cycle: ".join(' -> ', @cyc)."\n";
838 my @breakv = (@cyc, $cyc[0]);
839 while (@breakv > 1) {
840 last if $config->{'order'}->{"$breakv[0]:$breakv[1]"};
844 $breakv = $breakv[0];
846 $breakv = (sort {$needed{$a} <=> $needed{$b} || $a cmp $b} @cyc)[-1];
848 push @cyc, $cyc[0]; # make it loop
849 shift @cyc while $cyc[0] ne $breakv;
851 print STDERR " breaking dependency $breakv -> $v\n";
852 $deps{$breakv} = [ grep {$_ ne $v} @{$deps{$breakv}} ];
853 $rdeps{$v} = [ grep {$_ ne $breakv} @{$rdeps{$v}} ];
860 sub add_all_providers {
861 my ($config, @p) = @_;
862 my $whatprovides = $config->{'whatprovidesh'};
863 my $requires = $config->{'requiresh'};
866 for my $r (@{$requires->{$p} || [$p]}) {
867 my $rn = (split(' ', $r, 2))[0];
868 $a{$_} = 1 for @{$whatprovides->{$rn} || []};
875 ###########################################################################
878 my ($conffile, $fn, $field, $arch) = @ARGV;
879 my $cf = read_config($arch, $conffile);
881 my $d = Build::parse($cf, $fn);
882 die("$d->{'error'}\n") if $d->{'error'};
883 $d->{'sources'} = [ map {ref($d->{$_}) ? @{$d->{$_}} : $d->{$_}} grep {/^source/} sort keys %$d ];
884 my $x = $d->{$field};
885 $x = [ $x ] unless ref $x;
886 print "$_\n" for @$x;
889 sub parse_preinstallimage {
890 return undef unless $do_rpm;
891 my $d = Build::Rpm::parse(@_);
892 $d->{'name'} ||= 'preinstallimage';
897 my ($cf, $fn, @args) = @_;
898 return Build::Rpm::parse($cf, $fn, @args) if $do_rpm && $fn =~ /\.spec$/;
899 return Build::Deb::parse($cf, $fn, @args) if $do_deb && $fn =~ /\.dsc$/;
900 return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /config\.xml$/;
901 return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /\.kiwi$/;
902 return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fn =~ /(^|\/|-)PKGBUILD$/;
903 return parse_preinstallimage($cf, $fn, @args) if $fn =~ /(^|\/|-)_preinstallimage$/;
908 my ($binname, %opts) = @_;
909 my $handle = $binname;
910 if (ref($binname) eq 'ARRAY') {
911 $handle = $binname->[1];
912 $binname = $binname->[0];
914 return Build::Rpm::query($handle, %opts) if $do_rpm && $binname =~ /\.rpm$/;
915 return Build::Deb::query($handle, %opts) if $do_deb && $binname =~ /\.deb$/;
916 return Build::Kiwi::queryiso($handle, %opts) if $do_kiwi && $binname =~ /\.iso$/;
917 return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
918 return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.arch$/;
924 return Build::Rpm::queryhdrmd5(@_) if $do_rpm && $binname =~ /\.rpm$/;
925 return Build::Deb::queryhdrmd5(@_) if $do_deb && $binname =~ /\.deb$/;
926 return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.iso$/;
927 return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw$/;
928 return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw.install$/;
929 return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
930 return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.arch$/;