Also recored supplements, use recommends as choice breaker only in 3rd pass.
authorMichael Schroeder <mls@suse.de>
Mon, 28 Nov 2016 12:59:20 +0000 (13:59 +0100)
committeryang.zhang <y0169.zhang@samsung.com>
Tue, 7 Mar 2017 05:22:23 +0000 (13:22 +0800)
Conflicts:
Build.pm
expanddeps

Change-Id: I0eee5303d2098bfc7a69f6ecda239db2263818e2

Build.pm
createdirdeps
expanddeps

index e03c3ab..787b656 100644 (file)
--- a/Build.pm
+++ b/Build.pm
@@ -585,21 +585,24 @@ sub get_cbinstalls { return @{[]}; }
 
 sub readdeps {
   my ($config, $pkginfo, @depfiles) = @_;
-  my %requires;
-  my %recommends;
+
   local *F;
+  my %requires;
   my %provides;
   my %pkgconflicts;
   my %pkgobsoletes;
+  my %recommends;
+  my %supplements;
   my $dofileprovides = %{$config->{'fileprovides'} || {}};
   for my $depfile (@depfiles) {
     if (ref($depfile) eq 'HASH') {
       for my $rr (keys %$depfile) {
        $provides{$rr} = $depfile->{$rr}->{'provides'};
        $requires{$rr} = $depfile->{$rr}->{'requires'};
-       $recommends{$rr} = $depfile->{$rr}->{'recommends'};
        $pkgconflicts{$rr} = $depfile->{$rr}->{'conflicts'};
        $pkgobsoletes{$rr} = $depfile->{$rr}->{'obsoletes'};
+       $recommends{$rr} = $depfile->{$rr}->{'recommends'};
+       $supplements{$rr} = $depfile->{$rr}->{'supplements'};
       }
       next;
     }
@@ -641,7 +644,7 @@ sub readdeps {
       }
       my %ss;
       @ss = grep {!$ss{$_}++} @ss;
-      if ($s =~ /^(P|R|C|O|r):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
+      if ($s =~ /^(P|R|C|O|r|s):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
        my $pkgid = $2;
        my $arch = $3;
        if ($1 eq "P") {
@@ -657,11 +660,6 @@ sub readdeps {
          $pkginfo->{$pkgid}->{'requires'} = \@ss if $pkginfo;
          next;
        }
-       if ($1 eq "r") {
-         $recommends{$pkgid} = \@ss;
-         $pkginfo->{$pkgid}->{'recommends'} = \@ss if $pkginfo;
-         next;
-       }
        if ($1 eq "C") {
          $pkgconflicts{$pkgid} = \@ss;
          $pkginfo->{$pkgid}->{'conflicts'} = \@ss if $pkginfo;
@@ -672,6 +670,16 @@ sub readdeps {
          $pkginfo->{$pkgid}->{'obsoletes'} = \@ss if $pkginfo;
          next;
        }
+       if ($1 eq "r") {
+         $recommends{$pkgid} = \@ss;
+         $pkginfo->{$pkgid}->{'recommends'} = \@ss if $pkginfo;
+         next;
+       }
+       if ($1 eq "s") {
+         $supplements{$pkgid} = \@ss;
+         $pkginfo->{$pkgid}->{'supplements'} = \@ss if $pkginfo;
+         next;
+       }
       }
     }
     close F;
@@ -693,9 +701,10 @@ sub readdeps {
   }
   $config->{'providesh'} = \%provides;
   $config->{'requiresh'} = \%requires;
-  $config->{'recommendsh'} = \%recommends;
   $config->{'pkgconflictsh'} = \%pkgconflicts;
   $config->{'pkgobsoletesh'} = \%pkgobsoletes;
+  $config->{'recommendsh'} = \%recommends;
+  $config->{'supplementsh'} = \%supplements;
   makewhatprovidesh($config);
 }
 
@@ -721,9 +730,10 @@ sub writedeps {
   print $fh "F:$id$url$pkg->{'location'}\n";
   print $fh "P:$id".join(' ', @{$pkg->{'provides'} || []})."\n";
   print $fh "R:$id".join(' ', @{$pkg->{'requires'}})."\n" if $pkg->{'requires'};
-  print $fh "r:$id".join(' ', @{$pkg->{'recommends'}})."\n" if $pkg->{'recommends'};
   print $fh "C:$id".join(' ', @{$pkg->{'conflicts'}})."\n" if $pkg->{'conflicts'};
   print $fh "O:$id".join(' ', @{$pkg->{'obsoletes'}})."\n" if $pkg->{'obsoletes'};
+  print $fh "r:$id".join(' ', @{$pkg->{'recommends'}})."\n" if $pkg->{'recommends'};
+  print $fh "s:$id".join(' ', @{$pkg->{'supplements'}})."\n" if $pkg->{'supplements'};
   print $fh "I:$id".getbuildid($pkg)."\n";
 }
 
@@ -757,9 +767,10 @@ sub forgetdeps {
   delete $config->{'providesh'};
   delete $config->{'whatprovidesh'};
   delete $config->{'requiresh'};
-  delete $config->{'recommendsh'};
   delete $config->{'pkgconflictsh'};
   delete $config->{'pkgobsoletesh'};
+  delete $config->{'recommendsh'};
+  delete $config->{'supplementsh'};
 }
 
 my %addproviders_fm = (
@@ -863,6 +874,17 @@ sub checkobsoletes {
   return 0;
 }
 
+sub todo2recommended {
+  my ($config, $recommended, $todo) = @_;
+  my $whatprovides = $config->{'whatprovidesh'};
+  my $pkgrecommends = $config->{'recommendsh'} || {};
+  for my $p (splice @$todo) {
+    for my $r (@{$pkgrecommends->{$p} || []}) {
+      $recommended->{$_} = 1 for @{$whatprovides->{$r} || addproviders($config, $r)}
+    }
+  }
+}
+
 sub expand {
   my ($config, @p) = @_;
 
@@ -872,10 +894,11 @@ sub expand {
   my $prefer = $config->{'preferh'};
   my $ignore = $config->{'ignoreh'};
   my $ignoreconflicts = $config->{'expandflags:ignoreconflicts'};
+  my $ignoreignore;
+  my $userecommendsforchoices = 1;
 
   my $whatprovides = $config->{'whatprovidesh'};
   my $requires = $config->{'requiresh'};
-  my $recommends = $config->{'recommendsh'};
 
   my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
   my @directdepsend;
@@ -890,8 +913,18 @@ sub expand {
   }
   @p = grep {!/^-/} @p;
 
-  my %p;               # expanded packages
   my %aconflicts;      # packages we are conflicting with
+  for (grep {/^!/} @p) {
+    my $r = /^!!/ ? substr($_, 2) : substr($_, 1);
+    my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
+    @q = nevrmatch($config, $r, @q) if /^!!/;
+    $aconflicts{$_} = "is in BuildConflicts" for @q;
+  }
+  my %recommended;     # recommended by installed packages
+  my @rec_todo;                # installed todo
+
+  @p = grep {!/^[-!]/} @p;
+  my %p;               # expanded packages
 
   # add direct dependency packages. this is different from below,
   # because we add packages even if the dep is already provided and
@@ -920,6 +953,7 @@ sub expand {
        $aconflicts{$_} = "is obsoleted by installed $q[0]" for nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)});
       }
     }
+    push @rec_todo, $q[0] if $userecommendsforchoices;
   }
   push @p, @directdepsend;
 
@@ -985,21 +1019,11 @@ sub expand {
                last;
            }
        }
-       if (@q > 1 && $config->{"buildflags:userecommendsforchoices"} && @{$recommends->{$p} || []} > 0) {
-         my @recommendedq;
-         my $i;
-
-         for my $iq (@q) {
-           for my $rpkg (@{$recommends->{$p}}) {
-             if ($rpkg =~ /$iq/) {
-               push @recommendedq, $iq;
-             }
-           }
-         }
-         if (@recommendedq > 0) {
-            print "recommended [@recommendedq] among [@q]\n" if $expand_dbg;
-           @q = @recommendedq;
-         }
+       if ($doamb == 2) {
+         todo2recommended($config, \%recommended, \@rec_todo) if @rec_todo;
+         my @pq = grep {$recommended{$_}} @q;
+         print "recommended [@pq] among [@q]\n" if $expand_dbg;
+         @q = @pq if @pq;
        }
        if (@q > 1) {
          if ($r ne $p) {
@@ -1022,6 +1046,7 @@ sub expand {
            $aconflicts{$_} = "is obsoleted by installed $q[0]" for nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)});
          }
         }
+       push @rec_todo, $q[0] if $userecommendsforchoices;
        @error = ();
        $doamb = 0;
       }
@@ -1030,11 +1055,12 @@ sub expand {
     next if @p;                # still work to do
 
     # only ambig stuff left
-    if (@pamb && !$doamb) {
+    if (@pamb && ($doamb == 0 || $doamb == 1)) {
       @p = @pamb;
       @pamb = ();
-      $doamb = 1;
-      print "now doing undecided dependencies\n" if $expand_dbg;
+      todo2recommended($config, \%recommended, \@rec_todo) if @rec_todo;
+      $doamb = %recommended ? 2 : 3;
+      print "now doing undecided dependencies, $doamb = $doamb\n" if $expand_dbg;
       next;
     }
     return undef, @error if @error;
index b50739f..aa602ab 100755 (executable)
@@ -78,7 +78,7 @@ for my $dir (@ARGV) {
          next if $seen{$idx};
          $seen{$idx} = 1;
          print "F:$idx: $path\n";
-         for (qw{P R r C O I}) {
+         for (qw{P R C O I r s}) {
            print $old{"$_:$idx"}."\n" if $old{"$_:$idx"};
          }
          next;
index 19d9e7e..30ca3bd 100755 (executable)
@@ -126,7 +126,7 @@ if (defined($dist) && $dist ne '') {
   $binarytype = $cf->{'binarytype'} if $cf->{'binarytype'} && $cf->{'binarytype'} ne 'UNDEFINED';
 }
 
-my (%fn, %prov, %req, %rec, %con, %obs);
+my (%fn, %prov, %req, %con, %obs, %rec, %sup);
 
 my %packs;
 my %repo;
@@ -170,7 +170,7 @@ 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, $pkgr, $pkgC, $pkgO);
+my ($pkgF, $pkgP, $pkgR, $pkgC, $pkgO, $pkgr, $pkgs);
 
 my $verscmp = \&Build::Rpm::verscmp;
 
@@ -220,6 +220,10 @@ while(<F>) {
     $pkgO = $2;
     next if $obs{$1};
     $obs{$1} = $2;
+  } elsif (/^r:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+    $pkgr = $2;
+  } elsif (/^s:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+    $pkgs = $2;
   } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
     my $r = 0;
     if ($usehigherdeps) {
@@ -246,10 +250,13 @@ while(<F>) {
       delete $rec{$i};
       delete $con{$i};
       delete $obs{$i};
+      delete $rec{$i};
+      delete $sup{$i};
       $req{$i}  = $pkgR;
-      $rec{$i}  = $pkgr;
       $con{$i}  = $pkgC if defined $pkgC;
       $obs{$i}  = $pkgO if defined $pkgO;
+      $rec{$i}  = $pkgr if defined $pkgr;
+      $sup{$i}  = $pkgs if defined $pkgs;
     } else {
       next if $ids{$1};
       $ids{$1} = $2;
@@ -257,9 +264,10 @@ while(<F>) {
     undef $pkgF;
     undef $pkgP;
     undef $pkgR;
-    undef $pkgr;
     undef $pkgC;
     undef $pkgO;
+    undef $pkgr;
+    undef $pkgs;
   } elsif ($_ eq 'D:') {
     %packs_done = %ids;
   }
@@ -272,7 +280,7 @@ for my $arch (@archs) {
 
 for my $pack (keys %packs) {
   my $r = {};
-  my (@s, $s, @pr, @re, @rc, @co, @ob);
+  my (@s, $s, @pr, @re, @co, @ob, @rc, @su);
   @s = split(' ', $prov{$packs{$pack}} || '');
   while (@s) {
     $s = shift @s;
@@ -305,6 +313,30 @@ for my $pack (keys %packs) {
       splice(@s, 0, 2);
     }
   }
+  @s = split(' ', $con{$packs{$pack}} || '');
+  while (@s) {
+    $s = shift @s;
+    next if !$dofileprovides && $s =~ /^\//;
+    push @co, $s;
+    while (@s && $s[0] =~ /^[\(<=>|]/) {
+      $co[-1] .= " $s[0] $s[1]";
+      $co[-1] =~ s/ \((.*)\)/ $1/;
+      $co[-1] =~ s/(<|>){2}/$1/;
+      splice(@s, 0, 2);
+    }
+  }
+  @s = split(' ', $obs{$packs{$pack}} || '');
+  while (@s) {
+    $s = shift @s;
+    next if !$dofileprovides && $s =~ /^\//;
+    push @ob, $s;
+    while (@s && $s[0] =~ /^[\(<=>|]/) {
+      $ob[-1] .= " $s[0] $s[1]";
+      $ob[-1] =~ s/ \((.*)\)/ $1/;
+      $ob[-1] =~ s/(<|>){2}/$1/;
+      splice(@s, 0, 2);
+    }
+  }
   @s = split(' ', $rec{$packs{$pack}} || '');
   while (@s) {
     $s = shift @s;
@@ -321,35 +353,28 @@ for my $pack (keys %packs) {
       splice(@s, 0, 2);
     }
   }
-  @s = split(' ', $con{$packs{$pack}} || '');
+  @s = split(' ', $sup{$packs{$pack}} || '');
   while (@s) {
     $s = shift @s;
     next if !$dofileprovides && $s =~ /^\//;
-    push @co, $s;
-    while (@s && $s[0] =~ /^[\(<=>|]/) {
-      $co[-1] .= " $s[0] $s[1]";
-      $co[-1] =~ s/ \((.*)\)/ $1/;
-      $co[-1] =~ s/(<|>){2}/$1/;
+    if ($s =~ /^rpmlib\(/) {
       splice(@s, 0, 2);
+      next;
     }
-  }
-  @s = split(' ', $obs{$packs{$pack}} || '');
-  while (@s) {
-    $s = shift @s;
-    next if !$dofileprovides && $s =~ /^\//;
-    push @ob, $s;
+    push @su, $s;
     while (@s && $s[0] =~ /^[\(<=>|]/) {
-      $ob[-1] .= " $s[0] $s[1]";
-      $ob[-1] =~ s/ \((.*)\)/ $1/;
-      $ob[-1] =~ s/(<|>){2}/$1/;
+      $rc[-1] .= " $s[0] $s[1]";
+      $rc[-1] =~ s/ \((.*)\)/ $1/;
+      $rc[-1] =~ s/(<|>){2}/$1/;
       splice(@s, 0, 2);
     }
   }
   $r->{'provides'} = \@pr;
   $r->{'requires'} = \@re;
-  $r->{'recommends'} = \@rc;
   $r->{'conflicts'} = \@co;
   $r->{'obsoletes'} = \@ob;
+  $r->{'recommends'} = \@rc;
+  $r->{'supplements'} = \@su;
   $repo{$pack} = $r;
 }