]> git.donarmstrong.com Git - debhelper.git/commitdiff
inline sequences to optimize away recursive calls to make/dh for implicit targets
authorJoey Hess <joey@kitenet.net>
Mon, 13 Jun 2011 21:00:08 +0000 (17:00 -0400)
committerJoey Hess <joey@kitenet.net>
Mon, 13 Jun 2011 21:16:48 +0000 (17:16 -0400)
This assumes that all implicit rules file targets are owned by dh, so
it can just assume an implicit target can be optimized away to the commands
in its sequence.

I suppose this would break:

build:
dh build

install: build
dh install

binary-%: install
my-binary-builder-$@

my-binary-builder-arch:
echo "whee! I did something pointlessly complicated with make!"
dh binary-arch
my-binary-builder-indep:
dh binary-indep

But I can't imagine anyone does this, at least with a probability of 1 in
ten thousand, so hopefully it doesn't break any existing packages. :)

dh

diff --git a/dh b/dh
index 8844fb53650ecd213f9366bd867045bd04bbac37..33a7be33318c11be56ffbc175d07ecdab46cc98b 100755 (executable)
--- a/dh
+++ b/dh
@@ -550,7 +550,7 @@ if (! exists $sequences{$sequence}) {
        error "Unknown sequence $sequence (choose from: ".
                join(" ", sort keys %sequences).")";
 }
-my @sequence=@{$sequences{$sequence}};
+my @sequence=optimize_sequence(@{$sequences{$sequence}});
 
 # The list of all packages that can be acted on.
 my @packages=@{$dh{DOPACKAGES}};
@@ -672,18 +672,14 @@ sub run {
        # to prevent them from being acted on.
        push @options, map { "-N$_" } @exclude;
 
-       # If the command has a rules: prefix, run debian/rules with
-       # the remainder as the target.
-       my $rules_target = undef;
-       if ($command =~ /^rules:(.*)/) {
-               $rules_target = $1;
-       }
-
        # Check for override targets in debian/rules and
        # run them instead of running the command directly.
        my $override_command;
        my $has_explicit_target = rules_explicit_target("override_".$command);
 
+       # If the command has a rules: prefix, run debian/rules with
+       # the remainder as the target.
+       my $rules_target = rules_target($command);
        if (defined $rules_target) {
                # Don't pass DH_ environment variables, since this is
                # a fresh invocation of debian/rules and any sub-dh
@@ -753,6 +749,42 @@ sub run {
        }
 }
 
+sub optimize_sequence {
+       my @sequence;
+       my %seen;
+       my $add=sub {
+               # commands can appear multiple times when sequences are
+               # inlined together; only the first should be needed
+               my $command=shift;
+               if (! $seen{$command}) {
+                       $seen{$command}=1;
+                       push @sequence, $command;
+               }
+       };
+       foreach my $command (@_) {
+               my $rules_target=rules_target($command);
+               if (defined $rules_target &&
+                   ! rules_explicit_target($rules_target)) {
+                       # inline the sequence for this implicit target
+                       $add->($_) foreach optimize_sequence(@{$sequences{$rules_target}});
+               }
+               else {
+                       $add->($command);
+               }
+       }
+       return @sequence;
+}
+
+sub rules_target {
+       my $command=shift;
+       if ($command =~ /^rules:(.*)/) {
+               return $1
+       }
+       else {
+               return undef;
+       }
+}
+
 {
 my %targets;
 my $rules_parsed;