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 early. Just make sure that at
163 least dh_prep is run from the squence first, and be sure to use the
164 B<--remaining> option to ensure that commands that normally come before
165 those in the sequence are still run.
168 dh install --until dh_prep
169 dh_installdocs README TODO
170 dh_installchangelogs Changes
171 dh install --remaining
175 dh binary-arch --remaining
179 # Stash this away before init modifies it.
185 # Definitions of sequences.
187 $sequences{build} = [qw{
193 $sequences{clean} = [qw{
198 $sequences{install} = [@{$sequences{build}}, qw{
247 $sequences{'binary-indep'} = [@{$sequences{install}}, @b];
248 $sequences{binary} = [@{$sequences{install}}, qw{
253 $sequences{'binary-arch'} = [@{$sequences{binary}}];
255 # Third-party commands can be listed in the sequences, but should be
256 # listed here as well. They will not be run if not present.
262 # Get the sequence of commands to run.
264 error "specify a sequence to run";
267 if (! exists $sequences{$sequence}) {
268 error "Unknown sequence $sequence (chose from: ".
269 join(" ", sort keys %sequences).")";
271 my @sequence=@{$sequences{$sequence}};
273 # Get the options to pass to commands in the sequence.
274 # Filter out options intended only for this program.
276 if ($sequence eq 'binary-arch') {
279 elsif ($sequence eq 'binary-indep') {
283 my $opt=shift @ARGV_orig;
284 next if $opt eq $sequence;
285 if ($opt =~ /^--?(after|until|before)$/) {
289 elsif ($opt =~ /^--?(no-act|remaining|(after|until|before)=)/) {
295 # Figure out at what point in the sequence to start for each package.
298 foreach my $package (@{$dh{DOPACKAGES}}) {
299 my @log=loadlog($package);
301 # Run commands in the sequence that come after the
303 $startpoint{$package}=command_pos($dh{AFTER}, @sequence) + 1;
304 # Write a dummy log entry indicating that the specified
305 # command was, in fact, run. This handles the case where
306 # no commands remain to run after it, communicating to
307 # future dh instances that the specified command should not
309 writelog($package, $sequence[$startpoint{$package}-1]);
311 elsif ($dh{REMAINING}) {
312 # Start at the beginning so all remaining commands will get
314 $startpoint{$package}=0;
317 # Find the last logged command that is in the sequence, and
318 # continue with the next command after it. If no logged
319 # command is in the sequence, we're starting at the beginning..
320 $startpoint{$package}=0;
321 COMMAND: foreach my $command (reverse @log) {
322 foreach my $i (0..$#sequence) {
323 if ($command eq $sequence[$i]) {
324 $startpoint{$package}=$i+1;
332 # Figure out what point in the sequence to go to.
333 my $stoppoint=$#sequence;
335 $stoppoint=command_pos($dh{UNTIL}, @sequence);
337 elsif ($dh{BEFORE}) {
338 $stoppoint=command_pos($dh{BEFORE}, @sequence) - 1;
341 # Now run the commands in the sequence.
342 foreach my $i (0..$stoppoint) {
343 # Figure out which packages need to run this command.
345 foreach my $package (@{$dh{DOPACKAGES}}) {
346 if ($startpoint{$package} > $i ||
347 $logged{$package}{$sequence[$i]}) {
348 push @exclude, $package;
352 if (@exclude eq @{$dh{DOPACKAGES}}) {
353 # Command already done for all packages.
357 # Run command for all packages.
358 run($sequence[$i], @options);
361 # Run command for only a subset of packages.
362 run($sequence[$i], @options,
363 map { "-N$_" } @exclude);
371 # If a third party command is not in /usr/bin, don't try to run it.
372 if ($thirdparty{$command} && ! -x "/usr/bin/$command") {
376 # 3 space indent lines the command being run up under the
377 # sequence name after "dh ".
378 print " ".escape_shell($command, @options)."\n";
381 my $ret=system($command, @options);
382 if ($ret >> 8 != 0) {
393 my $ext=pkgext($package);
396 open(LOG, "<", "debian/${ext}debhelper.log") || return;
400 $logged{$package}{$_}=1;
409 my $ext=pkgext($package);
411 open(LOG, ">>", "debian/${ext}debhelper.log") || error("failed to write to log");
420 This program is a part of debhelper.
424 Joey Hess <joeyh@debian.org>