On Tue, Jun 07, 2011 at 01:47:41PM +0100, Roger Leigh wrote: > On Tue, Jun 07, 2011 at 08:12:15AM -0400, Joey Hess wrote: > > Roger Leigh wrote: > > > I think I may have proposed something similar to this patch before, but > > > I can't find it in the BTS. > > > > It caused significant slowdown (due to running every debhelper command > > twice with -a and -i) and quite likely broke packages due to > > running make install twice, so was removed. > > > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=604563#77 > > > > 657852b56b0d835afd4e45407d6e8d217c63ab20 > > I'm sure we can improve the performance with some additional work. > > Currently we have the "sequence dependencies" as a separate > list, not associated with the sequences themselves. It would be > possible to put them directly into the sequence list, e.g. with > a prefix such as "rules:build" which would make dh invoke > "debian/rules build" rather than the command directly. This would > permit the rules targets to be run at any point in a sequence.
Patch attached which includes the rules in the sequences. This should, as far as I can tell with my testing, eliminate the performance issues you mentioned above. With the rules targets in the sequence list, it also means you can potentially also use them as sequence points for --before etc. Note that there's one issue with the code that confuses me. This might be a pre-existing issue with dh that the patch exposes: % fakeroot dh binary --no-act debian/rules install debian/rules override_dh_strip dh_makeshlibs dh_shlibdeps dh_installdeb dh_gencontrol dh_md5sums dh_builddeb debian/rules binary-arch debian/rules binary-indep % fakeroot dh binary [build completes] % fakeroot dh binary --no-act debian/rules binary-arch debian/rules binary-indep Notice that the initial 'debian/rules install' performed by dh binary isn't repeated on the second invocation. But AFAICS there's no .log file that would make dh skip this, so I'm unsure why it's skipped. The same applies to the override to an extent (at least here the override is for a single specific purpose which we can assume was completed if the .log exists); install is rather more generic and I would expect it to be called even if it subsequently does nothing due to being up-to-date). Not yet found which bit of the code causes this to be skipped. Note that the documentation about dependencies is now outdated; I'll fix that next. Regards, Roger -- .''`. Roger Leigh : :' : Debian GNU/Linux http://people.debian.org/~rleigh/ `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/ `- GPG Public Key: 0x25BFB848 Please GPG sign your mail.
From a709296e8c7f8514e53f3792a6993a6da994ba61 Mon Sep 17 00:00:00 2001 From: Roger Leigh <[email protected]> Date: Fri, 3 Jun 2011 20:41:30 +0100 Subject: [PATCH 1/2] dh: Add sequence dependency support --- dh | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 94 insertions(+), 16 deletions(-) diff --git a/dh b/dh index 50e0f14..e7b6721 100755 --- a/dh +++ b/dh @@ -151,6 +151,16 @@ either and instead run your own commands. override_dh_auto_build: make universe-explode-in-delight +If running a configure script, it may be necessary to prevent it being +run twice, once for architecture-independent packages, and again for +architecture-dependent packages. This may be accomplished by +overriding L<dh_autoconfigure(1)>: + + override_dh_auto_configure: config.status + + config.status: + dh_auto_configure -- $configure_options + Another common case is wanting to do something manually before or after a particular debhelper command is run. @@ -273,6 +283,16 @@ that is in the specified sequence. It then continues with the next command in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining> options can override this behavior. +A sequence can also have dependencies. For example, the "binary" +sequence depends upon the "binary-arch" and "binary-indep" sequences, +and the "binary-arch" sequence depends upon the "install-arch" +sequence which in turn depends upon the "build-arch" sequence. These +will, by default, be run via "debian/rules <sequence>" and so may be +overridden or extended there, or else will run dh again to execute the +depending sequence. For example, "dh binary-arch" will run +"debian/rules install-arch" which will run "dh install-arch" unless a +custom install-arch target replaces the default 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 @@ -321,14 +341,15 @@ if (is_make_jobserver_unavailable()) { # Definitions of sequences. my %sequences; -$sequences{build} = [qw{ +my @bd = qw{ dh_testdir dh_auto_configure dh_auto_build dh_auto_test -}], -$sequences{'build-indep'} = [@{$sequences{build}}]; -$sequences{'build-arch'} = [@{$sequences{build}}]; +}; +$sequences{build} = [@bd, 'rules:build-arch', 'rules:build-indep']; +$sequences{'build-indep'} = [@bd]; +$sequences{'build-arch'} = [@bd]; $sequences{clean} = [qw{ dh_testdir dh_auto_clean @@ -376,9 +397,9 @@ my @i = qw{ dh_compress dh_fixperms }; -$sequences{'install'} = [@{$sequences{build}}, @i]; -$sequences{'install-indep'} = [@{$sequences{'build-indep'}}, @i]; -$sequences{'install-arch'} = [@{$sequences{'build-arch'}}, @i]; +$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 @@ -390,9 +411,9 @@ my @b=qw{ dh_md5sums dh_builddeb }; -$sequences{binary} = [@{$sequences{install}}, @ba, @b]; -$sequences{'binary-indep'} = [@{$sequences{'install-indep'}}, @b]; -$sequences{'binary-arch'} = [@{$sequences{'install-arch'}}, @ba, @b]; +$sequences{binary} = ['rules:install', @ba, @b, '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; @@ -641,20 +662,71 @@ sub run { # to prevent them from being acted on. push @options, map { "-N$_" } @exclude; + my $arch = grep {$_ eq '-a'} @options; + my $indep = grep {$_ eq '-i'} @options; + my $orig_command = $command; + + if ($command =~ '^rules:(.*)') { + my $target = $1; + $command = 'debian/rules'; + @options = ($target); + } + + # Check for override targets in debian/rules and + # run them instead of running the command directly. + my $has_explicit_target = rules_explicit_target("override_".$orig_command); + if ($command ne 'debian/rules' && defined $has_explicit_target) { + run_hook("override_".$orig_command, \@packages, \@exclude, @options); + } + else { + # Pass additional command options if any + unshift @options, @{$command_opts{$command}} if exists $command_opts{$command}; + if (defined $command) { + # 3 space indent lines the command being run up under the + # sequence name after "dh ". + print " ".escape_shell($command, @options)."\n"; + } + + if (! $dh{NO_ACT}) { + if (defined $command) { + local %ENV=%ENV; + if ($command eq 'debian/rules') { + # The dh options are not passed in the + # environment, to ensure that the behaviour + # is the same if invoked directly. + delete $ENV{DH_INTERNAL_OPTIONS}; + delete $ENV{DH_INTERNAL_OVERRIDE}; + } + my $ret=system($command, @options); + if ($ret >> 8 != 0) { + exit $ret >> 8; + } + elsif ($ret) { + exit 1; + } + } + } + } +} + +sub run_hook { + my $command=shift; + my @packages=@{shift()}; + my @exclude=@{shift()}; + my @options=@_; + + my @orig_options = @options; + # 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); + my $has_explicit_target = rules_explicit_target($command); if (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); - $ENV{DH_INTERNAL_OVERRIDE}=$command; $command="debian/rules"; - @options="override_".$override_command; + @options=$override_command; } else { $command = undef; @@ -676,6 +748,10 @@ sub run { if (! $dh{NO_ACT}) { if (defined $command) { + # This passes the options through to commands called + # inside the target. + $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @orig_options); + $ENV{DH_INTERNAL_OVERRIDE}=$command; my $ret=system($command, @options); if ($ret >> 8 != 0) { @@ -684,6 +760,8 @@ sub run { elsif ($ret) { exit 1; } + delete $ENV{DH_INTERNAL_OPTIONS}; + delete $ENV{DH_INTERNAL_OVERRIDE}; } if (defined $override_command) { -- 1.7.5.3
From 6bb492660bb8e78e3b9ed47b55d10eafcb01da93 Mon Sep 17 00:00:00 2001 From: Roger Leigh <[email protected]> Date: Fri, 3 Jun 2011 20:42:50 +0100 Subject: [PATCH 2/2] dh: Add hook support --- dh | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 67 insertions(+), 0 deletions(-) diff --git a/dh b/dh index e7b6721..a0ff637 100755 --- a/dh +++ b/dh @@ -32,6 +32,18 @@ target. The override target can then run the command with additional options, or run entirely different commands instead. See examples below. (Note that to use this feature, you should Build-Depend on debhelper 7.0.50 or above.) +If F<debian/rules> contains a target with a name like +I<dh_command>B<_hook>, I<dh_command>B<_indep_hook> or +I<dh_command>B<_arch_hook>, these targets will be called I<after> +I<dh_command> has been run. I<dh_command_hook> will be run for all +packages, while I<dh_command_indep_hook> will only be run for +architecture independent packages and I<dh_command_arch_hook> will +only be run for architecture dependent packages. The hook targets may +be used to run additional commands after the I<dh_command> has +run. See examples below. (Note that to use this feature, you should +Build-Depend on debhelper 8.1.0 or above.) + + =head1 OPTIONS =over 4 @@ -249,6 +261,31 @@ L<dh_listpackages(1)> to test what is being built. For example: chmod 4755 debian/foo/usr/bin/foo endif +Or using a hook, run after dh_fixperms: + + #!/usr/bin/make -f + %: + dh $@ + + dh_fixperms_hook: + ifneq (,$(filter foo, $(shell dh_listpackages))) + chmod 4755 debian/foo/usr/bin/foo + endif + +It may also be possible to do this more simply using a more specific +hook: + + #!/usr/bin/make -f + %: + dh $@ + + dh_fixperms_arch_hook: + chmod 4755 debian/foo/usr/bin/foo + +This is for the case where foo is an architecture dependent package; +if foo is an architecture independent package then +dh_fixperms_indep_hook would be the correct target to use. + Finally, remember that you are not limited to using override targets in the rules file when using B<dh>. You can also explicitly define the regular rules file targets when it makes sense to do so. A common reason to do this @@ -269,6 +306,15 @@ B<build-indep>. build-arch: $(MAKE) bins +Or alternatively, using hooks: + + dh_auto_build_indep_hook: + $(MAKE) docs + + dh_auto_build_arch_hook: + $(MAKE) bins + + =head1 INTERNALS If you're curious about B<dh>'s internals, here's how it works under the hood. @@ -707,6 +753,27 @@ sub run { } } } + + if ($command ne 'debian/rules') { + if ($arch || $indep) { + $has_explicit_target = rules_explicit_target($orig_command."_hook"); + if (defined $has_explicit_target) { + run_hook($orig_command."_hook", \@packages, \@exclude, @options); + } + } + if ($arch) { + $has_explicit_target = rules_explicit_target($orig_command."_arch_hook"); + if (defined $has_explicit_target) { + run_hook($orig_command."_arch_hook", \@packages, \@exclude, @options); + } + } + if ($indep) { + $has_explicit_target = rules_explicit_target($orig_command."_indep_hook"); + if (defined $has_explicit_target) { + run_hook($orig_command."_indep_hook", \@packages, \@exclude, @options); + } + } + } } sub run_hook { -- 1.7.5.3
signature.asc
Description: Digital signature

