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