X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=dh;h=a19a94a33eb276cd47e5056fa8e7bfedd26f2f25;hb=00ed6d0cc8f74caf4a591152a97027194304383c;hp=710117ead15d9db779a913b4068118e3322a2367;hpb=1089dbaaa1ccc4b7bade09555e67ae126bf776f2;p=debhelper.git diff --git a/dh b/dh index 710117e..a19a94a 100755 --- a/dh +++ b/dh @@ -24,22 +24,11 @@ they only work on binary independent packages, and commands in the binary-arch sequences are passed the "-a" option to ensure they only work on architecture dependent packages. -Each debhelper command will record when it's successfully run in -debian/package.debhelper.log. (Which dh_clean deletes.) So dh can tell -which commands have already been run, for which packages, and skip running -those commands again. - -Each time dh is run, it examines the log, and finds the last logged command -that is in the specified sequence. It then continues with the next command -in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining> -options can override this behavior. - If debian/rules contains a target with a name like "override_I", -then when it gets to that command in the sequence, dh will run that -target from the rules file, rather than running the actual command. The -override target can then run the command with additional options, or run -entirely different commands instead. (Note that to use this feature, -you should Build-Depend on debhelper 7.0.50 or above.) +then when it would normally run I, dh will instead call that +target. The override target can then run the command with additional options, +or run entirely different commands instead. See examples below. (Note that to +use this feature, you should Build-Depend on debhelper 7.0.50 or above.) =head1 OPTIONS @@ -78,18 +67,20 @@ Run commands in the sequence that come after I. Run all commands in the sequence that have yet to be run. +=item B<--no-act> + +Prints commands that would run for a given sequence, but does not run them. + =back All other options passed to dh are passed on to each command it runs. This can be used to set an option like "-v" or "-X" or "-N", as well as for more specialised options. -=head1 COMMAND SPECIFICATION - -I can be a full name of a debhelper command, or a substring. It'll first -search for a command in the sequence exactly matching the name, to avoid any -ambiguity. If there are multiple substring matches, the last one in the -sequence will be used. +In the above options, I can be a full name of a debhelper command, or +a substring. It'll first search for a command in the sequence exactly +matching the name, to avoid any ambiguity. If there are multiple substring +matches, the last one in the sequence will be used. =cut @@ -144,9 +135,9 @@ easy way to do with is by adding an override target for that command. override_dh_installdocs: dh_installdocs README TODO -Sometimes the automated dh_auto_configure and dh_auto_build can't guess -what to do for a strange package. Here's how to avoid running either -and instead run your own commands. +Sometimes the automated L and L +can't guess what to do for a strange package. Here's how to avoid running +either and instead run your own commands. #!/usr/bin/make -f %: @@ -174,24 +165,104 @@ default. This is how to use dh_pycentral instead. #!/usr/bin/make -f %: - dh --with python-central $@ + dh $@ --with python-central + +Here is how to force use of perl's Module::Build build system, +which can be necessary if debhelper wrongly detects that the package +uses MakeMaker. + + #!/usr/bin/make -f + %: + dh $@ --buildsystem=perl_build To patch your package using quilt, you can tell dh to use quilt's dh sequence addons like this: #!/usr/bin/make -f %: - dh --with quilt $@ + dh $@ --with quilt Here is an example of overriding where the dh_auto_* commands find the package's source, for a package where the source is located in a -subdirectory. It also forces use of perl's Module::Build build system, -which can be necessary if debhelper wrongly detects that the package -uses MakeMaker. +subdirectory. #!/usr/bin/make -f %: - dh --sourcedirectory=src --buildsystem=perl_build $@ + dh $@ --sourcedirectory=src + +And here is an example of how to tell the dh_auto_* commands to build +in a subdirectory, which will be removed on clean. + + #!/usr/bin/make -f + %: + dh $@ --builddirectory=build + +If your package can be built in parallel, you can support parallel building +as follows. Then I will work. + + #!/usr/bin/make -f + %: + dh $@ --parallel + +Here is a way to prevent dh from running several commands that you don't +want it to run, by defining empty override targets for each command. + + #!/usr/bin/make -f + %: + dh $@ + + # Commands not to run: + override_dh_auto_test override_dh_compress override_dh_fixperms: + +Sometimes, you may need to make an override target only run commands when a +particular package is being built. This can be accomplished using +L to test what is being built. For example: + + #!/usr/bin/make -f + %: + dh $@ + + override_dh_fixperms: + dh_fixperms + ifneq (,$(findstring foo, $(shell dh_listpackages))) + chmod 4755 debian/foo/usr/bin/foo + endif + +Finally, remember that you are not limited to using override targets in the +rules file when using dh. You can also explicitly define any of the regular +rules file targets when it makes sense to do so. A common reason to do this +is if your package needs different build-arch and build-indep targets. For +example, a package with a long document build process can put it in +build-indep to avoid build daemons redundantly building the documentation. + + #!/usr/bin/make -f + %: + dh $@ + + build: build-arch build-indep ; + build-indep: + $(MAKE) docs + build-arch: + $(MAKE) bins + +=head1 INTERNALS + +If you're curious about dh's internals, here's how it works under the hood. + +Each debhelper command will record when it's successfully run in +debian/package.debhelper.log. (Which dh_clean deletes.) So dh can tell +which commands have already been run, for which packages, and skip running +those commands again. + +Each time dh is run, it examines the log, and finds the last logged command +that is in the specified sequence. It then continues with the next command +in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining> +options can override this behavior. + +dh uses the DH_INTERNAL_OPTIONS environment variable to pass information +through to debhelper commands that are run inside override targets. The +contents (and indeed, existence) of this environment variable, as the name +might suggest, is subject to change at any time. =cut @@ -202,29 +273,38 @@ my @ARGV_orig=@ARGV; # (and comes first so python-central loads later and can disable it). unshift @ARGV, "--with=python-support"; -# Disable complaints about unknown options for both dh and the commands -# it runs. This is done because dh accepts and passes on options that may -# be specific to only some debhelper commands. -$ENV{DH_IGNORE_UNKNOWN_OPTIONS}=1; - init(options => { - "until=s" => \$dh{UNTIL}, - "after=s" => \$dh{AFTER}, - "before=s" => \$dh{BEFORE}, - "remaining" => \$dh{REMAINING}, - "with=s" => sub { - my ($option,$value)=@_; - push @{$dh{WITH}},split(",", $value); + "until=s" => \$dh{UNTIL}, + "after=s" => \$dh{AFTER}, + "before=s" => \$dh{BEFORE}, + "remaining" => \$dh{REMAINING}, + "with=s" => sub { + my ($option,$value)=@_; + push @{$dh{WITH}},split(",", $value); + }, + "without=s" => sub { + my ($option,$value)=@_; + @{$dh{WITH}} = grep { $_ ne $value } @{$dh{WITH}}; + }, + "l" => \&list_addons, + "list" => \&list_addons, }, - "without=s" => sub { - my ($option,$value)=@_; - @{$dh{WITH}} = grep { $_ ne $value } @{$dh{WITH}}; - }, - "l" => \$dh{LIST}, - "list" => \$dh{LIST}, -}); + # Disable complaints about unknown options; they are passed on to + # the debhelper commands. + ignore_unknown_options => 1, + # Bundling does not work well since there are unknown options. + bundling => 0, +); inhibit_log(); + +# If make is using a jobserver, but it is not available +# to this process, clean out MAKEFLAGS. This avoids +# ugly warnings when calling make. +if (is_make_jobserver_unavailable()) { + clean_jobserver_makeflags(); +} + # Definitions of sequences. my %sequences; $sequences{build} = [qw{ @@ -253,7 +333,6 @@ $sequences{install} = [@{$sequences{build}}, qw{ dh_installcatalogs dh_installcron dh_installdebconf - dh_installcatalogs dh_installemacsen dh_installifupdown dh_installinfo @@ -357,7 +436,7 @@ sub remove_command_options { } } -if ($dh{LIST}) { +sub list_addons { my %addons; for my $inc (@INC) { @@ -435,7 +514,17 @@ while (@ARGV_orig) { elsif ($opt =~ /^--?(no-act|remaining|(after|until|before|with|without)=)/) { next; } - push @options, $opt; + elsif ($opt=~/^-/) { + push @options, "-O".$opt; + } + elsif (@options) { + if ($options[$#options]=~/^-O--/) { + $options[$#options].="=".$opt; + } + else { + $options[$#options].=$opt; + } + } } # Figure out at what point in the sequence to start for each package. @@ -516,30 +605,44 @@ sub run { # Check for override targets in debian/rules and # run them instead of running the command directly. my $override_command; - if (rules_explicit_target("override_".$command)) { + my $has_explicit_target = rules_explicit_target("override_".$command); + if (defined $has_explicit_target) { $override_command=$command; - # This passes the options through to commands called - # inside the target. - $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options); - $command="debian/rules"; - @options="override_".$override_command; + # Check if target isn't noop + if ($has_explicit_target) { + # This passes the options through to commands called + # inside the target. + $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options); + $command="debian/rules"; + @options="override_".$override_command; + } + else { + $command = undef; + } } else { # Pass additional command options if any unshift @options, @{$command_opts{$command}} if exists $command_opts{$command}; } - # 3 space indent lines the command being run up under the - # sequence name after "dh ". - print " ".escape_shell($command, @options)."\n"; + if (defined $command) { + # 3 space indent lines the command being run up under the + # sequence name after "dh ". + print " ".escape_shell($command, @options)."\n"; + } + else { + print " ", "# Skipping ", $override_command, " - empty override", "\n"; + } if (! $dh{NO_ACT}) { - my $ret=system($command, @options); - if ($ret >> 8 != 0) { - exit $ret >> 8; - } - elsif ($ret) { - exit 1; + if (defined $command) { + my $ret=system($command, @options); + if ($ret >> 8 != 0) { + exit $ret >> 8; + } + elsif ($ret) { + exit 1; + } } if (defined $override_command) { @@ -564,12 +667,15 @@ my $rules_parsed; sub rules_explicit_target { # Checks if a specified target exists as an explicit target - # in debian/rules. + # in debian/rules. + # undef is returned if target does not exist, 0 if target is noop + # and 1 if target has dependencies or executes commands. my $target=shift; - - if (! $rules_parsed) { + + if (! $rules_parsed) { my $processing_targets = 0; my $not_a_target = 0; + my $current_target; open(MAKE, "LC_ALL=C make -Rrnpsf debian/rules debhelper-fail-me 2>/dev/null |"); while () { if ($processing_targets) { @@ -577,19 +683,34 @@ sub rules_explicit_target { $not_a_target = 1; } else { - if (!$not_a_target && /^([^#:]+)::?/) { - # Target is defined. - # NOTE: if it is a depenency - # of .PHONY it will be - # defined too but that's ok. - $targets{$1} = 1; + if (!$not_a_target && /^([^#:]+)::?\s*(.*)$/) { + # Target is defined. NOTE: if it is a depenency of + # .PHONY it will be defined too but that's ok. + # $2 contains target dependencies if any. + $current_target = $1; + $targets{$current_target} = ($2) ? 1 : 0; + } + else { + if (defined $current_target) { + if (/^#/) { + # Check if target has commands to execute + if (/^#\s*commands to execute/) { + $targets{$current_target} = 1; + } + } + else { + # Target parsed. + $current_target = undef; + } + } } # "Not a target:" is always followed by # a target name, so resetting this one # here is safe. $not_a_target = 0; } - } elsif (/^# Files$/) { + } + elsif (/^# Files$/) { $processing_targets = 1; } } @@ -597,7 +718,7 @@ sub rules_explicit_target { $rules_parsed = 1; } - return exists $targets{$target}; + return $targets{$target}; } }