summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Debian/Debhelper/Buildsystem/autotools.pm54
-rw-r--r--Debian/Debhelper/Buildsystem/cmake.pm49
-rw-r--r--Debian/Debhelper/Buildsystem/makefile.pm84
-rw-r--r--Debian/Debhelper/Buildsystem/perl_build.pm67
-rw-r--r--Debian/Debhelper/Buildsystem/perl_makefile.pm38
-rw-r--r--Debian/Debhelper/Buildsystem/python_distutils.pm62
-rw-r--r--Debian/Debhelper/Dh_Buildsystem_Bases.pm308
-rw-r--r--Debian/Debhelper/Dh_Buildsystems.pm175
8 files changed, 837 insertions, 0 deletions
diff --git a/Debian/Debhelper/Buildsystem/autotools.pm b/Debian/Debhelper/Buildsystem/autotools.pm
new file mode 100644
index 0000000..65694b3
--- /dev/null
+++ b/Debian/Debhelper/Buildsystem/autotools.pm
@@ -0,0 +1,54 @@
+# A buildsystem plugin for handling autotools based projects
+#
+# Copyright: © 2008 Joey Hess
+# © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::autotools;
+
+use strict;
+use File::Spec;
+use Debian::Debhelper::Dh_Lib;
+use base 'Debian::Debhelper::Buildsystem::makefile';
+
+sub DESCRIPTION {
+ "support for building GNU Autotools based packages"
+}
+
+sub is_buildable {
+ my $self=shift;
+ my ($action) = @_;
+ if ($action eq "configure") {
+ return -x "configure";
+ } else {
+ return $self->SUPER::is_buildable(@_);
+ }
+}
+
+sub configure_impl {
+ my $self=shift;
+
+ # Standard set of options for configure.
+ my @opts;
+ push @opts, "--build=" . dpkg_architecture_value("DEB_BUILD_GNU_TYPE");
+ push @opts, "--prefix=/usr";
+ push @opts, "--includedir=\${prefix}/include";
+ push @opts, "--mandir=\${prefix}/share/man";
+ push @opts, "--infodir=\${prefix}/share/info";
+ push @opts, "--sysconfdir=/etc";
+ push @opts, "--localstatedir=/var";
+ push @opts, "--libexecdir=\${prefix}/lib/" . $self->exec_in_topdir(\&sourcepackage);
+ push @opts, "--disable-maintainer-mode";
+ push @opts, "--disable-dependency-tracking";
+ # Provide --host only if different from --build, as recommended in
+ # autotools-dev README.Debian: When provided (even if equal) autotools
+ # 2.52+ switches to cross-compiling mode.
+ if (dpkg_architecture_value("DEB_BUILD_GNU_TYPE")
+ ne dpkg_architecture_value("DEB_HOST_GNU_TYPE")) {
+ push @opts, "--host=" . dpkg_architecture_value("DEB_HOST_GNU_TYPE");
+ }
+
+ doit($self->get_toppath("configure"), @opts, @_);
+}
+
+1;
diff --git a/Debian/Debhelper/Buildsystem/cmake.pm b/Debian/Debhelper/Buildsystem/cmake.pm
new file mode 100644
index 0000000..d7504d1
--- /dev/null
+++ b/Debian/Debhelper/Buildsystem/cmake.pm
@@ -0,0 +1,49 @@
+# A buildsystem plugin for handling CMake based projects.
+# It enforces outside-source building.
+#
+# Copyright: © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::cmake;
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use base 'Debian::Debhelper::Buildsystem::makefile';
+
+sub _add_cmake_flag {
+ my ($self, $name, $val) = @_;
+ push @{$self->{cmake_flags}}, "-D$name=$val";
+}
+
+sub DESCRIPTION {
+ "support for building CMake based packages (outside-source tree only)"
+}
+
+sub is_buildable {
+ return -e "CMakeLists.txt";
+}
+
+sub new {
+ my $cls=shift;
+ my $self=$cls->SUPER::new(@_);
+ # Enfore outside-source tree builds.
+ $self->enforce_outside_source_building();
+ $self->{cmake_flags} = [];
+ return $self;
+}
+
+sub configure_impl {
+ my $self=shift;
+
+ # Standard set of cmake flags
+ $self->_add_cmake_flag("CMAKE_INSTALL_PREFIX", "/usr");
+ $self->_add_cmake_flag("CMAKE_C_FLAGS", $ENV{CFLAGS}) if (exists $ENV{CFLAGS});
+ $self->_add_cmake_flag("CMAKE_CXX_FLAGS", $ENV{CXXFLAGS}) if (exists $ENV{CXXFLAGS});
+ $self->_add_cmake_flag("CMAKE_SKIP_RPATH", "ON");
+ $self->_add_cmake_flag("CMAKE_VERBOSE_MAKEFILE", "ON");
+ # TODO: LDFLAGS
+
+ doit("cmake", $self->get_topdir(), @{$self->{cmake_flags}}, @_);
+}
+
+1;
diff --git a/Debian/Debhelper/Buildsystem/makefile.pm b/Debian/Debhelper/Buildsystem/makefile.pm
new file mode 100644
index 0000000..91a6341
--- /dev/null
+++ b/Debian/Debhelper/Buildsystem/makefile.pm
@@ -0,0 +1,84 @@
+# A buildsystem plugin for handling simple Makefile based projects.
+#
+# Copyright: © 2008 Joey Hess
+# © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::makefile;
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use Debian::Debhelper::Dh_Buildsystem_Bases;
+use base 'Debian::Debhelper::Dh_Buildsystem_Chdir';
+
+sub _exists_make_target {
+ my ($cls, $target) = @_;
+ # Use make -n to check to see if the target would do
+ # anything. There's no good way to test if a target exists.
+ my $ret=`$ENV{MAKE} -s -n $target 2>/dev/null`;
+ chomp $ret;
+ return length($ret);
+}
+
+sub _make_first_existing_target {
+ my $cls = shift;
+ my $targets = shift;
+
+ $ENV{MAKE}="make" unless exists $ENV{MAKE};
+ foreach my $target (@$targets) {
+ if ($cls->_exists_make_target($target)) {
+ doit($ENV{MAKE}, $target, @_);
+ return $target;
+ }
+ }
+ return undef;
+}
+
+sub DESCRIPTION {
+ "support for building Makefile based packages (make && make install)"
+}
+
+sub is_buildable {
+ my $self=shift;
+ my ($action) = @_;
+ if (grep /^\Q$action\E$/, qw{build test install clean}) {
+ return -e $self->get_buildpath("Makefile") ||
+ -e $self->get_buildpath("makefile") ||
+ -e $self->get_buildpath("GNUmakefile");
+ } else {
+ return 1;
+ }
+}
+
+sub build_impl {
+ my $self=shift;
+ doit(exists $ENV{MAKE} ? $ENV{MAKE} : "make", @_);
+}
+
+sub test_impl {
+ my $self=shift;
+ $self->_make_first_existing_target(['test', 'check'], @_);
+}
+
+sub install_impl {
+ my $self=shift;
+ my $destdir=shift;
+
+ $ENV{MAKE}="make" unless exists $ENV{MAKE};
+ my @params="DESTDIR=$destdir";
+
+ # Special case for MakeMaker generated Makefiles.
+ if (-e "Makefile" &&
+ system('grep -q "generated automatically by MakeMaker" Makefile') == 0) {
+ push @params, "PREFIX=/usr";
+ }
+
+ $self->_make_first_existing_target(['install'], @params, @_);
+}
+
+sub clean_impl {
+ my $self=shift;
+ $self->_make_first_existing_target(['distclean', 'realclean', 'clean'], @_);
+}
+
+1;
diff --git a/Debian/Debhelper/Buildsystem/perl_build.pm b/Debian/Debhelper/Buildsystem/perl_build.pm
new file mode 100644
index 0000000..74106d9
--- /dev/null
+++ b/Debian/Debhelper/Buildsystem/perl_build.pm
@@ -0,0 +1,67 @@
+# A buildsystem plugin for handling Perl Build based projects.
+#
+# Copyright: © 2008-2009 Joey Hess
+# © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::perl_build;
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use Debian::Debhelper::Dh_Buildsystem_Bases;
+use base 'Debian::Debhelper::Dh_Buildsystem_Basic';
+
+sub DESCRIPTION {
+ "support for building Perl Build.PL based packages (in-source only)"
+}
+
+sub is_buildable {
+ my ($self, $action) = @_;
+ my $ret = (-e "Build.PL");
+ if ($action ne "configure") {
+ $ret &= (-e "Build");
+ }
+ return $ret;
+}
+
+sub invoke_impl {
+ my $self=shift;
+ $ENV{MODULEBUILDRC} = "/dev/null";
+ return $self->SUPER::invoke_impl(@_);
+}
+
+sub new {
+ my $cls=shift;
+ my $self= $cls->SUPER::new(@_);
+ $self->enforce_in_source_building();
+ return $self;
+}
+
+sub configure_impl {
+ my $self=shift;
+ $ENV{PERL_MM_USE_DEFAULT}=1; # Module::Build can also use this.
+ doit("perl", "Build.PL", "installdirs=vendor", @_);
+}
+
+sub build_impl {
+ my $self=shift;
+ doit("perl", "Build", @_);
+}
+
+sub test_impl {
+ my $self=shift;
+ doit(qw/perl Build test/, @_);
+}
+
+sub install_impl {
+ my $self=shift;
+ my $destdir=shift;
+ doit("perl", "Build", "install", "destdir=$destdir", "create_packlist=0", @_);
+}
+
+sub clean_impl {
+ my $self=shift;
+ doit("perl", "Build", "--allow_mb_mismatch", 1, "distclean", @_);
+}
+
+1;
diff --git a/Debian/Debhelper/Buildsystem/perl_makefile.pm b/Debian/Debhelper/Buildsystem/perl_makefile.pm
new file mode 100644
index 0000000..67a6f44
--- /dev/null
+++ b/Debian/Debhelper/Buildsystem/perl_makefile.pm
@@ -0,0 +1,38 @@
+# A buildsystem plugin for handling Perl Build based projects.
+#
+# Copyright: © 2008-2009 Joey Hess
+# © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::perl_makefile;
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use Debian::Debhelper::Dh_Buildsystem_Bases;
+use base 'Debian::Debhelper::Dh_Buildsystem_Basic';
+
+sub DESCRIPTION {
+ "support for building Perl Makefile.PL based packages (in-source only)"
+}
+
+sub is_buildable {
+ my ($self, $action) = @_;
+ return ($action eq "configure") && (-e "Makefile.PL");
+}
+
+sub new {
+ my $cls=shift;
+ my $self=$cls->SUPER::new(@_);
+ $self->enforce_in_source_building();
+ return $self;
+}
+
+sub configure_impl {
+ my $self=shift;
+ # If set to a true value then MakeMaker's prompt function will
+ # # always return the default without waiting for user input.
+ $ENV{PERL_MM_USE_DEFAULT}=1;
+ doit("perl", "Makefile.PL", "INSTALLDIRS=vendor", @_);
+}
+
+1;
diff --git a/Debian/Debhelper/Buildsystem/python_distutils.pm b/Debian/Debhelper/Buildsystem/python_distutils.pm
new file mode 100644
index 0000000..2a6df37
--- /dev/null
+++ b/Debian/Debhelper/Buildsystem/python_distutils.pm
@@ -0,0 +1,62 @@
+# A buildsystem plugin for building Python Distutils based
+# projects.
+#
+# Copyright: © 2008 Joey Hess
+# © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::python_distutils;
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use Debian::Debhelper::Dh_Buildsystem_Bases;
+use base 'Debian::Debhelper::Dh_Buildsystem_Option';
+
+sub DESCRIPTION {
+ "support for building Python distutils based packages"
+}
+
+sub is_buildable {
+ return -e "setup.py";
+}
+
+sub get_builddir_option {
+ my $self=shift;
+ if ($self->get_builddir()) {
+ return "--build-base=". $self->get_builddir();
+ }
+ return;
+}
+
+sub configure_impl {
+ # Do nothing
+ 1;
+}
+
+sub build_impl {
+ my $self=shift;
+ doit("python", "setup.py", "build", @_);
+}
+
+sub test_impl {
+ 1;
+}
+
+sub install_impl {
+ my $self=shift;
+ my $destdir=shift;
+
+ doit("python", "setup.py", "install",
+ "--root=$destdir",
+ "--no-compile", "-O0", @_);
+}
+
+sub clean_impl {
+ my $self=shift;
+ doit("python", "setup.py", "clean", "-a", @_);
+ # The setup.py might import files, leading to python creating pyc
+ # files.
+ doit('find', '.', '-name', '*.pyc', '-exec', 'rm', '{}', ';');
+}
+
+1;
diff --git a/Debian/Debhelper/Dh_Buildsystem_Bases.pm b/Debian/Debhelper/Dh_Buildsystem_Bases.pm
new file mode 100644
index 0000000..ab24829
--- /dev/null
+++ b/Debian/Debhelper/Dh_Buildsystem_Bases.pm
@@ -0,0 +1,308 @@
+# Defines base debhelper buildsystem class interface.
+#
+# Copyright: © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Dh_Buildsystem_Basic;
+
+use Cwd;
+use File::Spec;
+use Debian::Debhelper::Dh_Lib;
+
+# Build system name. Defaults to the last component of the package
+# name. Do not override this method unless you know what you are
+# doing.
+sub NAME {
+ my $self = shift;
+ my $cls = ref($self) || $self;
+ return ($cls =~ m/^.+::([^:]+)$/) ? $1 : "[invalid package name]";
+}
+
+# Description of the build system to be shown to the users.
+sub DESCRIPTION {
+ "basic debhelper build system class";
+}
+
+sub new {
+ my ($cls, $builddir) = @_;
+ my $self = bless({ builddir => $builddir }, $cls);
+ if (!defined($builddir) || $builddir eq ".") {
+ $self->{builddir} = undef;
+ }
+ return $self;
+}
+
+# This instance method is called to check if the build system is capable
+# to build a source package. Additional argument $action describes which
+# operation the caller is going to perform first (either configure,
+# build, test, install or clean). You must override this method for the
+# build system module to be ever picked up automatically.
+#
+# This method is supposed to be called with source root directory being
+# working directory. Use $self->get_buildpath($path) method to get full
+# path to the files in the build directory.
+sub is_buildable {
+ my $self=shift;
+ my ($action) = @_;
+ return 0;
+}
+
+# Derived class can call this method in its constructor
+# to enforce in-source building even if the user
+# requested otherwise.
+sub enforce_in_source_building {
+ my $self=shift;
+ if ($self->{builddir}) {
+ warning("warning: ".$self->NAME()." buildsystem does not support building outside-source. In-source build enforced.");
+ $self->{builddir} = undef;
+ }
+}
+
+sub get_builddir {
+ my $self=shift;
+ return $self->{builddir};
+}
+
+sub get_buildpath {
+ my ($self, $path) = @_;
+ if ($self->get_builddir()) {
+ return File::Spec->catfile($self->get_builddir(), $path);
+ }
+ else {
+ return File::Spec->catfile('.', $path);
+ }
+}
+
+sub invoke_impl {
+ my $self=shift;
+ my $method=shift;
+
+ return $self->$method(@_);
+}
+
+# The instance methods below provide support for configuring,
+# building, testing, install and cleaning source packages.
+# These methods are wrappers around respective *_impl() methods
+# which are supposed to do real buildsystem specific work.
+
+sub configure {
+ my $self=shift;
+ return $self->invoke_impl('configure_impl', @_);
+}
+
+sub build {
+ my $self=shift;
+ return $self->invoke_impl('build_impl', @_);
+}
+
+sub test {
+ my $self=shift;
+ return $self->invoke_impl('test_impl', @_);
+}
+
+sub install {
+ my $self=shift;
+ return $self->invoke_impl('install_impl', @_);
+}
+
+sub clean {
+ my $self=shift;
+ return $self->invoke_impl('clean_impl', @_);
+}
+
+# The instance methods below should be overriden by derived classes
+# to implement buildsystem specific actions needed to build the
+# source. Arbitary number of custom action arguments might be passed.
+# Default implementations do nothing.
+
+sub configure_impl {
+ my $self=shift;
+ 1;
+}
+
+sub build_impl {
+ my $self=shift;
+ 1;
+}
+
+sub test_impl {
+ my $self=shift;
+ 1;
+}
+
+# destdir parameter specifies where to install files.
+sub install_impl {
+ my $self=shift;
+ my $destdir=shift;
+ 1;
+}
+
+sub clean_impl {
+ my $self=shift;
+ 1;
+}
+
+package Debian::Debhelper::Dh_Buildsystem_Option;
+
+use Debian::Debhelper::Dh_Buildsystems qw( DEFAULT_BUILD_DIRECTORY );
+use base 'Debian::Debhelper::Dh_Buildsystem_Basic';
+
+# Derived class can call this method in its constructor to enforce
+# outside-source building even if the user didn't request it.
+sub enforce_outside_source_building {
+ my ($self, $builddir) = @_;
+ if (!defined $self->{builddir}) {
+ $self->{builddir} = ($builddir && $builddir ne ".") ? $builddir : DEFAULT_BUILD_DIRECTORY;
+ }
+}
+
+# Constructs option to be passed to the source package buildsystem to
+# change build directory. Returns nothing by default.
+sub get_builddir_option {
+ my $self=shift;
+ return;
+}
+
+sub invoke_impl {
+ my $self=shift;
+ my $method=shift;
+
+ if ($self->get_builddir_option()) {
+ return $self->SUPER::invoke_impl($method, $self->get_builddir_option(), @_);
+ }
+ else {
+ return $self->SUPER::invoke_impl($method, @_);
+ }
+}
+
+package Debian::Debhelper::Dh_Buildsystem_Chdir;
+
+use Cwd;
+use File::Spec;
+use Debian::Debhelper::Dh_Lib;
+use base 'Debian::Debhelper::Dh_Buildsystem_Option';
+
+sub new {
+ my $cls=shift;
+ my $self=$cls->SUPER::new(@_);
+ $self->{topdir} = '.';
+ return $self;
+}
+
+sub _cd {
+ my ($cls, $dir) = @_;
+ verbose_print("cd '$dir'");
+ if (! $dh{NO_ACT}) {
+ chdir $dir or error("error: unable to chdir to $dir");
+ }
+}
+
+sub _mkdir {
+ my ($cls, $dir) = @_;
+ if (-e $dir && ! -d $dir) {
+ error("error: unable to create '$dir': object already exists and is not a directory");
+ }
+ else {
+ verbose_print("mkdir '$dir'");
+ if (! $dh{NO_ACT}) {
+ mkdir($dir, 0755) or error("error: unable to create '$dir': $!");
+ }
+ return 1;
+ }
+ return 0;
+}
+
+sub get_builddir {
+ my $self=shift;
+ if (defined $self->{builddir} && $self->{topdir} ne ".") {
+ return File::Spec->catfile($self->{topdir}, $self->{builddir});
+ }
+ return $self->SUPER::get_builddir();
+}
+
+sub get_topdir {
+ my $self=shift;
+ if ($self->{topdir} ne ".") {
+ return File::Spec->abs2rel($self->{topdir});
+ }
+ return $self->{topdir};
+}
+
+sub get_toppath {
+ my ($self, $path) = @_;
+ return File::Spec->catfile($self->get_topdir(), $path);
+}
+
+sub cd {
+ my $self = shift;
+ if ($self->get_builddir() && $self->{topdir} ne ".") {
+ $self->_cd($self->get_topdir());
+ $self->{topdir} = ".";
+ return 1;
+ }
+ return 0;
+}
+
+sub cd_to_builddir {
+ my $self = shift;
+ if ($self->get_builddir() && $self->{topdir} eq ".") {
+ $self->{topdir} = getcwd();
+ $self->_cd($self->get_builddir());
+ return 1;
+ }
+ return 0;
+}
+
+sub exec_in_topdir {
+ my $self=shift;
+ my $sub=shift;
+ my $ret;
+
+ if ($self->get_topdir() ne ".") {
+ $self->cd();
+ $ret = &$sub(@_);
+ $self->cd_to_builddir();
+ }
+ else {
+ $ret = &$sub(@_);
+ }
+ return $ret;
+}
+
+# *_impl() is run with current working directory changed to the
+# build directory if requested.
+sub invoke_impl {
+ my $self=shift;
+ my $method=shift;
+ my $ret;
+
+ $self->cd_to_builddir();
+ $ret = $self->$method(@_);
+ $self->cd();
+ return $ret;
+}
+
+sub configure {
+ my $self=shift;
+ if ($self->get_builddir()) {
+ $self->_mkdir($self->get_builddir());
+ }
+ return $self->SUPER::configure(@_);
+}
+
+# If outside-source tree building is done, whole build directory
+# gets wiped out by default. Otherwise, clean_impl() is called.
+sub clean {
+ my $self=shift;
+ if ($self->get_builddir()) {
+ if (-d $self->get_builddir()) {
+ $self->cd();
+ doit("rm", "-rf", $self->get_builddir());
+ return 1;
+ }
+ } else {
+ return $self->SUPER::clean(@_);
+ }
+}
+
+1;
diff --git a/Debian/Debhelper/Dh_Buildsystems.pm b/Debian/Debhelper/Dh_Buildsystems.pm
new file mode 100644
index 0000000..7e8ca29
--- /dev/null
+++ b/Debian/Debhelper/Dh_Buildsystems.pm
@@ -0,0 +1,175 @@
+# A module for loading and managing debhelper buildsystem plugins.
+#
+# Copyright: © 2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Dh_Buildsystems;
+
+use strict;
+use warnings;
+use Debian::Debhelper::Dh_Lib;
+
+use Exporter qw( import );
+our @EXPORT_OK = qw( DEFAULT_BUILD_DIRECTORY );
+
+# IMPORTANT: more specific buildsystems should go first
+my @BUILDSYSTEMS = (
+ "autotools",
+ "cmake",
+ "perl_build",
+ "perl_makefile",
+ "python_distutils",
+ "makefile",
+);
+
+sub DEFAULT_BUILD_DIRECTORY {
+ return "obj-" . dpkg_architecture_value("DEB_BUILD_GNU_TYPE");
+}
+
+sub new {
+ my $cls=shift;
+ my %opts=@_;
+ my $self = bless({
+ 'o_dir' => undef,
+ 'o_system' => undef,
+ 'loaded_buildsystems' => [] }, $cls);
+
+ if (!exists $opts{noenv}) {
+ if (exists $ENV{DH_AUTO_BUILDDIRECTORY}) {
+ $self->_set_build_directory_option("env", $ENV{DH_AUTO_BUILDDIRECTORY});
+ }
+ if (exists $ENV{DH_AUTO_BUILDSYSTEM}) {
+ $self->{o_system} = $ENV{DH_AUTO_BUILDSYSTEM};
+ }
+ }
+ return $self;
+}
+
+sub get_options {
+ my $self=shift;
+ my @options=@_;
+
+ my $set_dir = sub { $self->_set_build_directory_option(@_) };
+ my $list_bs = sub { $self->list_buildsystems(@_); exit 0 };
+
+ push @options, (
+ "b:s" => $set_dir,
+ "build-directory:s" => $set_dir,
+ "builddirectory:s" => $set_dir,
+
+ "m=s" => \$self->{o_system},
+ "build-system=s" => \$self->{o_system},
+ "buildsystem=s" => \$self->{o_system},
+
+ "l" => $list_bs,
+ "--list" => $list_bs,
+ );
+ my %options = @options;
+ return \%options;
+}
+
+sub _set_build_directory_option {
+ my ($self, $option, $value) = @_;
+ if (!$value || $value eq "auto") {
+ # Autogenerate build directory name
+ $self->{o_dir} = DEFAULT_BUILD_DIRECTORY;
+ }
+ else {
+ $self->{o_dir} = $value;
+ }
+}
+
+sub _dump_options {
+ my $self=shift;
+ for my $opt (qw(o_dir o_system)) {
+ if (defined $self->{$opt}) {
+ print $opt, ": ", $self->{$opt}, "\n";
+ }
+ }
+}
+
+sub _get_buildsystem_module {
+ my ($self, $system) = @_;
+ my $module = "Debian::Debhelper::Buildsystem::$system";
+
+ if (grep $module, @{$self->{loaded_buildsystems}} == 0) {
+ eval "use $module";
+ if ($@) {
+ error("Unable to load buildsystem '$system': $@");
+ }
+ push @{$self->{loaded_buildsystems}}, $module;
+ }
+ return $module;
+}
+
+sub load_buildsystem {
+ my ($self, $action, $system) = @_;
+
+ if (!defined $system) {
+ $system = $self->{o_system};
+ }
+ if (defined $system) {
+ my $module = $self->_get_buildsystem_module($system);
+ verbose_print("Selected buildsystem (specified): ".$module->NAME());
+ return $module->new($self->{o_dir});
+ }
+ else {
+ # Try to determine build system automatically
+ for $system (@BUILDSYSTEMS) {
+ my $module = $self->_get_buildsystem_module($system);
+ my $inst = $module->new($self->{o_dir});
+ if ($inst->is_buildable($action)) {
+ verbose_print("Selected buildsystem (auto): ".$module->NAME());
+ return $inst;
+ }
+ }
+ }
+ return;
+}
+
+sub load_all_buildsystems {
+ my $self=shift;
+ for my $system (@BUILDSYSTEMS) {
+ $self->_get_buildsystem_module($system);
+ }
+ return @{$self->{loaded_buildsystems}};
+}
+
+sub list_buildsystems {
+ my $self=shift;
+ for my $system ($self->load_all_buildsystems()) {
+ printf("%s - %s.\n", $system->NAME(), $system->DESCRIPTION());
+ }
+}
+
+sub init_dh_auto_tool {
+ my $self=shift;
+
+ Debian::Debhelper::Dh_Lib::init(
+ options => $self->get_options(@_));
+ $self->{initialized}=1;
+}
+
+sub run_dh_auto_tool {
+ my $self=shift;
+ my $toolname = basename($0);
+ my $buildsystem;
+
+ if (!exists $self->{initialized}) {
+ $self->init_dh_auto_tool();
+ }
+
+ # Guess action from the dh_auto_* name
+ $toolname =~ s/^dh_auto_//;
+ if (grep(/^\Q$toolname\E$/, qw{configure build test install clean}) == 0) {
+ error("Unrecognized dh auto tool: ".basename($0));
+ }
+
+ $buildsystem = $self->load_buildsystem($toolname);
+ if (defined $buildsystem) {
+ return $buildsystem->$toolname(@_, @{$dh{U_PARAMS}});
+ }
+ return 0;
+}
+
+1;