Просмотр исходного кода

dpkg-source: call quilt only once to apply all patches

Refactor Dpkg::Source::Package::V3::quilt::apply_patches() to
call quilt only once (quilt push -a -q) instead of once per package. This
dramatically improves performance for packages like glibc that
have a large number of patches.
Raphael Hertzog лет назад: 17
Родитель
Сommit
ea1530fe45
2 измененных файлов с 29 добавлено и 18 удалено
  1. 2 0
      debian/changelog
  2. 27 18
      scripts/Dpkg/Source/Package/V3/quilt.pm

+ 2 - 0
debian/changelog

@@ -4,6 +4,8 @@ dpkg (1.15.1) UNRELEASED; urgency=low
   * Fix dpkg-genchanges to not include the additional upstream tarballs
   * Fix dpkg-genchanges to not include the additional upstream tarballs
     when they are not desired (specific to source packages using format 3.0
     when they are not desired (specific to source packages using format 3.0
     quilt).
     quilt).
+  * Call quilt only once to apply all patches instead of once per patch
+    when building 3.0 (quilt) source packages. Closes: #518453
 
 
   [ Updated dselect translations ]
   [ Updated dselect translations ]
   * German (Sven Joachim).
   * German (Sven Joachim).

+ 27 - 18
scripts/Dpkg/Source/Package/V3/quilt.pm

@@ -138,35 +138,44 @@ sub apply_patches {
         }
         }
     }
     }
 
 
-    # Apply patches
+    # Apply patches
     my $applied = File::Spec->catfile($dir, "debian", "patches", ".dpkg-source-applied");
     my $applied = File::Spec->catfile($dir, "debian", "patches", ".dpkg-source-applied");
     open(APPLIED, '>', $applied) || syserr(_g("cannot write %s"), $applied);
     open(APPLIED, '>', $applied) || syserr(_g("cannot write %s"), $applied);
     my $now = time();
     my $now = time();
-    foreach my $patch ($self->get_patches($dir, $skip_auto)) {
+    my $pobj = {};
+    my $panalysis = {};
+    my @patches = $self->get_patches($dir, $skip_auto);
+    foreach my $patch (@patches) {
         my $path = File::Spec->catfile($dir, "debian", "patches", $patch);
         my $path = File::Spec->catfile($dir, "debian", "patches", $patch);
-        my $patch_obj = Dpkg::Source::Patch->new(filename => $path);
-        if (not $self->{'options'}{'without_quilt'}) {
-            info(_g("applying %s with quilt"), $patch) unless $skip_auto;
-            my $analysis = $patch_obj->analyze($dir);
-            foreach my $dir (keys %{$analysis->{'dirtocreate'}}) {
+        $pobj->{$patch} = Dpkg::Source::Patch->new(filename => $path);
+        if ($self->{'options'}{'without_quilt'}) {
+            info(_g("applying %s"), $patch) unless $skip_auto;
+            $pobj->{$patch}->apply($dir, timestamp => $now,
+                    force_timestamp => 1, create_dirs => 1,
+                    add_options => [ '-E' ]);
+            print APPLIED "$patch\n";
+        } else {
+            $panalysis->{$patch} = $pobj->{$patch}->analyze($dir);
+            foreach my $dir (keys %{$panalysis->{$patch}->{'dirtocreate'}}) {
                 eval { mkpath($dir); };
                 eval { mkpath($dir); };
                 syserr(_g("cannot create directory %s"), $dir) if $@;
                 syserr(_g("cannot create directory %s"), $dir) if $@;
             }
             }
-            $self->run_quilt($dir, ['push', $patch],
-                             delete_env => ['QUILT_PATCH_OPTS'],
-                             wait_child => 1,
-                             to_file => '/dev/null');
-            foreach my $fn (keys %{$analysis->{'filepatched'}}) {
+        }
+    }
+    if (not $self->{'options'}{'without_quilt'}) {
+        my %opts;
+        $opts{"to_file"} = "/dev/null" if $skip_auto;
+        info(_g("applying all patches with %s"), "quilt push -a -q") unless $skip_auto;
+        $self->run_quilt($dir, ['push', '-a', '-q'],
+                         delete_env => ['QUILT_PATCH_OPTS'],
+                         wait_child => 1, %opts);
+        foreach my $patch (@patches) {
+            foreach my $fn (keys %{$panalysis->{$patch}->{'filepatched'}}) {
                 utime($now, $now, $fn) || $! == ENOENT ||
                 utime($now, $now, $fn) || $! == ENOENT ||
                     syserr(_g("cannot change timestamp for %s"), $fn);
                     syserr(_g("cannot change timestamp for %s"), $fn);
             }
             }
-        } else {
-            info(_g("applying %s"), $patch) unless $skip_auto;
-            $patch_obj->apply($dir, timestamp => $now,
-                    force_timestamp => 1, create_dirs => 1,
-                    add_options => [ '-E' ]);
+            print APPLIED "$patch\n";
         }
         }
-        print APPLIED "$patch\n";
     }
     }
     close(APPLIED);
     close(APPLIED);
 }
 }