#
# Library functions for debhelper programs, perl version.
#
-# Joey Hess, GPL copyright 1997-2000.
+# Joey Hess, GPL copyright 1997-2008.
package Debian::Debhelper::Dh_Lib;
use strict;
&pkgfile &pkgext &pkgfilename &isnative &autoscript &filearray
&filedoublearray &getpackages &basename &dirname &xargs %dh
&compat &addsubstvar &delsubstvar &excludefile &package_arch
- &is_udeb &udeb_filename &debhelper_script_subst &escape_shell);
+ &is_udeb &udeb_filename &debhelper_script_subst &escape_shell
+ &inhibit_log &load_log &write_log &dpkg_architecture_value
+ &sourcepackage);
-my $max_compat=6;
+my $max_compat=7;
sub init {
- # If DH_OPTIONS is set, prepend it @ARGV.
- if (defined($ENV{DH_OPTIONS})) {
- # Ignore leading/trailing whitespace.
- $ENV{DH_OPTIONS}=~s/^\s+//;
- $ENV{DH_OPTIONS}=~s/\s+$//;
- unshift @ARGV,split(/\s+/,$ENV{DH_OPTIONS});
- }
+ my %params=@_;
- # Check to see if an argument on the command line starts with a dash.
- # if so, we need to pass this off to the resource intensive
+ # Check to see if an option line starts with a dash,
+ # or DH_OPTIONS is set.
+ # If so, we need to pass this off to the resource intensive
# Getopt::Long, which I'd prefer to avoid loading at all if possible.
- my $parseopt=undef;
- my $arg;
- foreach $arg (@ARGV) {
- if ($arg=~m/^-/) {
- $parseopt=1;
- last;
- }
- }
- if ($parseopt) {
+ if ((defined $ENV{DH_OPTIONS} && length $ENV{DH_OPTIONS}) ||
+ (defined $ENV{DH_INTERNAL_OPTIONS} && length $ENV{DH_INTERNAL_OPTIONS}) ||
+ grep /^-/, @ARGV) {
eval "use Debian::Debhelper::Dh_Getopt";
- error($!) if $@;
- %dh=Debian::Debhelper::Dh_Getopt::parseopts();
+ error($@) if $@;
+ Debian::Debhelper::Dh_Getopt::parseopts($params{options});
}
# Another way to set excludes.
# Check if packages to build have been specified, if not, fall back to
# the default, doing them all.
if (! defined $dh{DOPACKAGES} || ! @{$dh{DOPACKAGES}}) {
- if ($dh{DOINDEP} || $dh{DOARCH} || $dh{DOSAME}) {
- error("You asked that all arch in(dep) packages be built, but there are none of that type.");
- }
push @{$dh{DOPACKAGES}},@allpackages;
}
# Run at exit. Add the command to the log files for the packages it acted
# on, if it's exiting successfully.
+my $write_log=1;
sub END {
- if ($? == 0) {
- my $cmd=basename($0);
- # dh_clean deletes the log, so should not recreate it at
- # the end
- if ($cmd ne "dh_clean") {
- foreach my $package (@{$dh{DOPACKAGES}}) {
- my $ext=pkgext($package);
- open(LOG, ">>", "debian/${ext}log.debhelper") || error("failed to write to log");
- print LOG $cmd."\n";
- close LOG;
- }
- }
+ if ($? == 0 && $write_log) {
+ write_log(basename($0), @{$dh{DOPACKAGES}});
}
}
+sub load_log {
+ my ($package, $db)=@_;
+ my $ext=pkgext($package);
+
+ my @log;
+ open(LOG, "<", "debian/${ext}debhelper.log") || return;
+ while (<LOG>) {
+ chomp;
+ push @log, $_;
+ $db->{$package}{$_}=1 if defined $db;
+ }
+ close LOG;
+ return @log;
+}
+
+sub write_log {
+ my $cmd=shift;
+ my @packages=@_;
+
+ foreach my $package (@packages) {
+ my $ext=pkgext($package);
+ my $log="debian/${ext}debhelper.log";
+ open(LOG, ">>", $log) || error("failed to write to ${log}: $!");
+ print LOG $cmd."\n";
+ close LOG;
+ }
+}
+
+sub inhibit_log {
+ $write_log=0;
+}
+
# Pass it an array containing the arguments of a shell command like would
# be run by exec(). It turns that into a line like you might enter at the
# shell, escaping metacharacters and quoting arguments that contain spaces.
verbose_print(escape_shell(@_));
if (! $dh{NO_ACT}) {
- my $ret=system(@_);
- $ret == 0 || error("command returned error code $ret");
+ system(@_) == 0 || _error_exitcode($_[0]);
}
}
if (! $dh{NO_ACT}) {
# The join makes system get a scalar so it forks off a shell.
- system(join(" ",@_)) == 0
- || error("command returned error code");
+ system(join(" ", @_)) == 0 || _error_exitcode(join(" ", @_))
}
}
+sub _error_exitcode {
+ my $command=shift;
+ if ($? == -1) {
+ error("$command failed to to execute: $!");
+ }
+ elsif ($? & 127) {
+ error("$command died with signal ".($? & 127));
+ }
+ else {
+ error("$command returned exit code ".($? >> 8));
+ }
+}
+
# Run a command that may have a huge number of arguments, like xargs does.
# Pass in a reference to an array containing the arguments, and then other
# parameters that are the command and any parameters that should be passed to
# Try the file..
open (COMPAT_IN, "debian/compat") || error "debian/compat: $!";
my $l=<COMPAT_IN>;
+ close COMPAT_IN;
if (! defined $l || ! length $l) {
warning("debian/compat is empty, assuming level $c");
}
}
if ($c < 4 && ! $warned_compat) {
- warning("Compatibility levels before 4 are deprecated.");
+ warning("Compatibility levels before 5 are deprecated.");
$warned_compat=1;
}
#
# It tries several filenames:
# * debian/package.filename.buildarch
+# * debian/package.filename.buildos
# * debian/package.filename
-# * debian/file (if the package is the main package)
-# If --name was specified then tonly the first two are tried, and they must
-# have the name after the pacage name:
+# * debian/filename (if the package is the main package)
+# If --name was specified then the files
+# must have the name after the package name:
# * debian/package.name.filename.buildarch
+# * debian/package.name.filename.buildos
# * debian/package.name.filename
+# * debian/name.filename (if the package is the main package)
sub pkgfile {
my $package=shift;
my $filename=shift;
}
my @try=("debian/$package.$filename.".buildarch(),
+ "debian/$package.$filename.".buildos(),
"debian/$package.$filename");
if ($package eq $dh{MAINPACKAGE}) {
push @try, "debian/$filename";
return 0;
}
+sub dpkg_architecture_value {
+ my $var = shift;
+ my $value=`dpkg-architecture -q$var 2>/dev/null` || error("dpkg-architecture failed");
+ chomp $value;
+ return $value;
+}
+
# Returns the build architecture. (Memoized)
{
my $arch;
sub buildarch {
- return $arch if defined $arch;
-
- $arch=`dpkg-architecture -qDEB_HOST_ARCH 2>/dev/null` || error("dpkg-architecture failed");
- chomp $arch;
+ if (!defined $arch) {
+ $arch=dpkg_architecture_value('DEB_HOST_ARCH');
+ }
return $arch;
}
}
+# Returns the build OS. (Memoized)
+{
+ my $os;
+
+ sub buildos {
+ return $os if defined $os;
+
+ $os=`dpkg-architecture -qDEB_HOST_ARCH_OS 2>/dev/null` || error("dpkg-architecture failed");
+ chomp $os;
+ return $os;
+ }
+}
+
# Passed an arch and a list of arches to match against, returns true if matched
sub samearch {
my $arch=shift;
return 0;
}
+# Returns source package name
+sub sourcepackage {
+ open (CONTROL, 'debian/control') ||
+ error("cannot read debian/control: $!\n");
+ while (<CONTROL>) {
+ chomp;
+ s/\s+$//;
+ if (/^Source:\s*(.*)/) {
+ close CONTROL;
+ return $1;
+ }
+ }
+
+ close CONTROL;
+ error("could not find Source: line in control file.");
+}
+
# Returns a list of packages in the control file.
# Must pass "arch" or "indep" or "same" to specify arch-dependant or
# -independant or same arch packages. If nothing is specified, returns all