5 dh - debhelper command sequencer
10 use Debian::Debhelper::Dh_Lib;
14 B<dh> sequence [B<--until> I<cmd>] [B<--before> I<cmd>] [B<--after> I<cmd>] [B<--remaining> [S<I<debhelper options>>]
18 dh runs a sequence of debhelper commands. The supported sequences
19 correspond to the targets of a debian/rules file: "build", "clean",
20 "install", "binary-arch", "binary-indep", and "binary".
22 Commands in the binary-indep sequence are passed the "-i" option to ensure
23 they only work on binary independent packages, and commands in the
24 binary-arch sequences are passed the "-a" option to ensure they only work
25 on architecture dependent packages.
27 Each debhelper command will record when it's successfully run in
28 debian/package.debhelper.log. (Which dh_clean deletes.) So dh can tell
29 which commands have already been run, for which packages, and skip running
32 Each time dh is run, it examines the log, and finds the last logged command
33 that is in the specified sequence. It then continues with the next command
34 in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining>
35 options can override this behavior.
41 =item B<--until> I<cmd>
43 Run commands in the sequence until and including I<cmd>, then stop.
45 =item B<--before> I<cmd>
47 Run commands in the sequence before I<cmd>, then stop.
49 =item B<--after> I<cmd>
51 Run commands in the sequence that come after I<cmd>.
55 Run all commands in the sequence that have yet to be run.
59 All other options passed to dh are passed on to each command it runs. This
60 can be used to set an option like "-v" or "-X" or "-N", as well as for more
63 =head1 COMMAND SPECIFICATION
65 I<cmd> can be a full name of a debhelper command, or a substring. It'll first
66 search for a command in the sequence exactly matching the name, to avoid any
67 ambiguity. If there are multiple substring matches, the last one in the
68 sequence will be used.
76 foreach my $i (0..$#sequence) {
77 if ($command eq $sequence[$i]) {
83 foreach my $i (0..$#sequence) {
84 if ($sequence[$i] =~ /\Q$command\E/) {
89 error "command specification \"$command\" does not match any command in the sequence"
98 To see what commands are included in a sequence, without actually doing
101 dh binary-arch --no-act
103 This is a very simple rules file, for packages where the default seqences of
104 commands work with no additional options.
110 This is a simple rules file that is a good starting place for customisation.
111 (It's also available in F</usr/share/doc/debhelper/examples/rules.simple>
127 binary-indep: install
130 binary: binary-arch binary-indep
132 Often you'll want to pass an option to ./configure. This uses dh to run all
133 commands before L<dh_auto_configure(1)>, then runs that command by hand,
134 and then finished up by running the rest of the sequence. You could also
135 run ./configure by hand, instead of bothering with using dh_auto_configure.
136 And if necessary, you can add commands to run automake, etc here too.
139 dh build --before configure
140 dh_auto_configure --kitchen-sink=yes
141 dh build --after configure
143 Here's how to skip two automated in a row (configure and build), and
144 instead run the commands by hand.
147 dh build --before configure
149 make universe-explode-in-delight
150 dh build --after build
152 Another common case is wanting to run some code manually after a particular
153 debhelper command is run.
156 dh install --until dh_fixperms
157 # dh_fixperms has run, now override it for one program
158 chmod 4755 debian/foo/usr/bin/foo
160 dh install --after dh_fixperms
162 It's also fine to run debhelper commands before starting a dh sequence.
163 Just be sure to use the B<--remaining> option to ensure that commands
164 that normally come before those in the sequence are still run.
167 dh_installdocs README TODO
168 dh_installchangelogs Changes
169 dh install --remaining
173 dh binary-arch --remaining
177 # Stash this away before init modifies it.
183 # Definitions of sequences.
185 $sequences{build} = [qw{
191 $sequences{clean} = [qw{
196 $sequences{install} = [@{$sequences{build}}, qw{
245 $sequences{'binary-indep'} = [@{$sequences{install}}, @b];
246 $sequences{binary} = [@{$sequences{install}}, qw{
251 $sequences{'binary-arch'} = [@{$sequences{binary}}];
253 # Third-party commands can be listed in the sequences, but should be
254 # listed here as well. They will not be run if not present.
260 # Get the sequence of commands to run.
262 error "specify a sequence to run";
265 if (! exists $sequences{$sequence}) {
266 error "Unknown sequence $sequence (chose from: ".
267 join(" ", sort keys %sequences).")";
269 my @sequence=@{$sequences{$sequence}};
271 # Get the options to pass to commands in the sequence.
272 # Filter out options intended only for this program.
274 if ($sequence eq 'binary-arch') {
277 elsif ($sequence eq 'binary-indep') {
281 my $opt=shift @ARGV_orig;
282 next if $opt eq $sequence;
283 if ($opt =~ /^--?(after|until|before)$/) {
287 elsif ($opt =~ /^--?(no-act|remaining|(after|until|before)=)/) {
293 # Figure out at what point in the sequence to start for each package.
296 foreach my $package (@{$dh{DOPACKAGES}}) {
297 my @log=loadlog($package);
299 # Run commands in the sequence that come after the
301 $startpoint{$package}=command_pos($dh{AFTER}, @sequence) + 1;
302 # Write a dummy log entry indicating that the specified
303 # command was, in fact, run. This handles the case where
304 # no commands remain to run after it, communicating to
305 # future dh instances that the specified command should not
307 writelog($package, $sequence[$startpoint{$package}-1]);
309 elsif ($dh{REMAINING}) {
310 # Start at the beginning so all remaining commands will get
312 $startpoint{$package}=0;
315 # Find the last logged command that is in the sequence, and
316 # continue with the next command after it. If no logged
317 # command is in the sequence, we're starting at the beginning..
318 $startpoint{$package}=0;
319 COMMAND: foreach my $command (reverse @log) {
320 foreach my $i (0..$#sequence) {
321 if ($command eq $sequence[$i]) {
322 $startpoint{$package}=$i+1;
330 # Figure out what point in the sequence to go to.
331 my $stoppoint=$#sequence;
333 $stoppoint=command_pos($dh{UNTIL}, @sequence);
335 elsif ($dh{BEFORE}) {
336 $stoppoint=command_pos($dh{BEFORE}, @sequence) - 1;
339 # Now run the commands in the sequence.
340 foreach my $i (0..$stoppoint) {
341 # Figure out which packages need to run this command.
343 foreach my $package (@{$dh{DOPACKAGES}}) {
344 if ($startpoint{$package} > $i ||
345 $logged{$package}{$sequence[$i]}) {
346 push @exclude, $package;
350 if (@exclude eq @{$dh{DOPACKAGES}}) {
351 # Command already done for all packages.
355 # Run command for all packages.
356 run($sequence[$i], @options);
359 # Run command for only a subset of packages.
360 run($sequence[$i], @options,
361 map { "-N$_" } @exclude);
369 # If a third party command is not in /usr/bin, don't try to run it.
370 if ($thirdparty{$command} && ! -x "/usr/bin/$command") {
374 # 3 space indent lines the command being run up under the
375 # sequence name after "dh ".
376 print " ".escape_shell($command, @options)."\n";
379 my $ret=system($command, @options);
380 if ($ret >> 8 != 0) {
391 my $ext=pkgext($package);
394 open(LOG, "<", "debian/${ext}debhelper.log") || return;
398 $logged{$package}{$_}=1;
407 my $ext=pkgext($package);
409 open(LOG, ">>", "debian/${ext}debhelper.log") || error("failed to write to log");
418 This program is a part of debhelper.
422 Joey Hess <joeyh@debian.org>