]> git.donarmstrong.com Git - debhelper.git/blob - dh
speling
[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> I<sequence> [B<--with> I<addon>[B<,>I<addon> ...]] [B<--list>] [S<I<debhelper options>>]
15
16 =head1 DESCRIPTION
17
18 B<dh> runs a sequence of debhelper commands. The supported I<sequence>s
19 correspond to the targets of a F<debian/rules> file: B<build-arch>,
20 B<build-indep>, B<build>, B<clean>, B<install-indep>, B<install-arch>,
21 B<install>, B<binary-arch>, B<binary-indep>, and B<binary>.
22
23 =head1 OVERRIDE TARGETS
24
25 A F<debian/rules> file using B<dh> can override the command that is run
26 at any step in a sequence, by defining an override target.
27
28 To override I<dh_command>, add a target named B<override_>I<dh_command> to
29 the rules file. When it would normally run I<dh_command>, B<dh> will
30 instead call that target. The override target can then run the command with
31 additional options, or run entirely different commands instead. See
32 examples below.
33 (Note that to use this feature, you should Build-Depend on
34 debhelper 7.0.50 or above.)
35
36 Override targets can also be defined to run only when building
37 architecture dependent or architecture independent packages.
38 Use targets with names like B<override_>I<dh_command>B<-arch>
39 and B<override_>I<dh_command>B<-indep>.
40 (Note that to use this feature, you should Build-Depend on
41 debhelper 8.9.7 or above.)
42
43 =head1 OPTIONS
44
45 =over 4
46
47 =item B<--with> I<addon>[B<,>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 F<PROGRAMMING> file for documentation about
54 the sequence addon interface.
55
56 =item B<--without> I<addon>
57
58 The inverse of B<--with>, disables using the given addon.
59
60 =item B<--list>, B<-l>
61
62 List all available addons.
63
64 =item B<--no-act>
65
66 Prints commands that would run for a given sequence, but does not run them.
67
68 =back
69
70 Other options passed to B<dh> are passed on to each command it runs. This
71 can be used to set an option like B<-v> or B<-X> or B<-N>, as well as for more
72 specialised options.
73
74 =head1 EXAMPLES
75
76 To see what commands are included in a sequence, without actually doing
77 anything:
78
79         dh binary-arch --no-act
80
81 This is a very simple rules file, for packages where the default sequences of
82 commands work with no additional options.
83
84         #!/usr/bin/make -f
85         %:
86                 dh $@
87
88 Often you'll want to pass an option to a specific debhelper command. The
89 easy way to do with is by adding an override target for that command.
90
91         #!/usr/bin/make -f
92         %:
93                 dh $@
94         
95         override_dh_strip:
96                 dh_strip -Xfoo
97         
98         override_dh_auto_configure:
99                 dh_auto_configure -- --with-foo --disable-bar
100
101 Sometimes the automated L<dh_auto_configure(1)> and L<dh_auto_build(1)>
102 can't guess what to do for a strange package. Here's how to avoid running
103 either and instead run your own commands.
104
105         #!/usr/bin/make -f
106         %:
107                 dh $@
108
109         override_dh_auto_configure:
110                 ./mondoconfig
111
112         override_dh_auto_build:
113                 make universe-explode-in-delight
114
115 Another common case is wanting to do something manually before or
116 after a particular debhelper command is run.
117
118         #!/usr/bin/make -f
119         %:
120                 dh $@
121
122         override_dh_fixperms:
123                 dh_fixperms
124                 chmod 4755 debian/foo/usr/bin/foo
125
126 If your package uses autotools and you want to freshen F<config.sub> and
127 F<config.guess> with newer versions from the B<autotools-dev> package
128 at build time, you can use some commands provided in B<autotools-dev>
129 that automate it, like this.
130
131         #!/usr/bin/make -f
132         %:
133                 dh $@ --with autotools_dev
134
135 Python tools are not run by dh by default, due to the continual change
136 in that area. (Before compatibility level v9, dh does run B<dh_pysupport>.)
137 Here is how to use B<dh_python2>.
138
139         #!/usr/bin/make -f
140         %:
141                 dh $@ --with python2
142
143 Here is how to force use of Perl's B<Module::Build> build system,
144 which can be necessary if debhelper wrongly detects that the package
145 uses MakeMaker.
146
147         #!/usr/bin/make -f
148         %:
149                 dh $@ --buildsystem=perl_build
150
151 Here is an example of overriding where the B<dh_auto_>I<*> commands find
152 the package's source, for a package where the source is located in a
153 subdirectory.
154
155         #!/usr/bin/make -f
156         %:
157                 dh $@ --sourcedirectory=src
158
159 And here is an example of how to tell the B<dh_auto_>I<*> commands to build
160 in a subdirectory, which will be removed on B<clean>.
161
162         #!/usr/bin/make -f
163         %:
164                 dh $@ --builddirectory=build
165
166 If your package can be built in parallel, you can support parallel building
167 as follows. Then B<dpkg-buildpackage -j> will work.
168
169         #!/usr/bin/make -f
170         %:
171                 dh $@ --parallel
172
173 Here is a way to prevent B<dh> from running several commands that you don't
174 want it to run, by defining empty override targets for each command.
175
176         #!/usr/bin/make -f
177         %:
178                 dh $@
179         
180         # Commands not to run:
181         override_dh_auto_test override_dh_compress override_dh_fixperms:
182
183 A long build process for a separate documentation package can
184 be separated out using architecture independent overrides.
185 These will be skipped when running build-arch and binary-arch sequences.
186
187         #!/usr/bin/make -f
188         %:
189                 dh $@
190         
191         override_dh_auto_build-indep:
192                 $(MAKE) -C docs
193
194         # No tests needed for docs
195         override_dh_auto_test-indep:
196
197         override_dh_auto_install-indep:
198                 $(MAKE) -C docs install
199
200 Adding to the example above, suppose you need to chmod a file, but only
201 when building the architecture dependent package, as it's not present
202 when building only documentation.
203
204         override_dh_fixperms-arch:
205                 dh_fixperms
206                 chmod 4755 debian/foo/usr/bin/foo
207
208 =head1 INTERNALS
209
210 If you're curious about B<dh>'s internals, here's how it works under the hood.
211
212 Each debhelper command will record when it's successfully run in
213 F<debian/package.debhelper.log>. (Which B<dh_clean> deletes.) So B<dh> can tell
214 which commands have already been run, for which packages, and skip running
215 those commands again.
216
217 Each time B<dh> is run, it examines the log, and finds the last logged command
218 that is in the specified sequence. It then continues with the next command
219 in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining>
220 options can override this behavior.
221
222 A sequence can also run dependent targets in debian/rules.  For
223 example, the "binary" sequence runs the "install" target.
224
225 B<dh> uses the B<DH_INTERNAL_OPTIONS> environment variable to pass information
226 through to debhelper commands that are run inside override targets. The
227 contents (and indeed, existence) of this environment variable, as the name
228 might suggest, is subject to change at any time.
229
230 Commands in the B<build-indep>, B<install-indep> and B<binary-indep>
231 sequences are passed the B<-i> option to ensure they only work on
232 architecture independent packages, and commands in the B<build-arch>,
233 B<install-arch> and B<binary-arch> sequences are passed the B<-a>
234 option to ensure they only work on architecture dependent packages.
235
236 =head1 DEPRECATED OPTIONS
237
238 The following options are deprecated. It's much 
239 better to use override targets instead.
240
241 =over 4
242
243 =item B<--until> I<cmd>
244
245 Run commands in the sequence until and including I<cmd>, then stop.
246
247 =item B<--before> I<cmd>
248
249 Run commands in the sequence before I<cmd>, then stop.
250
251 =item B<--after> I<cmd>
252
253 Run commands in the sequence that come after I<cmd>.
254
255 =item B<--remaining>
256
257 Run all commands in the sequence that have yet to be run.
258
259 =back
260
261 In the above options, I<cmd> can be a full name of a debhelper command, or
262 a substring. It'll first search for a command in the sequence exactly
263 matching the name, to avoid any ambiguity. If there are multiple substring
264 matches, the last one in the sequence will be used.
265
266 =cut
267
268 # Stash this away before init modifies it.
269 my @ARGV_orig=@ARGV;
270
271 if (compat(8, 1)) {
272         # python-support was enabled by default before v9.
273         # (and comes first so python-central loads later and can disable it).
274         unshift @ARGV, "--with=python-support";
275 }
276                 
277 init(options => {
278                 "until=s" => \$dh{UNTIL},
279                 "after=s" => \$dh{AFTER},
280                 "before=s" => \$dh{BEFORE},
281                 "remaining" => \$dh{REMAINING},
282                 "with=s" => sub {
283                         my ($option,$value)=@_;
284                         push @{$dh{WITH}},split(",", $value);
285                 },
286                 "without=s" => sub {
287                         my ($option,$value)=@_;
288                         @{$dh{WITH}} = grep { $_ ne $value } @{$dh{WITH}};
289                 },
290                 "l" => \&list_addons,
291                 "list" => \&list_addons,
292         },
293         # Disable complaints about unknown options; they are passed on to 
294         # the debhelper commands.
295         ignore_unknown_options => 1,
296         # Bundling does not work well since there are unknown options.
297         bundling => 0,
298 );
299 inhibit_log();
300 set_buildflags();
301 warn_deprecated();
302
303 # If make is using a jobserver, but it is not available
304 # to this process, clean out MAKEFLAGS. This avoids
305 # ugly warnings when calling make.
306 if (is_make_jobserver_unavailable()) {
307         clean_jobserver_makeflags();
308 }
309
310 # Process the sequence parameter.
311 my $sequence;
312 if (! compat(7)) {
313         # From v8, the sequence is the very first parameter.
314         $sequence=shift @ARGV_orig;
315         if (defined $sequence && $sequence=~/^-/) {
316                 error "Unknown sequence $sequence (options should not come before the sequence)";
317         }
318 }
319 else {
320         # Before v8, the sequence could be at any position in the parameters,
321         # so was what was left after parsing.
322         $sequence=shift;
323         if (defined $sequence) {
324                 @ARGV_orig=grep { $_ ne $sequence } @ARGV_orig;
325         }
326 }
327 if (! defined $sequence) {
328         error "specify a sequence to run";
329 }
330 # make -B causes the rules file to be run as a target.
331 # Also support completly empty override targets.
332 # Note: it's not safe to use rules_explicit_target before this check,
333 # since it causes dh to be run.
334 my $dummy_target="debhelper-fail-me";
335 if ($sequence eq 'debian/rules' ||
336     $sequence =~ /^override_dh_/ ||
337     $sequence eq $dummy_target) {
338         exit 0;
339 }
340
341
342 # Definitions of sequences.
343 my %sequences;
344 my @bd_minimal = qw{
345         dh_testdir
346 };
347 my @bd = qw{
348         dh_testdir
349         dh_auto_configure
350         dh_auto_build
351         dh_auto_test
352 };
353 my @i = qw{
354         dh_testroot
355         dh_prep
356         dh_installdirs
357         dh_auto_install
358
359         dh_install
360         dh_installdocs
361         dh_installchangelogs
362         dh_installexamples
363         dh_installman
364
365         dh_installcatalogs
366         dh_installcron
367         dh_installdebconf
368         dh_installemacsen
369         dh_installifupdown
370         dh_installinfo
371         dh_installinit
372         dh_installmenu
373         dh_installmime
374         dh_installmodules
375         dh_installlogcheck
376         dh_installlogrotate
377         dh_installpam
378         dh_installppp
379         dh_installudev
380         dh_installwm
381         dh_installxfonts
382         dh_installgsettings
383         dh_bugfiles
384         dh_ucf
385         dh_lintian
386         dh_gconf
387         dh_icons
388         dh_perl
389         dh_usrlocal
390
391         dh_link
392         dh_compress
393         dh_fixperms
394 };
395 my @ba=qw{
396         dh_strip
397         dh_makeshlibs
398         dh_shlibdeps
399 };
400 if (! getpackages("arch")) {
401         @ba=();
402 }
403 my @b=qw{
404         dh_installdeb
405         dh_gencontrol
406         dh_md5sums
407         dh_builddeb
408 };
409 $sequences{clean} = [qw{
410         dh_testdir
411         dh_auto_clean
412         dh_clean
413 }];
414 $sequences{'build-indep'} = [@bd];
415 $sequences{'build-arch'} = [@bd];
416 if (! compat(8)) {
417         # From v9, sequences take standard rules targets into account.
418         $sequences{build} = [@bd_minimal, rules("build-arch"), rules("build-indep")];
419         $sequences{'install-indep'} = [rules("build-indep"), @i];
420         $sequences{'install-arch'} = [rules("build-arch"), @i];
421         $sequences{'install'} = [rules("build"), rules("install-arch"), rules("install-indep")];
422         $sequences{'binary-indep'} = [rules("install-indep"), @b];
423         $sequences{'binary-arch'} = [rules("install-arch"), @ba, @b];
424         $sequences{binary} = [rules("install"), rules("binary-arch"), rules("binary-indep")];
425 }
426 else {
427         $sequences{build} = [@bd];
428         $sequences{'install'} = [@{$sequences{build}}, @i];
429         $sequences{'install-indep'} = [@{$sequences{'build-indep'}}, @i];
430         $sequences{'install-arch'} = [@{$sequences{'build-arch'}}, @i];
431         $sequences{binary} = [@{$sequences{install}}, @ba, @b];
432         $sequences{'binary-indep'} = [@{$sequences{'install-indep'}}, @b];
433         $sequences{'binary-arch'} = [@{$sequences{'install-arch'}}, @ba, @b];
434 }
435
436 # Additional command options
437 my %command_opts;
438
439 # sequence addon interface
440 sub _insert {
441         my $offset=shift;
442         my $existing=shift;
443         my $new=shift;
444         foreach my $sequence (keys %sequences) {
445                 my @list=@{$sequences{$sequence}};
446                 next unless grep $existing, @list;
447                 my @new;
448                 foreach my $command (@list) {
449                         if ($command eq $existing) {
450                                 push @new, $new if $offset < 0;
451                                 push @new, $command;
452                                 push @new, $new if $offset > 0;
453                         }
454                         else {
455                                 push @new, $command;
456                         }
457                 }
458                 $sequences{$sequence}=\@new;
459         }
460 }
461 sub insert_before {
462         _insert(-1, @_);
463 }
464 sub insert_after {
465         _insert(1, @_);
466 }
467 sub remove_command {
468         my $command=shift;
469         foreach my $sequence (keys %sequences) {
470                 $sequences{$sequence}=[grep { $_ ne $command } @{$sequences{$sequence}}];
471         }
472         
473 }
474 sub add_command {
475         my $command=shift;
476         my $sequence=shift;
477         unshift @{$sequences{$sequence}}, $command;
478 }
479 sub add_command_options {
480         my $command=shift;
481         push @{$command_opts{$command}}, @_;
482 }
483 sub remove_command_options {
484         my $command=shift;
485         if (@_) {
486                 # Remove only specified options
487                 if (my $opts = $command_opts{$command}) {
488                         foreach my $opt (@_) {
489                                 $opts = [ grep { $_ ne $opt } @$opts ];
490                         }
491                         $command_opts{$command} = $opts;
492                 }
493         }
494         else {
495                 # Clear all additional options
496                 delete $command_opts{$command};
497         }
498 }
499
500 sub list_addons {
501         my %addons;
502
503         for my $inc (@INC) {
504                 eval q{use File::Spec};
505                 my $path = File::Spec->catdir($inc, "Debian/Debhelper/Sequence");
506                 if (-d $path) {
507                         for my $module_path (glob "$path/*.pm") {
508                                 my $name = basename($module_path);
509                                 $name =~ s/\.pm$//;
510                                 $name =~ s/_/-/g;
511                                 $addons{$name} = 1;
512                         }
513                 }
514         }
515
516         for my $name (sort keys %addons) {
517                 print "$name\n";
518         }
519
520         exit 0;
521 }
522
523 # Load addons, which can modify sequences.
524 foreach my $addon (@{$dh{WITH}}) {
525         my $mod="Debian::Debhelper::Sequence::$addon";
526         $mod=~s/-/_/g;
527         eval "use $mod";
528         if ($@) {
529                 error("unable to load addon $addon: $@");
530         }
531 }
532
533 if (! exists $sequences{$sequence}) {
534         error "Unknown sequence $sequence (choose from: ".
535                 join(" ", sort keys %sequences).")";
536 }
537 my @sequence=optimize_sequence(@{$sequences{$sequence}});
538
539 # The list of all packages that can be acted on.
540 my @packages=@{$dh{DOPACKAGES}};
541
542 # Get the options to pass to commands in the sequence.
543 # Filter out options intended only for this program.
544 my @options;
545 if ($sequence eq 'build-arch' ||
546     $sequence eq 'install-arch' ||
547     $sequence eq 'binary-arch') {
548         push @options, "-a";
549         # as an optimisation, remove from the list any packages
550         # that are not arch dependent
551         my %arch_packages = map { $_ => 1 } getpackages("arch");
552         @packages = grep { $arch_packages{$_} } @packages;
553 }
554 elsif ($sequence eq 'build-indep' ||
555        $sequence eq 'install-indep' ||
556        $sequence eq 'binary-indep') {
557         push @options, "-i";
558         # ditto optimisation for arch indep
559         my %indep_packages = map { $_ => 1 } getpackages("indep");
560         @packages = grep { $indep_packages{$_} } @packages;
561 }
562 while (@ARGV_orig) {
563         my $opt=shift @ARGV_orig;
564         if ($opt =~ /^--?(after|until|before|with|without)$/) {
565                 shift @ARGV_orig;
566                 next;
567         }
568         elsif ($opt =~ /^--?(no-act|remaining|(after|until|before|with|without)=)/) {
569                 next;
570         }
571         elsif ($opt=~/^-/) {
572                 push @options, "-O".$opt;
573         }
574         elsif (@options) {
575                 if ($options[$#options]=~/^-O--/) {
576                         $options[$#options].="=".$opt;
577                 }
578                 else {
579                         $options[$#options].=$opt;
580                 }
581         }
582 }
583
584 # Figure out at what point in the sequence to start for each package.
585 my %logged;
586 my %startpoint;
587 foreach my $package (@packages) {
588         my @log=load_log($package, \%logged);
589         if ($dh{AFTER}) {
590                 # Run commands in the sequence that come after the
591                 # specified command.
592                 $startpoint{$package}=command_pos($dh{AFTER}, @sequence) + 1;
593                 # Write a dummy log entry indicating that the specified
594                 # command was, in fact, run. This handles the case where
595                 # no commands remain to run after it, communicating to
596                 # future dh instances that the specified command should not
597                 # be run again.
598                 write_log($sequence[$startpoint{$package}-1], $package);
599         }
600         elsif ($dh{REMAINING}) {
601                 # Start at the beginning so all remaining commands will get
602                 # run.
603                 $startpoint{$package}=0;
604         }
605         else {
606                 # Find the last logged command that is in the sequence, and
607                 # continue with the next command after it. If no logged
608                 # command is in the sequence, we're starting at the beginning..                         
609                 $startpoint{$package}=0;
610 COMMAND:        foreach my $command (reverse @log) {
611                         foreach my $i (0..$#sequence) {
612                                 if ($command eq $sequence[$i]) {
613                                         $startpoint{$package}=$i+1;
614                                         last COMMAND;
615                                 }
616                         }
617                 }
618         }
619 }
620
621 # Figure out what point in the sequence to go to.
622 my $stoppoint=$#sequence;
623 if ($dh{UNTIL}) {
624         $stoppoint=command_pos($dh{UNTIL}, @sequence);
625 }
626 elsif ($dh{BEFORE}) {
627         $stoppoint=command_pos($dh{BEFORE}, @sequence) - 1;
628 }
629
630 # Now run the commands in the sequence.
631 foreach my $i (0..$stoppoint) {
632         my $command=$sequence[$i];
633
634         # Figure out which packages need to run this command.
635         my @todo;
636         my @opts=@options;
637         foreach my $package (@packages) {
638                 if ($startpoint{$package} > $i ||
639                     $logged{$package}{$sequence[$i]}) {
640                         push @opts, "-N$package";
641                 }
642                 else {
643                         push @todo, $package;
644                 }
645         }
646         next unless @todo;
647
648         my $rules_target = rules_target($command);
649         if (defined $rules_target) {
650                 # Don't pass DH_ environment variables, since this is
651                 # a fresh invocation of debian/rules and any sub-dh commands.
652                 delete $ENV{DH_INTERNAL_OPTIONS};
653                 delete $ENV{DH_INTERNAL_OVERRIDE};
654                 run("debian/rules", $rules_target);
655                 next;
656         }
657         
658         # Check for override targets in debian/rules, and run instead of
659         # the usual command. (The non-arch-specific override is tried first,
660         # for simplest semantics; mixing it with arch-specific overrides
661         # makes little sense.)
662         foreach my $override_type (undef, "arch", "indep") {
663                 @todo = run_override($override_type, $command, \@todo, @opts);
664         }
665         next unless @todo;
666
667         run($command, @opts);
668 }
669
670 sub run {
671         my $command=shift;
672         my @options=@_;
673
674         # Include additional command options if any
675         unshift @options, @{$command_opts{$command}}
676                 if exists $command_opts{$command};
677
678         # 3 space indent lines the command being run up under the
679         # sequence name after "dh ".
680         print "   ".escape_shell($command, @options)."\n";
681
682         return if $dh{NO_ACT};
683                         
684         my $ret=system($command, @options);
685         if ($ret >> 8 != 0) {
686                 exit $ret >> 8;
687         }
688         elsif ($ret) {
689                 exit 1;
690         }
691 }
692
693 # Tries to run an override target for a command. Returns the list of
694 # packages that it was unable to run an override target for.
695 sub run_override {
696         my $override_type=shift; # arch, indep, or undef
697         my $command=shift;
698         my @packages=@{shift()};
699         my @options=@_;
700
701         my $override="override_$command".
702                 (defined $override_type ? "-".$override_type : "");
703
704         # Check which packages are of the right architecture for the
705         # override_type.
706         my (@todo, @rest);
707         if (defined $override_type) {
708                 foreach my $package (@packages) {
709                         my $isall=package_arch($package) eq 'all';
710                         if (($override_type eq 'indep' && $isall) ||
711                             ($override_type eq 'arch' && !$isall)) {
712                                 push @todo, $package;
713                         }
714                         else {
715                                 push @rest, $package;
716                                 push @options, "-N$package";
717                         }
718                 }
719         }
720         else {
721                 @todo=@packages;
722         }
723
724         my $has_explicit_target = rules_explicit_target($override);
725         return @packages unless defined $has_explicit_target; # no such override
726         return @rest if ! $has_explicit_target; # has empty override
727         return @rest unless @todo; # has override, but no packages to act on
728
729         if (defined $override_type) {
730                 # Ensure appropriate -a or -i option is passed when running
731                 # an arch-specific override target.
732                 my $opt=$override_type eq "arch" ? "-a" : "-i";
733                 push @options, $opt unless grep { $_ eq $opt } @options;
734         }
735
736         # This passes the options through to commands called
737         # inside the target.
738         $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options);
739         $ENV{DH_INTERNAL_OVERRIDE}=$command;
740         run("debian/rules", $override);
741         delete $ENV{DH_INTERNAL_OPTIONS};
742         delete $ENV{DH_INTERNAL_OVERRIDE};
743
744         # Update log for overridden command now that it has
745         # finished successfully.
746         # (But avoid logging for dh_clean since it removes
747         # the log earlier.)
748         if (! $dh{NO_ACT} && $command ne 'dh_clean') {
749                 write_log($command, @todo);
750                 commit_override_log(@todo);
751         }
752
753         return @rest;
754 }
755
756 sub optimize_sequence {
757         my @sequence;
758         my %seen;
759         my $add=sub {
760                 # commands can appear multiple times when sequences are
761                 # inlined together; only the first should be needed
762                 my $command=shift;
763                 if (! $seen{$command}) {
764                         $seen{$command}=1;
765                         push @sequence, $command;
766                 }
767         };
768         foreach my $command (@_) {
769                 my $rules_target=rules_target($command);
770                 if (defined $rules_target &&
771                     ! defined rules_explicit_target($rules_target)) {
772                         # inline the sequence for this implicit target
773                         $add->($_) foreach optimize_sequence(@{$sequences{$rules_target}});
774                 }
775                 else {
776                         $add->($command);
777                 }
778         }
779         return @sequence;
780 }
781
782 sub rules_target {
783         my $command=shift;
784         if ($command =~ /^debian\/rules\s+(.*)/) {
785                 return $1
786         }
787         else {
788                 return undef;
789         }
790 }
791
792 sub rules {
793         return "debian/rules ".join(" ", @_);
794 }
795
796 {
797 my %targets;
798 my $rules_parsed;
799
800 sub rules_explicit_target {
801         # Checks if a specified target exists as an explicit target
802         # in debian/rules.
803         # undef is returned if target does not exist, 0 if target is noop
804         # and 1 if target has dependencies or executes commands.
805         my $target=shift;
806
807         if (! $rules_parsed) {
808                 my $processing_targets = 0;
809                 my $not_a_target = 0;
810                 my $current_target;
811                 open(MAKE, "LC_ALL=C make -Rrnpsf debian/rules $dummy_target 2>/dev/null |");
812                 while (<MAKE>) {
813                         if ($processing_targets) {
814                                 if (/^# Not a target:/) {
815                                         $not_a_target = 1;
816                                 }
817                                 else {
818                                         if (!$not_a_target && /^([^#:]+)::?\s*(.*)$/) {
819                                                 # Target is defined. NOTE: if it is a depenency of
820                                                 # .PHONY it will be defined too but that's ok.
821                                                 # $2 contains target dependencies if any.
822                                                 $current_target = $1;
823                                                 $targets{$current_target} = ($2) ? 1 : 0;
824                                         }
825                                         else {
826                                                 if (defined $current_target) {
827                                                         if (/^#/) {
828                                                                 # Check if target has commands to execute
829                                                                 if (/^#\s*(commands|recipe) to execute/) {
830                                                                         $targets{$current_target} = 1;
831                                                                 }
832                                                         }
833                                                         else {
834                                                                 # Target parsed.
835                                                                 $current_target = undef;
836                                                         }
837                                                 }
838                                         }
839                                         # "Not a target:" is always followed by
840                                         # a target name, so resetting this one
841                                         # here is safe.
842                                         $not_a_target = 0;
843                                 }
844                         }
845                         elsif (/^# Files$/) {
846                                 $processing_targets = 1;
847                         }
848                 }
849                 close MAKE;
850                 $rules_parsed = 1;
851         }
852
853         return $targets{$target};
854 }
855
856 }
857
858 sub warn_deprecated {
859         foreach my $deprecated ('until', 'after', 'before', 'remaining') {
860                 if (defined $dh{uc $deprecated}) {
861                         warning("The --$deprecated option is deprecated. Use override targets instead.");
862                 }
863         }
864 }
865
866 sub command_pos {
867         my $command=shift;
868         my @sequence=@_;
869
870         foreach my $i (0..$#sequence) {
871                 if ($command eq $sequence[$i]) {
872                         return $i;
873                 }
874         }
875
876         my @matches;
877         foreach my $i (0..$#sequence) {
878                 if ($sequence[$i] =~ /\Q$command\E/) {
879                         push @matches, $i;
880                 }
881         }
882         if (! @matches) {
883                 error "command specification \"$command\" does not match any command in the sequence"
884         }
885         else {
886                 return pop @matches;
887         }
888 }
889
890 =head1 SEE ALSO
891
892 L<debhelper(7)>
893
894 This program is a part of debhelper.
895
896 =head1 AUTHOR
897
898 Joey Hess <joeyh@debian.org>
899
900 =cut