=head1 DESCRIPTION
B<dh> runs a sequence of debhelper commands. The supported I<sequence>s
-correspond to the targets of a F<debian/rules> file: B<build>, B<clean>,
+correspond to the targets of a F<debian/rules> file: B<build-arch>,
+B<build-indep>, B<build>, B<clean>, B<install-indep>, B<install-arch>,
B<install>, B<binary-arch>, B<binary-indep>, and B<binary>.
-Commands in the B<binary-indep> sequence are passed the B<-i> option to ensure
-they only work on binary independent packages, and commands in the
-B<binary-arch> sequences are passed the B<-a> option to ensure they only work
-on architecture dependent packages.
+Commands in the B<build-indep>, B<install-indep> and B<binary-indep>
+sequences are passed the B<-i> option to ensure they only work on
+architecture independent packages, and commands in the B<build-arch>,
+B<install-arch> and B<binary-arch> sequences are passed the B<-a>
+option to ensure they only work on architecture dependent packages.
If F<debian/rules> contains a target with a name like B<override_>I<dh_command>,
then when it would normally run I<dh_command>, B<dh> will instead call that
Finally, remember that you are not limited to using override targets in the
rules file when using B<dh>. You can also explicitly define any of the regular
rules file targets when it makes sense to do so. A common reason to do this
-is if your package needs different B<build-arch> and B<build-indep> targets. For
-example, a package with a long document build process can put it in
-B<build-indep> to avoid build daemons redundantly building the documentation.
+is when your package needs different B<build-arch> and B<build-indep> targets.
+For example, a package with a long document build process can put it in
+B<build-indep>.
#!/usr/bin/make -f
%:
dh $@
- build: build-arch build-indep ;
build-indep:
$(MAKE) docs
build-arch:
$(MAKE) bins
+Note that in the example above, dh will arrange for "debian/rules build"
+to call your build-indep and build-arch targets. You do not need to
+explicitly define the dependencies in the rules file when using dh.
+
=head1 INTERNALS
If you're curious about B<dh>'s internals, here's how it works under the hood.
in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining>
options can override this behavior.
+A sequence can also run dependent targets in debian/rules. For
+example, the "binary" sequence runs the "install" target.
+
B<dh> uses the B<DH_INTERNAL_OPTIONS> environment variable to pass information
through to debhelper commands that are run inside override targets. The
contents (and indeed, existence) of this environment variable, as the name
# Definitions of sequences.
my %sequences;
-$sequences{build} = [qw{
+my @bd_minimal = qw{
+ dh_testdir
+};
+my @bd = qw{
dh_testdir
dh_auto_configure
dh_auto_build
dh_auto_test
-}],
+ };
+# rules:build-arch and rules:build-indep are not called by build,
+# as an optimisation (code below will adjust this if explicit targets exist).
+$sequences{build} = [@bd];
+$sequences{'build-indep'} = [@bd];
+$sequences{'build-arch'} = [@bd];
$sequences{clean} = [qw{
dh_testdir
dh_auto_clean
dh_clean
}];
-$sequences{install} = [@{$sequences{build}}, qw{
+my @i_minimal = qw{
+ dh_testroot
+};
+my @i = qw{
dh_testroot
dh_prep
dh_installdirs
dh_installudev
dh_installwm
dh_installxfonts
+ dh_installgsettings
dh_bugfiles
+ dh_ucf
dh_lintian
dh_gconf
dh_icons
dh_link
dh_compress
dh_fixperms
-}];
+};
+# The install sequences will call rules:build before running
+# the standard sequence. rules:install-arch and rules:install-indep
+# are not called by install, as an optimisation (code below will adjust
+# this if explicit targets exist).
+$sequences{'install'} = ['rules:build', @i, 'rules:install-arch', 'rules:install-indep'];
+$sequences{'install-indep'} = ['rules:build-indep', @i];
+$sequences{'install-arch'} = ['rules:build-arch', @i];
+my @ba=qw{
+ dh_strip
+ dh_makeshlibs
+ dh_shlibdeps
+};
my @b=qw{
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
};
-$sequences{'binary-indep'} = [@{$sequences{install}}, @b];
-$sequences{binary} = [@{$sequences{install}}, qw{
- dh_strip
- dh_makeshlibs
- dh_shlibdeps
-}, @b];
-$sequences{'binary-arch'} = [@{$sequences{binary}}];
+# The binary sequences will call 'debian/rules install' before running
+# the standard sequence.
+$sequences{binary} = ['rules:install', 'rules:binary-arch', 'rules:binary-indep'];
+$sequences{'binary-indep'} = ['rules:install-indep', @b];
+$sequences{'binary-arch'} = ['rules:install-arch', @ba, @b];
# Additional command options
my %command_opts;
if (! defined $sequence) {
error "specify a sequence to run";
}
+# make -B causes the rules file to be run as a target.
+# Also support completly empty override targets.
+# Note: it's not safe to use rules_explicit_target before this check.
if ($sequence eq 'debian/rules' ||
$sequence =~ /^override_dh_/) {
- # make -B causes the rules file to be run as a target.
- # Also support completly empty override targets.
exit 0;
}
elsif (! exists $sequences{$sequence}) {
error "Unknown sequence $sequence (choose from: ".
join(" ", sort keys %sequences).")";
}
+
+# If debian/rules defines build-arch or build-indep, run sequences separately.
+if (rules_explicit_target('build-arch') ||
+ rules_explicit_target('build-indep')) {
+ $sequences{build} = [@bd_minimal, 'rules:build-arch', 'rules:build-indep'];
+}
+# If debian/rules defines install-arch or install-indep, run sequences
+# separately.
+if (rules_explicit_target('install-arch') ||
+ rules_explicit_target('install-indep')) {
+ $sequences{'install'} = ['rules:build', @i_minimal, 'rules:install-arch', 'rules:install-indep'];
+}
+
my @sequence=@{$sequences{$sequence}};
# The list of all packages that can be acted on.
# Get the options to pass to commands in the sequence.
# Filter out options intended only for this program.
my @options;
-if ($sequence eq 'binary-arch') {
+if ($sequence eq 'build-arch' ||
+ $sequence eq 'install-arch' ||
+ $sequence eq 'binary-arch') {
push @options, "-a";
# as an optimisation, remove from the list any packages
# that are not arch dependent
my %arch_packages = map { $_ => 1 } getpackages("arch");
@packages = grep { $arch_packages{$_} } @packages;
}
-elsif ($sequence eq 'binary-indep') {
+elsif ($sequence eq 'build-indep' ||
+ $sequence eq 'install-indep' ||
+ $sequence eq 'binary-indep') {
push @options, "-i";
# ditto optimisation for arch indep
my %indep_packages = map { $_ => 1 } getpackages("indep");
# 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 (defined $has_explicit_target) {
+
+ if (defined $rules_target) {
+ # Don't pass DH_ environment variables, since this is
+ # a fresh invocation of debian/rules and any sub-dh
+ # commands.
+ $override_command=$command;
+ delete $ENV{DH_INTERNAL_OPTIONS};
+ delete $ENV{DH_INTERNAL_OVERRIDE};
+ $command="debian/rules";
+ @options=$rules_target;
+ }
+ elsif (defined $has_explicit_target) {
$override_command=$command;
# Check if target isn't noop
if ($has_explicit_target) {
# This passes the options through to commands called
# inside the target.
$ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options);
- # Prevent commands called inside the target from
- # logging.
- $ENV{DH_INHIBIT_LOG}=$command;
+ $ENV{DH_INTERNAL_OVERRIDE}=$command;
$command="debian/rules";
@options="override_".$override_command;
}
else {
print " ", "# Skipping ", $override_command, " - empty override", "\n";
}
-
+
if (! $dh{NO_ACT}) {
if (defined $command) {
my $ret=system($command, @options);
+
if ($ret >> 8 != 0) {
exit $ret >> 8;
}
}
if (defined $override_command) {
- delete $ENV{DH_INTERNAL_OPTIONS};
- delete $ENV{DH_INHIBIT_LOG};
# Update log for overridden command now that it has
# finished successfully.
# (But avoid logging for dh_clean since it removes
my %packages=map { $_ => 1 } @packages;
map { delete $packages{$_} } @exclude;
write_log($override_command, keys %packages);
+ commit_override_log(keys %packages);
}
+
+ delete $ENV{DH_INTERNAL_OPTIONS};
+ delete $ENV{DH_INTERNAL_OVERRIDE};
}
}
}