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