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