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