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