]> git.donarmstrong.com Git - debhelper.git/blob - dh
dh(1): Minor rewording of documentation of override commands. Closes: #560421
[debhelper.git] / dh
1 #!/usr/bin/perl -w
2
3 =head1 NAME
4
5 dh - debhelper command sequencer
6
7 =cut
8
9 use strict;
10 use Debian::Debhelper::Dh_Lib;
11
12 =head1 SYNOPSIS
13
14 B<dh> sequence [B<--with> I<addon>[,I<addon>,...]] [B<--list>] [B<--until> I<cmd>] [B<--before> I<cmd>] [B<--after> I<cmd>] [B<--remaining>] [S<I<debhelper options>>]
15
16 =head1 DESCRIPTION
17
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".
21
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.
26
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
30 those commands again.
31
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.
36
37 If debian/rules contains a target with a name like "override_I<dh_command>",
38 then when it would notmally run I<dh_command>, dh will instead call that
39 target. The override target can then run the command with additional options,
40 or run entirely different commands instead. See examples below. (Note that to
41 use this feature, you should Build-Depend on debhelper 7.0.50 or above.)
42
43 =head1 OPTIONS
44
45 =over 4
46
47 =item B<--with> I<addon>[,I<addon>,...]
48
49 Add the debhelper commands specified by the given addon to appropriate places
50 in the sequence of commands that is run. This option can be repeated more
51 than once, or multiple addons can be listed, separated by commas.
52 This is used when there is a third-party package that provides
53 debhelper commands. See the PROGRAMMING file for documentation about
54 the sequence addon interface.
55
56 =item B<--without> I<addon>
57
58 The inverse of --with, disables using the given addon.
59
60 =item B<--list>, B<-l>
61
62 List all available addons.
63
64 =item B<--until> I<cmd>
65
66 Run commands in the sequence until and including I<cmd>, then stop.
67
68 =item B<--before> I<cmd>
69
70 Run commands in the sequence before I<cmd>, then stop.
71
72 =item B<--after> I<cmd>
73
74 Run commands in the sequence that come after I<cmd>.
75
76 =item B<--remaining>
77
78 Run all commands in the sequence that have yet to be run.
79
80 =item B<--no-act>
81
82 Prints commands that would run for a given sequence, but does not run them.
83
84 =back
85
86 All other options passed to dh are passed on to each command it runs. This
87 can be used to set an option like "-v" or "-X" or "-N", as well as for more
88 specialised options.
89
90 =head1 COMMAND SPECIFICATION
91
92 I<cmd> can be a full name of a debhelper command, or a substring. It'll first
93 search for a command in the sequence exactly matching the name, to avoid any
94 ambiguity. If there are multiple substring matches, the last one in the
95 sequence will be used.
96
97 =cut
98
99 sub command_pos {
100         my $command=shift;
101         my @sequence=@_;
102
103         foreach my $i (0..$#sequence) {
104                 if ($command eq $sequence[$i]) {
105                         return $i;
106                 }
107         }
108
109         my @matches;
110         foreach my $i (0..$#sequence) {
111                 if ($sequence[$i] =~ /\Q$command\E/) {
112                         push @matches, $i;
113                 }
114         }
115         if (! @matches) {
116                 error "command specification \"$command\" does not match any command in the sequence"
117         }
118         else {
119                 return pop @matches;
120         }
121 }
122
123 =head1 EXAMPLES
124
125 To see what commands are included in a sequence, without actually doing
126 anything:
127
128         dh binary-arch --no-act
129
130 This is a very simple rules file, for packages where the default sequences of
131 commands work with no additional options.
132
133         #!/usr/bin/make -f
134         %:
135                 dh $@
136
137 Often you'll want to pass an option to a specific debhelper command. The
138 easy way to do with is by adding an override target for that command.
139         
140         #!/usr/bin/make -f
141         %:
142                 dh $@
143
144         override_dh_strip:
145                 dh_strip -Xfoo
146                 
147         override_dh_installdocs:
148                 dh_installdocs README TODO
149
150 Sometimes the automated dh_auto_configure and dh_auto_build can't guess
151 what to do for a strange package. Here's how to avoid running either
152 and instead run your own commands.
153
154         #!/usr/bin/make -f
155         %:
156                 dh $@
157
158         override_dh_auto_configure:
159                 ./mondoconfig
160
161         override_dh_auto_build:
162                 make universe-explode-in-delight
163
164 Another common case is wanting to do something manually before or
165 after a particular debhelper command is run.
166
167         #!/usr/bin/make -f
168         %:
169                 dh $@
170
171         override_dh_fixperms:
172                 dh_fixperms
173                 chmod 4755 debian/foo/usr/bin/foo
174
175 If your package is a python package, dh will use dh_pysupport by
176 default. This is how to use dh_pycentral instead.
177
178         #!/usr/bin/make -f
179         %:
180                 dh --with python-central $@
181
182 To patch your package using quilt, you can tell dh to use quilt's dh
183 sequence addons like this:
184         
185         #!/usr/bin/make -f
186         %:
187                 dh --with quilt $@
188
189 Here is an example of overriding where the dh_auto_* commands find
190 the package's source, for a package where the source is located in a
191 subdirectory. It also forces use of perl's Module::Build build system,
192 which can be necessary if debhelper wrongly detects that the package
193 uses MakeMaker.
194
195         #!/usr/bin/make -f
196         %:
197                 dh --sourcedirectory=src --buildsystem=perl_build $@
198
199 =cut
200
201 # Stash this away before init modifies it.
202 my @ARGV_orig=@ARGV;
203
204 # python-support is enabled by default, at least for now
205 # (and comes first so python-central loads later and can disable it).
206 unshift @ARGV, "--with=python-support";
207                 
208 # Disable complaints about unknown options for both dh and the commands
209 # it runs. This is done because dh accepts and passes on options that may
210 # be specific to only some debhelper commands.
211 $ENV{DH_IGNORE_UNKNOWN_OPTIONS}=1;
212
213 init(options => {
214         "until=s" => \$dh{UNTIL},
215         "after=s" => \$dh{AFTER},
216         "before=s" => \$dh{BEFORE},
217         "remaining" => \$dh{REMAINING},
218         "with=s" => sub {
219                 my ($option,$value)=@_;
220                 push @{$dh{WITH}},split(",", $value);
221         },
222         "without=s" => sub {
223                 my ($option,$value)=@_;
224                 @{$dh{WITH}} = grep { $_ ne $value } @{$dh{WITH}};
225         },
226         "l" => \$dh{LIST},
227         "list" => \$dh{LIST},
228 });
229 inhibit_log();
230
231 # If make is using a jobserver, but it is not available
232 # to this process, clean out MAKEFLAGS. This avoids
233 # ugly warnings when calling make.
234 if (is_make_jobserver_unavailable()) {
235         clean_jobserver_makeflags();
236 }
237
238 # Definitions of sequences.
239 my %sequences;
240 $sequences{build} = [qw{
241         dh_testdir
242         dh_auto_configure
243         dh_auto_build
244         dh_auto_test
245 }],
246 $sequences{clean} = [qw{
247         dh_testdir
248         dh_auto_clean
249         dh_clean
250 }];
251 $sequences{install} = [@{$sequences{build}}, qw{
252         dh_testroot
253         dh_prep
254         dh_installdirs
255         dh_auto_install
256
257         dh_install
258         dh_installdocs
259         dh_installchangelogs
260         dh_installexamples
261         dh_installman
262
263         dh_installcatalogs
264         dh_installcron
265         dh_installdebconf
266         dh_installemacsen
267         dh_installifupdown
268         dh_installinfo
269         dh_installinit
270         dh_installmenu
271         dh_installmime
272         dh_installmodules
273         dh_installlogcheck
274         dh_installlogrotate
275         dh_installpam
276         dh_installppp
277         dh_installudev
278         dh_installwm
279         dh_installxfonts
280         dh_bugfiles
281         dh_lintian
282         dh_gconf
283         dh_icons
284         dh_perl
285         dh_usrlocal
286
287         dh_link
288         dh_compress
289         dh_fixperms
290 }];
291 my @b=qw{
292         dh_installdeb
293         dh_gencontrol
294         dh_md5sums
295         dh_builddeb
296 };
297 $sequences{'binary-indep'} = [@{$sequences{install}}, @b];
298 $sequences{binary} = [@{$sequences{install}}, qw{
299         dh_strip
300         dh_makeshlibs
301         dh_shlibdeps
302 }, @b];
303 $sequences{'binary-arch'} = [@{$sequences{binary}}];
304
305 # Additional command options
306 my %command_opts;
307
308 # sequence addon interface
309 sub _insert {
310         my $offset=shift;
311         my $existing=shift;
312         my $new=shift;
313         foreach my $sequence (keys %sequences) {
314                 my @list=@{$sequences{$sequence}};
315                 next unless grep $existing, @list;
316                 my @new;
317                 foreach my $command (@list) {
318                         if ($command eq $existing) {
319                                 push @new, $new if $offset < 0;
320                                 push @new, $command;
321                                 push @new, $new if $offset > 0;
322                         }
323                         else {
324                                 push @new, $command;
325                         }
326                 }
327                 $sequences{$sequence}=\@new;
328         }
329 }
330 sub insert_before {
331         _insert(-1, @_);
332 }
333 sub insert_after {
334         _insert(1, @_);
335 }
336 sub remove_command {
337         my $command=shift;
338         foreach my $sequence (keys %sequences) {
339                 $sequences{$sequence}=[grep { $_ ne $command } @{$sequences{$sequence}}];
340         }
341         
342 }
343 sub add_command {
344         my $command=shift;
345         my $sequence=shift;
346         unshift @{$sequences{$sequence}}, $command;
347 }
348 sub add_command_options {
349         my $command=shift;
350         push @{$command_opts{$command}}, @_;
351 }
352 sub remove_command_options {
353         my $command=shift;
354         if (@_) {
355                 # Remove only specified options
356                 if (my $opts = $command_opts{$command}) {
357                         foreach my $opt (@_) {
358                                 $opts = [ grep { $_ ne $opt } @$opts ];
359                         }
360                         $command_opts{$command} = $opts;
361                 }
362         }
363         else {
364                 # Clear all additional options
365                 delete $command_opts{$command};
366         }
367 }
368
369 if ($dh{LIST}) {
370         my %addons;
371
372         for my $inc (@INC) {
373                 eval q{use File::Spec};
374                 my $path = File::Spec->catdir($inc, "Debian/Debhelper/Sequence");
375                 if (-d $path) {
376                         for my $module_path (glob "$path/*.pm") {
377                                 my $name = basename($module_path);
378                                 $name =~ s/\.pm$//;
379                                 $name =~ s/_/-/g;
380                                 $addons{$name} = 1;
381                         }
382                 }
383         }
384
385         for my $name (sort keys %addons) {
386                 print "$name\n";
387         }
388
389         exit 0;
390 }
391
392 foreach my $addon (@{$dh{WITH}}) {
393         my $mod="Debian::Debhelper::Sequence::$addon";
394         $mod=~s/-/_/g;
395         eval "use $mod";
396         if ($@) {
397                 error("unable to load addon $addon: $@");
398         }
399 }
400
401 # Get the sequence of commands to run.
402 if (! @ARGV) {
403         error "specify a sequence to run";
404 }
405 my $sequence=shift;
406 if ($sequence eq 'debian/rules' ||
407     $sequence =~ /^override_dh_/) {
408         # make -B causes the rules file to be run as a target
409         # and support completly empty override targets
410         exit 0
411 }       
412 elsif (! exists $sequences{$sequence}) {
413         error "Unknown sequence $sequence (choose from: ".
414                 join(" ", sort keys %sequences).")";
415 }
416 my @sequence=@{$sequences{$sequence}};
417
418 # The list of all packages that can be acted on.
419 my @packages=@{$dh{DOPACKAGES}};
420
421 # Get the options to pass to commands in the sequence.
422 # Filter out options intended only for this program.
423 my @options;
424 if ($sequence eq 'binary-arch') {
425         push @options, "-a";
426         # as an optimisation, remove from the list any packages
427         # that are not arch dependent
428         my %arch_packages = map { $_ => 1 } getpackages("arch");
429         @packages = grep { $arch_packages{$_} } @packages;
430 }
431 elsif ($sequence eq 'binary-indep') {
432         push @options, "-i";
433         # ditto optimisation for arch indep
434         my %indep_packages = map { $_ => 1 } getpackages("indep");
435         @packages = grep { $indep_packages{$_} } @packages;
436 }
437 while (@ARGV_orig) {
438         my $opt=shift @ARGV_orig;
439         next if $opt eq $sequence;
440         if ($opt =~ /^--?(after|until|before|with|without)$/) {
441                 shift @ARGV_orig;
442                 next;
443         }
444         elsif ($opt =~ /^--?(no-act|remaining|(after|until|before|with|without)=)/) {
445                 next;
446         }
447         push @options, $opt;
448 }
449
450 # Figure out at what point in the sequence to start for each package.
451 my %logged;
452 my %startpoint;
453 foreach my $package (@packages) {
454         my @log=load_log($package, \%logged);
455         if ($dh{AFTER}) {
456                 # Run commands in the sequence that come after the
457                 # specified command.
458                 $startpoint{$package}=command_pos($dh{AFTER}, @sequence) + 1;
459                 # Write a dummy log entry indicating that the specified
460                 # command was, in fact, run. This handles the case where
461                 # no commands remain to run after it, communicating to
462                 # future dh instances that the specified command should not
463                 # be run again.
464                 write_log($sequence[$startpoint{$package}-1], $package);
465         }
466         elsif ($dh{REMAINING}) {
467                 # Start at the beginning so all remaining commands will get
468                 # run.
469                 $startpoint{$package}=0;
470         }
471         else {
472                 # Find the last logged command that is in the sequence, and
473                 # continue with the next command after it. If no logged
474                 # command is in the sequence, we're starting at the beginning..                         
475                 $startpoint{$package}=0;
476 COMMAND:        foreach my $command (reverse @log) {
477                         foreach my $i (0..$#sequence) {
478                                 if ($command eq $sequence[$i]) {
479                                         $startpoint{$package}=$i+1;
480                                         last COMMAND;
481                                 }
482                         }
483                 }
484         }
485 }
486
487 # Figure out what point in the sequence to go to.
488 my $stoppoint=$#sequence;
489 if ($dh{UNTIL}) {
490         $stoppoint=command_pos($dh{UNTIL}, @sequence);
491 }
492 elsif ($dh{BEFORE}) {
493         $stoppoint=command_pos($dh{BEFORE}, @sequence) - 1;
494 }
495
496 # Now run the commands in the sequence.
497 foreach my $i (0..$stoppoint) {
498         # Figure out which packages need to run this command.
499         my @exclude;
500         foreach my $package (@packages) {
501                 if ($startpoint{$package} > $i ||
502                     $logged{$package}{$sequence[$i]}) {
503                         push @exclude, $package;
504                 }
505         }
506         
507         if (@exclude eq @packages) {
508                 # Command already done for all packages.
509                 next;
510         }
511
512         run($sequence[$i], \@packages, \@exclude, @options);
513 }
514
515 sub run {
516         my $command=shift;
517         my @packages=@{shift()};
518         my @exclude=@{shift()};
519         my @options=@_;
520         
521         # If some packages are excluded, add flags
522         # to prevent them from being acted on.
523         push @options, map { "-N$_" } @exclude;
524
525         # Check for override targets in debian/rules and
526         # run them instead of running the command directly.
527         my $override_command;
528         if (rules_explicit_target("override_".$command)) {
529                 $override_command=$command;
530                 # This passes the options through to commands called
531                 # inside the target.
532                 $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options);
533                 $command="debian/rules";
534                 @options="override_".$override_command;
535         }
536         else {
537                 # Pass additional command options if any
538                 unshift @options, @{$command_opts{$command}} if exists $command_opts{$command};
539         }
540
541         # 3 space indent lines the command being run up under the 
542         # sequence name after "dh ".
543         print "   ".escape_shell($command, @options)."\n";
544
545         if (! $dh{NO_ACT}) {
546                 my $ret=system($command, @options);
547                 if ($ret >> 8 != 0) {
548                         exit $ret >> 8;
549                 }
550                 elsif ($ret) {
551                         exit 1;
552                 }
553
554                 if (defined $override_command) {
555                         delete $ENV{DH_INTERNAL_OPTIONS};
556                         # Need to handle logging for overriden commands here,
557                         # because the actual debhelper command may not have
558                         # been run by the rules file target.
559                         # (But avoid logging for dh_clean since it removes
560                         # the log earlier.)
561                         if ($override_command ne 'dh_clean') {
562                                 my %packages=map { $_ => 1 } @packages;
563                                 map { delete $packages{$_} } @exclude;
564                                 write_log($override_command, keys %packages);
565                         }
566                 }
567         }
568 }
569
570 {
571 my %targets;
572 my $rules_parsed;
573
574 sub rules_explicit_target {
575         # Checks if a specified target exists as an explicit target
576         # in debian/rules. 
577         my $target=shift;
578         
579         if (! $rules_parsed) {  
580                 my $processing_targets = 0;
581                 my $not_a_target = 0;
582                 open(MAKE, "LC_ALL=C make -Rrnpsf debian/rules debhelper-fail-me 2>/dev/null |");
583                 while (<MAKE>) {
584                         if ($processing_targets) {
585                                 if (/^# Not a target:/) {
586                                         $not_a_target = 1;
587                                 }
588                                 else {
589                                         if (!$not_a_target && /^([^#:]+)::?/) {
590                                                 # Target is defined.
591                                                 # NOTE: if it is a depenency
592                                                 # of .PHONY it will be
593                                                 # defined too but that's ok.
594                                                 $targets{$1} = 1;
595                                         }
596                                         # "Not a target:" is always followed by
597                                         # a target name, so resetting this one
598                                         # here is safe.
599                                         $not_a_target = 0;
600                                 }
601                         } elsif (/^# Files$/) {
602                                 $processing_targets = 1;
603                         }
604                 }
605                 close MAKE;
606                 $rules_parsed = 1;
607         }
608
609         return exists $targets{$target};
610 }
611
612 }
613
614 =head1 SEE ALSO
615
616 L<debhelper(7)>
617
618 This program is a part of debhelper.
619
620 =head1 AUTHOR
621
622 Joey Hess <joeyh@debian.org>
623
624 =cut