From e3367a17054a70074c4a225e6073d3743959d05d Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 27 Feb 2009 15:11:25 -0500 Subject: dh override targets * dh: debian/rules override targets can change what is run for a specific debhelper command in a sequence. * dh: Redid all the examples to use override targets, since these eliminate all annoying boilerplate and are much easier to understand than the old method. * Remove rules.simple example, there's no need to use explcit targets with dh anymore. (cherry picked from commit 0f3f59fe6058edfda4010dc88bd3b8aa3ae70a6d) Conflicts: Debian/Debhelper/Dh_Getopt.pm Debian/Debhelper/Dh_Lib.pm debian/changelog dh --- Debian/Debhelper/Dh_Getopt.pm | 9 +++ Debian/Debhelper/Dh_Lib.pm | 34 ++++---- debian/changelog | 12 +++ dh | 184 +++++++++++++++++++++++------------------- examples/rules.simple | 22 ----- 5 files changed, 137 insertions(+), 124 deletions(-) delete mode 100755 examples/rules.simple diff --git a/Debian/Debhelper/Dh_Getopt.pm b/Debian/Debhelper/Dh_Getopt.pm index f8e02889..d8019337 100644 --- a/Debian/Debhelper/Dh_Getopt.pm +++ b/Debian/Debhelper/Dh_Getopt.pm @@ -191,6 +191,15 @@ sub parseopts { "<>" => \&NonOption, ); + # DH_INTERNAL_OPTIONS is used to pass additional options from + # dh through an override target to a command. + if (defined $ENV{DH_INTERNAL_OPTIONS}) { + $ENV{DH_INTERNAL_OPTIONS}=~s/^\s+//; + $ENV{DH_INTERNAL_OPTIONS}=~s/\s+$//; + unshift @ARGV, split(/\s+/,$ENV{DH_INTERNAL_OPTIONS}); + } + + my $ret=getoptions(\@ARGV, $options); if (!$ret) { error("unknown option; aborting"); } diff --git a/Debian/Debhelper/Dh_Lib.pm b/Debian/Debhelper/Dh_Lib.pm index 6be25f9d..871adf48 100644 --- a/Debian/Debhelper/Dh_Lib.pm +++ b/Debian/Debhelper/Dh_Lib.pm @@ -31,15 +31,9 @@ sub init { # Check to see if an argument on the command line starts with a dash. # if so, we need to pass this off to the resource intensive # Getopt::Long, which I'd prefer to avoid loading at all if possible. - my $parseopt=undef; - my $arg; - foreach $arg (@ARGV) { - if ($arg=~m/^-/) { - $parseopt=1; - last; - } - } - if ($parseopt) { + if ((defined $ENV{DH_OPTIONS} && length $ENV{DH_OPTIONS}) || + (defined $ENV{DH_INTERNAL_OPTIONS} && length $ENV{DH_INTERNAL_OPTIONS}) || + grep /^-/, @ARGV) { eval "use Debian::Debhelper::Dh_Getopt"; error($!) if $@; %dh=Debian::Debhelper::Dh_Getopt::parseopts(); @@ -114,14 +108,20 @@ sub init { my $write_log=1; sub END { if ($? == 0 && $write_log) { - my $cmd=basename($0); - foreach my $package (@{$dh{DOPACKAGES}}) { - my $ext=pkgext($package); - my $log="debian/${ext}debhelper.log"; - open(LOG, ">>", $log) || error("failed to write to ${log}: $!"); - print LOG $cmd."\n"; - close LOG; - } + write_log(basename($0), @{$dh{DOPACKAGES}}); + } +} + +sub write_log { + my $cmd=shift; + my @packages=@_; + + foreach my $package (@packages) { + my $ext=pkgext($package); + my $log="debian/${ext}debhelper.log"; + open(LOG, ">>", $log) || error("failed to write to ${log}: $!"); + print LOG $cmd."\n"; + close LOG; } } diff --git a/debian/changelog b/debian/changelog index 2f107939..9950c219 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +debhelper (7.2.0) UNRELEASED; urgency=low + + * dh: debian/rules override targets can change what is run + for a specific debhelper command in a sequence. + * dh: Redid all the examples to use override targets, since these + eliminate all annoying boilerplate and are much easier to understand + than the old method. + * Remove rules.simple example, there's no need to use explcit targets + with dh anymore. + + -- Joey Hess Thu, 25 Dec 2008 16:26:36 -0500 + debhelper (7.0.17) unstable; urgency=low [ Per Olofsson ] diff --git a/dh b/dh index 98d90241..d0165c99 100755 --- a/dh +++ b/dh @@ -11,7 +11,7 @@ use Debian::Debhelper::Dh_Lib; =head1 SYNOPSIS -B sequence [B<--until> I] [B<--before> I] [B<--after> I] [B<--remaining>] [B<--with> I] [S>] +B sequence [B<--with> I] [B<--until> I] [B<--before> I] [B<--after> I] [B<--remaining>] [S>] =head1 DESCRIPTION @@ -34,10 +34,25 @@ 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. +If debian/rules contains a target with a name like "override_I", +then when it gets to that command in the sequence, dh will run that +target from the rules file, rather than running the actual command. The +override target can then run the command with additional options, or run +entirely different commands instead. (Note that to use this feature, +you should Build-Depend on debhelper 7.2 or above.) + =head1 OPTIONS =over 4 +=item B<--with> I + +Add the debhelper commands specified by the given addon to appropriate places +in the sequence of commands that is run. This option can be repeated more +than once, and is used when there is a third-party package that provides +debhelper commands. See "SEQUENCE ADDONS" below for documentation about what +such packages should do to be supported by --with. + =item B<--until> I Run commands in the sequence until and including I, then stop. @@ -54,14 +69,6 @@ Run commands in the sequence that come after I. Run all commands in the sequence that have yet to be run. -=item B<--with> I - -Add the debhelper commands specified by the given addon to appropriate places -in the sequence of commands that is run. This option can be repeated more -than once, and is used when there is a third-party package that provides -debhelper commands. See "SEQUENCE ADDONS" below for documentation about what -such packages should do to be supported by --with. - =back All other options passed to dh are passed on to each command it runs. This @@ -137,83 +144,43 @@ commands work with no additional options. %: dh $@ -This is a simple rules file that is a good starting place for customisation. -(It's also available in F - +Often you'll want to pass an option to a specific debhelper command. The +easy way to do with is by adding an override target for that command. + #!/usr/bin/make -f + %: + dh $@ - build: build-stamp - dh build - touch build-stamp - - clean: - dh clean - - install: build install-stamp - install-stamp: - dh install - touch install-stamp - - binary-arch: install - dh binary-arch - - binary-indep: install - dh binary-indep - - binary: binary-arch binary-indep - -Often you'll want to pass an option to ./configure. This uses dh to run all -commands before L, then runs that command by hand, -and then finished up by running the rest of the sequence. You could also -run ./configure by hand, instead of bothering with using dh_auto_configure. -And if necessary, you can add commands to run automake, etc here too. + override_dh_strip: + dh_strip -Xfoo + + override_dh_installdocs: + dh_installdocs README TODO - build: build-stamp - build-stamp: - dh build --before configure - dh_auto_configure -- --kitchen-sink=yes - dh build --after configure - touch build-stamp +Sometimes the automated dh_auto_configure and dh_auto_build can't guess +what to do for a strange package. Here's how to avoid running either +and instead run your own commands. -Here's how to skip two automated steps in a row (configure and build), and -instead run the commands by hand. + #!/usr/bin/make -f + %: + dh $@ - build: build-stamp - build-stamp: - dh build --before configure + override_dh_auto_configure: ./mondoconfig + + override_dh_auto_build: make universe-explode-in-delight - dh build --after build - touch build-stamp -Another common case is wanting to run some code manually after a particular -debhelper command is run. +Another common case is wanting to do something manually before or +after a particular debhelper command is run. - install: build install-stamp - install-stamp: - dh install --until dh_fixperms - # dh_fixperms has run, now override it for one program - chmod 4755 debian/foo/usr/bin/foo - # and continue - dh install --after dh_fixperms - touch install-stamp - -It's also fine to run debhelper commands early. Just make sure that at -least dh_prep is run from the sequence first, and be sure to use the -B<--remaining> option to ensure that commands that normally come before -those in the sequence are still run. - - install: build install-stamp - install-stamp: - dh install --until dh_prep - dh_installdocs README TODO - dh_installchangelogs Changes - dh install --remaining - touch install-stamp + #!/usr/bin/make -f + %: + dh $@ - binary-arch: install - dh_strip -X foo - dh binary-arch --remaining + override_dh_fixperms: + dh_fixperms + chmod 4755 debian/foo/usr/bin/foo =cut @@ -443,21 +410,33 @@ foreach my $i (0..$stoppoint) { # Command already done for all packages. next; } - elsif (! @exclude) { - # Run command for all packages. - run($sequence[$i], @options); - } - else { - # Run command for only a subset of packages. - run($sequence[$i], @options, - map { "-N$_" } @exclude); - } + + run($sequence[$i], \@packages, \@exclude, @options); } sub run { my $command=shift; + my @packages=@{shift()}; + my @exclude=@{shift()}; my @options=@_; + # Check for override targets in debian/rules and + # run them instead of running the command directly. + my $override_command; + if (rules_explicit_target("override_".$command)) { + $override_command=$command; + # This passes the options through to commands called + # inside the target. + $ENV{DH_INTERNAL_OPTIONS}=join(" ", @options); + $command="debian/rules"; + @options="override_".$override_command; + } + else { + # If some packages are excluded, add flags + # to prevent them from being acted on. + push @options, map { "-N$_" } @exclude; + } + # 3 space indent lines the command being run up under the # sequence name after "dh ". print " ".escape_shell($command, @options)."\n"; @@ -470,6 +449,16 @@ sub run { elsif ($ret) { exit 1; } + + if (defined $override_command) { + delete $ENV{DH_INTERNAL_OPTIONS}; + # Need to handle logging for overriden commands here, + # because the actual debhelper command may not have + # been run by the rules file target. + my %packages=map { $_ => 1 } @packages; + map { delete $packages{$_} } @exclude; + Debian::Debhelper::Dh_Lib::write_log($override_command, keys %packages); + } } } @@ -498,6 +487,31 @@ sub writelog { close LOG; } +{ +my %targets; +my $rules_parsed; + +sub rules_explicit_target { + # Checks if a specified target exists as an explicit target + # in debian/rules. + # Currently this is accomplished via a stupid makefile parser. + my $target=shift; + + if (! $rules_parsed) { + open(IN, ") { + if (/^([a-zA-Z_]+):/) { + $targets{$1}=1; + } + } + close IN; + } + + return exists $targets{$target}; +} + +} + =head1 SEE ALSO L diff --git a/examples/rules.simple b/examples/rules.simple deleted file mode 100755 index ab49db98..00000000 --- a/examples/rules.simple +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/make -f - -build: build-stamp -build-stamp: - dh build - touch build-stamp - -clean: - dh clean - -install: build install-stamp -install-stamp: - dh install - touch install-stamp - -binary-arch: install - dh binary-arch - -binary-indep: install - dh binary-indep - -binary: binary-arch binary-indep -- cgit v1.2.3