+ return if $dh{NO_ACT};
+
+ my $ret=system($command, @options);
+ if ($ret >> 8 != 0) {
+ exit $ret >> 8;
+ }
+ elsif ($ret) {
+ exit 1;
+ }
+}
+
+# Tries to run an override target for a command. Returns the list of
+# packages that it was unable to run an override target for.
+sub run_override {
+ my $override_type=shift; # arch, indep, or undef
+ my $command=shift;
+ my @packages=@{shift()};
+ my @options=@_;
+
+ my $override="override_$command".
+ (defined $override_type ? "-".$override_type : "");
+
+ # Check which packages are of the right architecture for the
+ # override_type.
+ my (@todo, @rest);
+ if (defined $override_type) {
+ foreach my $package (@packages) {
+ my $isall=package_arch($package) eq 'all';
+ if (($override_type eq 'indep' && $isall) ||
+ ($override_type eq 'arch' && !$isall)) {
+ push @todo, $package;
+ }
+ else {
+ push @rest, $package;
+ push @options, "-N$package";
+ }
+ }
+ }
+ else {
+ @todo=@packages;
+ }
+
+ my $has_explicit_target = rules_explicit_target($override);
+ return @packages unless defined $has_explicit_target; # no such override
+ return @rest if ! $has_explicit_target; # has empty override
+ return @rest unless @todo; # has override, but no packages to act on
+
+ if (defined $override_type) {
+ # Ensure appropriate -a or -i option is passed when running
+ # an arch-specific override target.
+ my $opt=$override_type eq "arch" ? "-a" : "-i";
+ push @options, $opt unless grep { $_ eq $opt } @options;
+ }
+
+ # This passes the options through to commands called
+ # inside the target.
+ $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options);
+ $ENV{DH_INTERNAL_OVERRIDE}=$command;
+ run("debian/rules", $override);
+ delete $ENV{DH_INTERNAL_OPTIONS};
+ delete $ENV{DH_INTERNAL_OVERRIDE};
+
+ # Update log for overridden command now that it has
+ # finished successfully.
+ # (But avoid logging for dh_clean since it removes
+ # the log earlier.)
+ if (! $dh{NO_ACT} && $command ne 'dh_clean') {
+ write_log($command, @todo);
+ commit_override_log(@todo);
+ }
+
+ return @rest;
+}
+
+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 &&
+ ! defined rules_explicit_target($rules_target)) {
+ # inline the sequence for this implicit target
+ $add->($_) foreach optimize_sequence(@{$sequences{$rules_target}});