diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2017-11-19 13:00:50 +0300 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2017-11-19 13:00:50 +0300 |
commit | 0f55f1989c5eef00d91f7ae8e12f781e52f2e628 (patch) | |
tree | bfe0eb53e99fd38bc316f0642656237fd9f86ba7 /dh | |
parent | 04c923d15dbe45268d71beb9f1ac012bb6dcc9ec (diff) | |
parent | 1a52f701f3c9fb3d1dc18461e06176dc046b0f42 (diff) | |
download | debhelper-0f55f1989c5eef00d91f7ae8e12f781e52f2e628.tar.gz |
Merge https://anonscm.debian.org/git/debhelper/debhelper
Diffstat (limited to 'dh')
-rwxr-xr-x | dh | 197 |
1 files changed, 120 insertions, 77 deletions
@@ -10,6 +10,8 @@ use strict; use warnings; use Debian::Debhelper::Dh_Lib; +our $VERSION = DH_BUILTIN_VERSION; + =head1 SYNOPSIS B<dh> I<sequence> [B<--with> I<addon>[B<,>I<addon> ...]] [B<--list>] [S<I<debhelper options>>] @@ -62,7 +64,9 @@ listed, separated by commas. List all available addons. -This can be used without a F<debian/compat> file. +When called only with this option, B<dh> can be called from any +directory (i.e. it does not need access to files from a source +package). =item B<--no-act> @@ -130,8 +134,7 @@ after a particular debhelper command is run. chmod 4755 debian/foo/usr/bin/foo Python tools are not run by dh by default, due to the continual change -in that area. (Before compatibility level v9, dh does run B<dh_pysupport>.) -Here is how to use B<dh_python2>. +in that area. Here is how to use B<dh_python2>. #!/usr/bin/make -f %: @@ -217,10 +220,16 @@ If you're curious about B<dh>'s internals, here's how it works under the hood. In compat 10 (or later), B<dh> creates a stamp file F<debian/debhelper-build-stamp> after the build step(s) are complete -to avoid re-running them. Inside an override target, B<dh_*> commands -will create a log file F<debian/package.debhelper.log> to keep track -of which packages the command(s) have been run for. These log files -are then removed once the override target is complete. +to avoid re-running them. It is possible to avoid the stamp file by +passing B<--without=build-stamp> to B<dh>. This makes "no clean" +builds behave more like what some people expect at the expense of +possibly running the build and test twice (the second time as root or +under L<fakeroot(1)>). + +Inside an override target, B<dh_*> commands will create a log file +F<debian/package.debhelper.log> to keep track of which packages the +command(s) have been run for. These log files are then removed once +the override target is complete. In compat 9 or earlier, each debhelper command will record when it's successfully run in F<debian/package.debhelper.log>. (Which @@ -283,19 +292,18 @@ matches, the last one in the sequence will be used. # Stash this away before init modifies it. my @ARGV_orig=@ARGV; -if (compat(8, 1)) { - # python-support was enabled by default before v9. - # (and comes first so python-central loads later and can disable it). - unshift @ARGV, "--with=python-support"; -} if (not compat(9, 1)) { # Enable autoreconf'ing by default in compat 10 or later. Use the # sequence add-on so existing --without=autoreconf unshift(@ARGV, "--with=autoreconf"); # Enable systemd support by default in compat 10 or later. - unshift(@ARGV, "--with=systemd"); + # - compat 11 injects the dh_installsystemd tool directly in the + # sequence instead of using a --with sequence. + unshift(@ARGV, "--with=systemd") if compat(10, 1); + unshift(@ARGV, "--with=build-stamp"); } + inhibit_log(); init(options => { @@ -369,15 +377,12 @@ my %sequences; my @bd_minimal = qw{ dh_testdir }; -my @bd = (qw{ - dh_testdir +my @bd = (@bd_minimal, qw{ dh_update_autotools_config dh_auto_configure dh_auto_build dh_auto_test -}, - "create-stamp ${build_stamp_file}", -); +}); my @i = (qw{ dh_testroot dh_prep @@ -396,6 +401,10 @@ my @i = (qw{ dh_installemacsen dh_installinfo dh_installinit +}, + (!compat(10) ? qw(dh_installsystemd) : qw()), + +qw{ dh_installmenu dh_installmime dh_installlogcheck @@ -418,6 +427,7 @@ my @i = (qw{ dh_strip_nondeterminism dh_compress dh_fixperms + dh_missing }); my @ba=qw{ dh_strip @@ -433,8 +443,7 @@ my @b=qw{ dh_md5sums dh_builddeb }; -$sequences{clean} = [qw{ - dh_testdir +$sequences{clean} = [@bd_minimal, qw{ dh_auto_clean dh_clean }]; @@ -465,9 +474,7 @@ my %command_opts; # sequence addon interface sub _insert { - my $offset=shift; - my $existing=shift; - my $new=shift; + my ($offset, $existing, $new) = @_; foreach my $sequence (keys %sequences) { my @list=@{$sequences{$sequence}}; next unless grep $existing, @list; @@ -492,27 +499,30 @@ sub insert_after { _insert(1, @_); } sub remove_command { - my $command=shift; + my ($command) = @_; foreach my $sequence (keys %sequences) { $sequences{$sequence}=[grep { $_ ne $command } @{$sequences{$sequence}}]; } } sub add_command { - my $command=shift; - my $sequence=shift; + my ($command, $sequence) = @_; unshift @{$sequences{$sequence}}, $command; } +sub add_command_at_end { + my ($command, $sequence) = @_; + push(@{$sequences{$sequence}}, $command); +} sub add_command_options { my $command=shift; push @{$command_opts{$command}}, @_; } sub remove_command_options { - my $command=shift; - if (@_) { + my ($command, @cmd_options) = @_; + if (@cmd_options) { # Remove only specified options if (my $opts = $command_opts{$command}) { - foreach my $opt (@_) { + foreach my $opt (@cmd_options) { $opts = [ grep { $_ ne $opt } @$opts ]; } $command_opts{$command} = $opts; @@ -528,7 +538,7 @@ sub list_addons { my %addons; for my $inc (@INC) { - eval q{use File::Spec}; + require File::Spec; my $path = File::Spec->catdir($inc, "Debian/Debhelper/Sequence"); if (-d $path) { for my $module_path (glob "$path/*.pm") { @@ -575,6 +585,7 @@ my @packages=@{$dh{DOPACKAGES}}; # Filter out options intended only for this program. my @options; my $user_specified_options=0; +my $build_system_options = 0; if ($sequence eq 'build-arch' || $sequence eq 'install-arch' || $sequence eq 'binary-arch') { @@ -616,6 +627,7 @@ while (@ARGV_orig) { next if $max_parallel == 1; } push @options, "-O".$opt; + $build_system_options = 1 if $opt ne '--no-parallel' and $opt ne '--parallel'; $user_specified_options=1 unless $opt =~ /^--((?:no-)?parallel|buildsystem|sourcedirectory|builddirectory|)/; } @@ -647,12 +659,23 @@ if ( -f $build_stamp_file) { close($fd); } +# Lazy cache of the result of optimize_sequence on the "build" +# sequence +my $optimized_build_seq; foreach my $package (@packages) { my @log; if (compat(9)) { @log = load_log($package, \%logged); } elsif (exists($stamp_file{$package})) { - @log = @bd; + if (not defined($optimized_build_seq)) { + # Expand "build" so we can accurately filter out + # everything (admittedly, it is bit of an over + # approximation) + # Related bug: #851071 + my @seq = optimize_sequence(@{$sequences{'build'}}); + $optimized_build_seq = \@seq; + } + @log = @{$optimized_build_seq}; # We do not need %logged in compat 10 } if ($dh{AFTER}) { @@ -725,6 +748,8 @@ foreach my $i (0..$stoppoint) { } if (my $stamp_file = stamp_target($command)) { my %seen; + print " create-stamp ".escape_shell($stamp_file)."\n"; + next if $dh{NO_ACT}; open(my $fd, '+>>', $stamp_file) or error("open($stamp_file, rw) failed: $!"); # Seek to the beginning @@ -778,8 +803,7 @@ foreach my $i (0..$stoppoint) { } sub run { - my $command=shift; - my @options=@_; + my ($command, @options) = @_; # Include additional command options if any unshift @options, @{$command_opts{$command}} @@ -792,8 +816,8 @@ sub run { } return if $dh{NO_ACT}; - - my $ret=system($command, @options); + + my $ret=system { $command } $command, @options; if ($ret >> 8 != 0) { exit $ret >> 8; } @@ -805,10 +829,7 @@ sub run { # Tries to run an override target for a command. Returns the list of # packages that it was unable to run an override target for. sub run_override { - my $override_type=shift; # arch, indep, or undef - my $command=shift; - my @packages=@{shift()}; - my @options=@_; + my ($override_type, $command, $packages, @options) = @_; my $override="override_$command". (defined $override_type ? "-".$override_type : ""); @@ -816,25 +837,25 @@ sub run_override { # Check which packages are of the right architecture for the # override_type. my (@todo, @rest); + my $has_explicit_target = rules_explicit_target($override); + if (defined $override_type) { - foreach my $package (@packages) { - my $isall=package_arch($package) eq 'all'; + foreach my $package (@{$packages}) { + my $isall=package_is_arch_all($package); if (($override_type eq 'indep' && $isall) || - ($override_type eq 'arch' && !$isall)) { + ($override_type eq 'arch' && !$isall)) { push @todo, $package; - } - else { + } else { push @rest, $package; push @options, "-N$package"; } } } else { - @todo=@packages; + @todo=@{$packages}; } - my $has_explicit_target = rules_explicit_target($override); - return @packages unless defined $has_explicit_target; # no such override + return @{$packages} unless defined $has_explicit_target; # no such override return @rest if ! $has_explicit_target; # has empty override return @rest unless @todo; # has override, but no packages to act on @@ -845,6 +866,12 @@ sub run_override { push @options, $opt unless grep { $_ eq $opt } @options; } + # Discard any override log files before calling the override + # target + if (not compat(9)) { + my @files = glob('debian/*.debhelper.log'); + rm_files(@files) if @files; + } # This passes the options through to commands called # inside the target. $ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options); @@ -852,7 +879,6 @@ sub run_override { run("debian/rules", $override); delete $ENV{DH_INTERNAL_OPTIONS}; delete $ENV{DH_INTERNAL_OVERRIDE}; - complex_doit("rm","-f","debian/*.debhelper.log") if not compat(9); # Update log for overridden command now that it has # finished successfully. @@ -863,12 +889,17 @@ sub run_override { commit_override_log(@todo); } + # Override targets may introduce new helper files. Strictly + # speaking this *shouldn't* be necessary, but lets make no + # assumptions. + Debian::Debhelper::Dh_Lib::dh_clear_unsafe_cache(); + return @rest; } sub optimize_sequence { - my @sequence; - my %seen; + my (@commands) = @_; + my (@sequence, %seen); my $add=sub { # commands can appear multiple times when sequences are # inlined together; only the first should be needed @@ -878,7 +909,7 @@ sub optimize_sequence { push @sequence, $command; } }; - foreach my $command (@_) { + foreach my $command (@commands) { my $rules_target=rules_target($command); if (defined $rules_target && ! defined rules_explicit_target($rules_target)) { @@ -893,7 +924,7 @@ sub optimize_sequence { } sub rules_target { - my $command=shift; + my ($command) = @_; if ($command =~ /^debian\/rules\s+(.*)/) { return $1 } @@ -923,7 +954,7 @@ sub rules_explicit_target { # 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; + my ($target) = @_; if (! $rules_parsed) { my $processing_targets = 0; @@ -989,8 +1020,7 @@ sub warn_deprecated { } sub command_pos { - my $command=shift; - my @sequence=@_; + my ($command, @sequence) = @_; foreach my $i (0..$#sequence) { if ($command eq $sequence[$i]) { @@ -1014,8 +1044,7 @@ sub command_pos { my %skipinfo; sub can_skip { - my $command=shift; - my @packages=@_; + my ($command, @packages) = @_; return 0 if $user_specified_options || (exists $ENV{DH_OPTIONS} && length $ENV{DH_OPTIONS}); @@ -1025,37 +1054,57 @@ sub can_skip { } my @skipinfo=@{$skipinfo{$command}}; return 0 unless @skipinfo; - - foreach my $package (@packages) { - foreach my $skipinfo (@skipinfo) { - if ($skipinfo=~/^([a-zA-Z0-9-_]+)\((.*)\)$/) { - my $type = $1; - my $need = $2; - if ($type eq 'tmp') { + return 1 if scalar(@skipinfo) == 1 and $skipinfo[0] eq 'always-skip'; + my $all_pkgs; + + foreach my $skipinfo (@skipinfo) { + if ($skipinfo=~/^([a-zA-Z0-9-_]+)\((.*)\)$/) { + my $type = $1; + my $need = $2; + if ($type eq 'tmp') { + foreach my $package (@packages) { my $tmp = tmpdir($package); return 0 if -e "$tmp/$need"; + } + } elsif ($type eq 'pkgfile' or $type eq 'pkgfile-logged') { + my $pkgs; + if ($type eq 'pkgfile') { + $pkgs = \@packages; } else { - # Unknown hint - make no assumptions - return 0; + $all_pkgs //= [getpackages()]; + $pkgs = $all_pkgs; } - } - elsif (pkgfile($package, $skipinfo) ne '') { + # Use the secret bulk check call + return 0 if pkgfile($pkgs, $need) ne ''; + } elsif ($type eq 'buildsystem') { + # If there are any buildsystem options, we assume that + # the build needs a buildsystem. + return 0 if $build_system_options; + require Debian::Debhelper::Dh_Buildsystems; + my $system = Debian::Debhelper::Dh_Buildsystems::load_buildsystem(undef, $need); + return 0 if defined($system); + } else { + # Unknown hint - make no assumptions return 0; } + } else { + # Use the secret bulk check call + return 0 if pkgfile(\@packages, $skipinfo) ne ''; } } return 1; } sub extract_skipinfo { - my $command=shift; + my ($command) = @_; foreach my $dir (split (':', $ENV{PATH})) { if (open (my $h, "<", "$dir/$command")) { while (<$h>) { - if (m/PROMISE: DH NOOP WITHOUT\s+(.*)/) { + if (m/PROMISE: DH NOOP( WITHOUT\s+(.*))?\s*$/) { close $h; - return split(' ', $1); + return split(' ', $2) if defined($2); + return ('always-skip'); } } close $h; @@ -1075,9 +1124,3 @@ This program is a part of debhelper. Joey Hess <joeyh@debian.org> =cut - -# Local Variables: -# indent-tabs-mode: t -# tab-width: 4 -# cperl-indent-level: 4 -# End: |