]> git.donarmstrong.com Git - debhelper.git/commitdiff
Modular object-orientied buildsystem implementation (try 2).
authorModestas Vainius <modestas@vainius.eu>
Tue, 14 Apr 2009 12:12:14 +0000 (15:12 +0300)
committerJoey Hess <joey@gnu.kitenet.net>
Tue, 14 Apr 2009 18:14:07 +0000 (14:14 -0400)
Major changess:

* Dh_Buildsystem_Option dropped and Dh_Buildsystem_Chdir functionality
  partitially merged into Dh_Buildsystem_Basic. Dh_Buildsystem_Bases.pm
  renamed to Dh_Buildsystem_Basic.pm to match classname.
* *_impl() ditched completely. Previous {configure,build,test,install,clean}_impl()
  renamed to just configure(), build(), test(), install(), clean() instead.
  Added pre_action($action) and post_action($action) hooks instead which are called
  by Dh_Buildsystems::buildsystems_do().
* Builddir is handled via mkdir_builddir(), doit_in_buildddir(), clean_builddir()
  methods which buildsystems should call directly. Removed get_top* method, added
  get_rel2builddir_path().
* is_buildable() method renamed to is_auto_buildable() to reflect its
  purpose more.
* ::perl_makefile renamed to ::perl_makemaker and which is based on ::makefile
  now. MakeMaker hack moved from ::makefile to ::perl_makemaker where it belongs
  (thanks for the tip).
* Dh_Buildsystems refactored into a simple perl module rather than OO class and
  simplified a bit.
* @BUILDSYSTEMS and is_auto_buildable() modified to 100% match historical order.

TODO: user documentation (e.g. DH_AUTO_BUILDDIRECTORY and DH_AUTO_BUILDSYSTEM
environment variables and common dh_auto_* options (--buildsystem and --builddirectory)).

Current plugin inheritance hierarchy is like this:

    Buildsystem::perl_build -> Dh_Buildsystem_Basic  <- Buildsystem::python_distutils
                                      ^
                                      |
                              Buildsystem::makefile  <- Buildsystem::perl_makemaker
                              ^       ^           ^
                             /        |             \
       Buildsystem::autotools  Buildsystem::cmake   Buildsystem::python_distutils

Signed-off-by: Modestas Vainius <modestas@vainius.eu>
15 files changed:
Debian/Debhelper/Buildsystem/autotools.pm
Debian/Debhelper/Buildsystem/cmake.pm
Debian/Debhelper/Buildsystem/makefile.pm
Debian/Debhelper/Buildsystem/perl_build.pm
Debian/Debhelper/Buildsystem/perl_makefile.pm [deleted file]
Debian/Debhelper/Buildsystem/perl_makemaker.pm [new file with mode: 0644]
Debian/Debhelper/Buildsystem/python_distutils.pm
Debian/Debhelper/Dh_Buildsystem_Bases.pm [deleted file]
Debian/Debhelper/Dh_Buildsystem_Basic.pm [new file with mode: 0644]
Debian/Debhelper/Dh_Buildsystems.pm
dh_auto_build
dh_auto_clean
dh_auto_configure
dh_auto_install
dh_auto_test

index 945ca4080ffaae8cbad3829c615bc3013c1fafcb..1ebc93846329f3a0247293e339712b9c54e39c4c 100644 (file)
@@ -15,17 +15,18 @@ sub DESCRIPTION {
        "support for building GNU Autotools based packages"
 }
 
-sub is_buildable {
+sub is_auto_buildable {
        my $self=shift;
-       my ($action) = @_;
+       my $action=shift;
+
+       # Handle configure; the rest - next class
        if ($action eq "configure") {
                return -x "configure";
-       } else {
-               return $self->SUPER::is_buildable(@_);
        }
+       return 0;
 }
 
-sub configure_impl {
+sub configure {
        my $self=shift;
 
        # Standard set of options for configure.
@@ -37,17 +38,7 @@ sub configure_impl {
        push @opts, "--infodir=\${prefix}/share/info";
        push @opts, "--sysconfdir=/etc";
        push @opts, "--localstatedir=/var";
-       # XXX JEH this is where the sheer evil of Dh_Buildsystem_Chdir
-       # becomes evident. Why is exec_in_topdir needed here?
-       # Because:
-       # - The parent class happens to be derived from Dh_Buildsystem_Chdir.
-       # - sourcepage() happens to, like many other parts of debhelper's
-       #   library, assume it's being run in the top of the source tree,
-       #   and fails if it's not.
-       # Having to worry about interactions like that for every line of
-       # every derived method is simply not acceptable.
-       # Dh_Buildsystem_Chdir must die! -- JEH
-       push @opts, "--libexecdir=\${prefix}/lib/" . $self->exec_in_topdir(\&sourcepackage);
+       push @opts, "--libexecdir=\${prefix}/lib/" . sourcepackage();
        push @opts, "--disable-maintainer-mode";
        push @opts, "--disable-dependency-tracking";
        # Provide --host only if different from --build, as recommended in
@@ -62,7 +53,9 @@ sub configure_impl {
        # but does not need to in the is_buildable method is not clear,
        # unless one is familiar with the implementation of its parent
        # class. I think that speaks to a bad design..
-       doit($self->get_toppath("configure"), @opts, @_);
+       # XXX MDX It should be more explicit now.
+       $self->mkdir_builddir();
+       $self->doit_in_builddir($self->get_rel2builddir_path("configure"), @opts, @_);
 }
 
 1;
index 00f6be4d771ea0712dd7771fa3f9c0fec6e1d1ef..026004a0704145f5adfd698d331ca3dc74083939 100644 (file)
@@ -10,45 +10,43 @@ 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 is_auto_buildable {
+       my $self=shift;
+       my ($action)=@_;
+       my $ret = -e "CMakeLists.txt";
+       $ret &&= $self->SUPER::is_auto_buildable(@_) if $action ne "configure";
+       return $ret;
 }
 
 sub new {
        my $cls=shift;
        my $self=$cls->SUPER::new(@_);
-       # Enfore outside-source tree builds.
+       # Enforce outside-source tree builds.
        $self->enforce_outside_source_building();
-       $self->{cmake_flags} = [];
        return $self;
 }
 
-sub configure_impl {
+sub configure {
        my $self=shift;
+       my @flags;
 
        # 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
-       # XXX JEH why are we using a method and an object
-       # field to build up a simple one-time-use list?
-       #       my @flags;
-       #       push @flags, ... if $foo
-
-       # XXX JEH again a non-sequitor get_topdir. 
-       doit("cmake", $self->get_topdir(), @{$self->{cmake_flags}}, @_);
+       push @flags, "-DCMAKE_INSTALL_PREFIX=/usr";
+       push @flags, "-DCMAKE_C_FLAGS=$ENV{CFLAGS}" if (exists $ENV{CFLAGS});
+       push @flags, "-DCMAKE_CXX_FLAGS=$ENV{CXXFLAGS}" if (exists $ENV{CXXFLAGS});
+       push @flags, "-DCMAKE_LD_FLAGS=$ENV{LDFLAGS}" if (exists $ENV{LDFLAGS});
+       push @flags, "-DCMAKE_SKIP_RPATH=ON";
+       push @flags, "-DCMAKE_VERBOSE_MAKEFILE=ON";
+
+       # XXX JEH again a non-sequitor get_topdir.
+       # XXX MDX I cannot avoid it as I need to pass the path to the sourcedir
+       # to cmake which is relative to the builddir.
+       $self->mkdir_builddir();
+       $self->doit_in_builddir("cmake", $self->get_rel2builddir_path(), @flags);
 }
 
 1;
index cbd9e3c38b213465a6f421b2160f61f3364c3840..7ffb048ed56c0981aa1861ed39fedf38d582df61 100644 (file)
@@ -8,30 +8,41 @@ 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';
+use base 'Debian::Debhelper::Dh_Buildsystem_Basic';
+
+# XXX JEH setting this env var is dodgy,
+# probably better to test if it exists with a default value.
+# (Factor out to helper function?)
+# XXX MDX Done. See new().
+
+sub get_makecmd_C {
+       my $self=shift;
+       if ($self->get_builddir()) {
+               return $self->{makecmd} . " -C " . $self->get_builddir();
+       }
+       return $self->{makecmd};
+}
 
 # XXX JEH I *like* this. Yay for factoring out ugly ugly stuff!
-sub _exists_make_target {
-       my ($cls, $target) = @_;
+# XXX MDX TODO: this could use dh debian/rules parser.
+sub exists_make_target {
+       my ($self, $target) = @_;
+       my $makecmd=$self->get_makecmd_C();
+
        # 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`;
+       my $ret=`$makecmd -s -n $target 2>/dev/null`;
        chomp $ret;
        return length($ret);
 }
 
-sub _make_first_existing_target {
-       my $cls = shift;
-       my $targets = shift;
+sub make_first_existing_target {
+       my $self=shift;
+       my $targets=shift;
 
-       # XXX JEH setting this env var is dodgy,
-       # probably better to test if it exists with a default value.
-       # (Factor out to helper function?)
-       $ENV{MAKE}="make" unless exists $ENV{MAKE};
        foreach my $target (@$targets) {
-               if ($cls->_exists_make_target($target)) {
-                       doit($ENV{MAKE}, $target, @_);
+               if ($self->exists_make_target($target)) {
+                       $self->doit_in_builddir($self->{makecmd}, $target, @_);
                        return $target;
                }
        }
@@ -42,56 +53,49 @@ sub DESCRIPTION {
        "support for building Makefile based packages (make && make install)"
 }
 
-sub is_buildable {
+sub new {
+       my $cls=shift;
+       my $self=$cls->SUPER::new(@_);
+       $self->{makecmd} = (exists $ENV{MAKE}) ? $ENV{MAKE} : "make";
+       return $self;
+}
+
+sub is_auto_buildable {
        my $self=shift;
        my ($action) = @_;
+
+       # Handles build, test, install, clean; configure - next class
        if (grep /^\Q$action\E$/, qw{build test install clean}) {
-               # XXX JEH why does get_buildpath need to be used 
-               # here? is_buildable is run at the top of the source
-               # directory, so -e 'Makefile' should be the same
+               # This is always called in the source directory, but generally
+               # Makefiles are created (or live) in the the build directory.
                return -e $self->get_buildpath("Makefile") ||
                       -e $self->get_buildpath("makefile") ||
                       -e $self->get_buildpath("GNUmakefile");
-       } else {
-               # XXX JEH why return 1 here?
-               return 1;
        }
+       return 0;
 }
 
-sub build_impl {
+sub build {
        my $self=shift;
-       doit(exists $ENV{MAKE} ? $ENV{MAKE} : "make", @_);
+       $self->doit_in_builddir($self->{makecmd}, @_);
 }
 
-sub test_impl {
+sub test {
        my $self=shift;
-       $self->_make_first_existing_target(['test', 'check'], @_);
+       $self->make_first_existing_target(['test', 'check'], @_);
 }
 
-sub install_impl {
+sub install {
        my $self=shift;
        my $destdir=shift;
-
-       # XXX JEH again with the setting the env var, see above..
-       $ENV{MAKE}="make" unless exists $ENV{MAKE};
-       my @params="DESTDIR=$destdir";
-
-       # Special case for MakeMaker generated Makefiles.
-       # XXX JEH This is a really unfortunate breaking of the
-       # encapsulation of the perl_makefile module. Perhaps it would be
-       # better for that module to contain some hack that injects that
-       # test into this one?
-       if (-e "Makefile" &&
-           system('grep -q "generated automatically by MakeMaker" Makefile') == 0) {
-               push @params, "PREFIX=/usr";
-       }
-
-       $self->_make_first_existing_target(['install'], @params, @_);
+       $self->make_first_existing_target(['install'], "DESTDIR=$destdir", @_);
 }
 
-sub clean_impl {
+sub clean {
        my $self=shift;
-       $self->_make_first_existing_target(['distclean', 'realclean', 'clean'], @_);
+       if (!$self->clean_builddir()) {
+               $self->make_first_existing_target(['distclean', 'realclean', 'clean'], @_);
+       }
 }
 
 1;
index a43d65dacd7a1cf8fa6d5cbf617c68c4cb92446d..9be71a27a81a01ff3550934dba832bd9af8e1b00 100644 (file)
@@ -8,26 +8,27 @@ 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 {
+sub is_auto_buildable {
        my ($self, $action) = @_;
-       my $ret = (-e "Build.PL");
+
+       # Handles everything
+       my $ret = -e "Build.PL";
        if ($action ne "configure") {
-               $ret &= (-e "Build");
+               $ret &&= -e "Build";
        }
        return $ret;
 }
 
-sub invoke_impl {
+sub do_perl {
        my $self=shift;
        $ENV{MODULEBUILDRC} = "/dev/null";
-       return $self->SUPER::invoke_impl(@_);
+       doit("perl", @_);
 }
 
 sub new {
@@ -37,33 +38,31 @@ sub new {
        return $self;
 }
 
-sub configure_impl {
+sub configure {
        my $self=shift;
-       # XXX JEH I think the below comment is inherited from elsewhere;
-       # doesn't really make sense now.
-       $ENV{PERL_MM_USE_DEFAULT}=1; # Module::Build can also use this.
-       doit("perl", "Build.PL", "installdirs=vendor", @_);
+       $ENV{PERL_MM_USE_DEFAULT}=1;
+       $self->do_perl("Build.PL", "installdirs=vendor", @_);
 }
 
-sub build_impl {
+sub build {
        my $self=shift;
-       doit("perl", "Build", @_);
+       $self->do_perl("Build", @_);
 }
 
-sub test_impl {
+sub test {
        my $self=shift;
-       doit(qw/perl Build test/, @_);
+       $self->do_perl("Build", "test", @_);
 }
 
-sub install_impl {
+sub install {
        my $self=shift;
        my $destdir=shift;
-       doit("perl", "Build", "install", "destdir=$destdir", "create_packlist=0", @_);
+       $self->do_perl("Build", "install", "destdir=$destdir", "create_packlist=0", @_);
 }
 
-sub clean_impl {
+sub clean {
        my $self=shift;
-       doit("perl", "Build", "--allow_mb_mismatch", 1, "distclean", @_);
+       $self->do_perl("Build", "--allow_mb_mismatch", 1, "distclean", @_);
 }
 
 1;
diff --git a/Debian/Debhelper/Buildsystem/perl_makefile.pm b/Debian/Debhelper/Buildsystem/perl_makefile.pm
deleted file mode 100644 (file)
index 67a6f44..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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/perl_makemaker.pm b/Debian/Debhelper/Buildsystem/perl_makemaker.pm
new file mode 100644 (file)
index 0000000..1553958
--- /dev/null
@@ -0,0 +1,71 @@
+# A buildsystem plugin for handling Perl MakeMaker based projects.
+#
+# Copyright: © 2008-2009 Joey Hess
+#            © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Buildsystem::perl_makemaker;
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use base 'Debian::Debhelper::Buildsystem::makefile';
+
+sub DESCRIPTION {
+       "support for building Perl MakeMaker based packages (in-source only)"
+}
+
+sub is_auto_buildable {
+       my ($self, $action)=@_;
+
+       # Handles configure, install; the rest - next class
+       if ($action eq "install") {
+               # This hack is needed to keep full 100% compatibility with previous
+               # debhelper versions.
+               if (-e "Makefile" &&
+                   system('grep -q "generated automatically by MakeMaker" Makefile') == 0) {
+                       return 1;
+               }
+       }
+       elsif ($action eq "configure") {
+               return -e "Makefile.PL";
+       }
+       else {
+               return 0;
+       }
+}
+
+sub new {
+       my $cls=shift;
+       my $self=$cls->SUPER::new(@_);
+       $self->enforce_in_source_building();
+       return $self;
+}
+
+sub configure {
+       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", @_);
+}
+
+sub install {
+       my $self=shift;
+       my $destdir=shift;
+       # XXX JEH This is a really unfortunate breaking of the
+       # encapsulation of the perl_makefile module. Perhaps it would be
+       # better for that module to contain some hack that injects that
+       # test into this one?
+       # XXX MDX Solved. perl_makemaker will need come before makefile in
+       # @BUILDSYSTEMS. See also hack in is_auto_buildable().
+       # This is a safety check needed to keep 100% compatibility with
+       # earlier debhelper behaviour. This if is very unlikely to be false.
+       if (-e "Makefile" &&
+           system('grep -q "generated automatically by MakeMaker" Makefile') == 0) {
+               $self->SUPER::install($destdir, "PREFIX=/usr", @_);
+       } else {
+               $self->SUPER::install($destdir, @_);
+       }
+}
+
+1;
index 2e7eacbb30eae5a9e3225e49d6b512f6ebd608e7..a69b36f4136e81e29aad249487bc93219e58b950 100644 (file)
@@ -9,54 +9,47 @@ 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';
+use base 'Debian::Debhelper::Dh_Buildsystem_Basic';
 
 sub DESCRIPTION {
        "support for building Python distutils based packages"
 }
 
-sub is_buildable {
-       return -e "setup.py";
+sub is_auto_buildable {
+       my $self=shift;
+       my $action=shift;
+
+       # Handle build install clean; the rest - next class
+       if (grep(/^\Q$action\E$/, qw{build install clean})) {
+               return -e "setup.py";
+       }
+       return 0;
 }
 
-sub get_builddir_option {
+sub setup_py {
        my $self=shift;
+       my $act=shift;
+
        if ($self->get_builddir()) {
-               return "--build-base=". $self->get_builddir();
+               unshift @_, "--build-base=" . $self->get_builddir();
        }
-       return;
+       doit("python", "setup.py", $act, @_);
 }
 
-# XXX JEH the default for all these methods is to do nothing successfully.
-# So either this, or those default stubs, need to be removed.
-sub configure_impl {
-       # Do nothing
-       1;
-}
-
-sub build_impl {
+sub build {
        my $self=shift;
-       doit("python", "setup.py", "build", @_);
-}
-
-# XXX JEH see anove comment
-sub test_impl {
-       1;
+       $self->setup_py("build", @_);
 }
 
-sub install_impl {
+sub install {
        my $self=shift;
        my $destdir=shift;
-
-       doit("python", "setup.py", "install", 
-            "--root=$destdir",
-            "--no-compile", "-O0", @_);
+       $self->setup_py("install", "--root=$destdir", "--no-compile", "-O0", @_);
 }
 
-sub clean_impl {
+sub clean {
        my $self=shift;
-       doit("python", "setup.py", "clean", "-a", @_);
+       $self->setup_py("clean", "-a", @_);
        # The setup.py might import files, leading to python creating pyc
        # files.
        doit('find', '.', '-name', '*.pyc', '-exec', 'rm', '{}', ';');
diff --git a/Debian/Debhelper/Dh_Buildsystem_Bases.pm b/Debian/Debhelper/Dh_Buildsystem_Bases.pm
deleted file mode 100644 (file)
index 2416453..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-# Defines base debhelper buildsystem class interface.
-#
-# Copyright: © 2008-2009 Modestas Vainius
-# License: GPL-2+
-
-# XXX JEH file name does not match package name (Bases vs Basic)
-# That will cause problems when using 'use' to load the module.
-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.
-# XXX JEH s/package/class/ in above comment for clarity..
-sub NAME {
-       my $self = shift;
-       my $cls = ref($self) || $self;
-       return ($cls =~ m/^.+::([^:]+)$/) ? $1 : "[invalid package name]";
-       # XXX JEH s/package/class/ in above message for clarity..
-       # (maybe dying on this unusual error would be better tho?)
-}
-
-# Description of the build system to be shown to the users.
-sub DESCRIPTION {
-       "basic debhelper build system class";
-}
-
-sub new {
-       my ($cls, $builddir) = @_;
-       # XXX JEH probably would be better to use named parameters here
-       # Also, if the builddir value is not specified, it could use
-       # DEFAULT_BUILD_DIRECTORY here. Which would allow moving that
-       # sub from Dh_Buildsystems to here, since it would no longer need
-       # to be used there.
-       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);
-       }
-}
-
-# XXX JEH this method seems entirely useless.
-#      $self->invoke_impl('foo', @_);
-#      $self->foo(@_);
-# The second is easier to both read and write.
-#
-# Turns out that one build system overrides this method,
-# perl_build uses it to set an env vatiable before each method
-# call. But that's unnecessary; it could just set it in its constructor.
-#
-# And there's another version of this method in the derifed class below,
-# which just adds another parameter to the method call. That is used only
-# by the python_distutils build system, to add a --build-base parameter
-# to two calls to python. It could be manually added to those two calls
-# with less fuss.
-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. 
-
-# XXX JEH if invoke_impl is done away with, these can be replaced
-# with the bodies of the foo_impl methods they call. That layer of
-# indirection is not really needed.
-
-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.
-# XXX JEH I don't see where this destdir parameter is passed in
-# to a call to $object->install ? In Dh_Buildsystems it does:
-#                 return $buildsystem->$toolname(@_, @{$dh{U_PARAMS}});
-# Which passes a different parameter, to ALL these methods.
-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.
-#
-# XXX JEH is there a reason for this to be in
-# Dh_Buildsystem_Option instead of the base class?
-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;
-}
-
-# XXX JEH if the reasoning for removing invoke_impl from above is followed,
-# then this whole derived class ends up not being needed.
-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;
-
-# XXX JEH I'm very leery of code that chdirs, it can be very hard to follow
-# and cause a lot of mess. (As we'll see in the buildsystem modules that
-# use this class.) It seems to me that this entire class could be
-# basically replaced by a doit_in_builddir() function.
-
-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_Buildsystem_Basic.pm b/Debian/Debhelper/Dh_Buildsystem_Basic.pm
new file mode 100644 (file)
index 0000000..cd4e448
--- /dev/null
@@ -0,0 +1,277 @@
+# Defines basic debhelper buildsystem class interface.
+#
+# Copyright: © 2008-2009 Modestas Vainius
+# License: GPL-2+
+
+package Debian::Debhelper::Dh_Buildsystem_Basic;
+
+use strict;
+use warnings;
+use Cwd;
+use File::Spec;
+use Debian::Debhelper::Dh_Lib;
+
+# Build system name. Defaults to the last component of the class
+# name. Do not override this method unless you know what you are
+# doing.
+sub NAME {
+       my $self=shift;
+       my $cls = ref($self) || $self;
+       if ($cls =~ m/^.+::([^:]+)$/) {
+               return $1;
+       }
+       else {
+               error("ınvalid buildsystem class name: $cls");
+       }
+}
+
+# Description of the build system to be shown to the users.
+sub DESCRIPTION {
+       "basic debhelper build system class (please provide description)";
+}
+
+# Default build directory. Can be overriden in the derived
+# class if really needed.
+sub DEFAULT_BUILD_DIRECTORY {
+       "obj-" . dpkg_architecture_value("DEB_BUILD_GNU_TYPE");
+}
+
+# XXX JEH Turns out that one build system overrides this method,
+# perl_build uses it to set an env vatiable before each method
+# call. But that's unnecessary; it could just set it in its constructor.
+# XXX MDX See comment below. is_auto is currently unused but I think it
+# is a good addition to the API for future cases.
+
+# Constructs a new build system object. Named parameters:
+# - builddir - specifies build directory to use. If not specified,
+#              in-source build will be performed. If undef or empty,
+#              default DEFAULT_BUILD_DIRECTORY will be used.
+# - is_auto -  might be used by the derived classes to determine if
+#              the build system has been picked up automatically.
+# Derived class can override the constructor to initialize common parameters.
+# Constructor SHOULD NOT be used to initialize build environment because
+# constructed class may not be eventually used to build the package (if e.g.
+# is_auto_buildable() returns 0).
+sub new {
+       my ($cls, %opts)=@_;
+
+       my $self = bless({ builddir => undef, is_auto => $opts{is_auto} }, $cls);
+       if (exists $opts{builddir}) {
+               if ($opts{builddir}) {
+                       $self->{builddir} = $opts{builddir};
+               }
+               else {
+                       $self->{builddir} = $self->DEFAULT_BUILD_DIRECTORY();
+               }
+       }
+       return $self;
+}
+
+# This instance method is called to check if the build system is capable
+# to auto build a source package. Additional argument $action describes
+# which operation the caller is going to perform (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
+# used in conjuction with @Dh_Buildsystems::BUILDSYSTEMS.
+#
+# 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_auto_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}) {
+               # Since this method is called in the constructor, emitting
+               # warnings immediatelly may cause too much noise when
+               # scanning for auto buildsystems or listing them.
+               push @{$self->{warnings}},
+                   $self->NAME()." buildsystem does not support building outside-source. In-source build enforced.";
+               $self->{builddir} = undef;
+       }
+}
+
+# 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 : $self->DEFAULT_BUILD_DIRECTORY();
+       }
+}
+
+# Get path to the specified build directory
+sub get_builddir {
+       my $self=shift;
+       return $self->{builddir};
+}
+
+# Construct absolute path to the file from the given path that is relative
+# to the build directory.
+sub get_buildpath {
+       my ($self, $path) = @_;
+       if ($self->get_builddir()) {
+               return File::Spec->catfile($self->get_builddir(), $path);
+       }
+       else {
+               return File::Spec->catfile('.', $path);
+       }
+}
+
+# When given a relative path in the source tree, converts it
+# to the path that is relative to the build directory.
+# If $path is not given, returns relative path to the root of the
+# source tree from the build directory.
+sub get_rel2builddir_path {
+       my $self=shift;
+       my $path=shift;
+
+       if (defined $path) {
+               $path = File::Spec->catfile(Cwd::getcwd(), $path);
+       }
+       else {
+               $path = Cwd::getcwd();
+       }
+       if ($self->get_builddir()) {
+               return File::Spec->abs2rel($path, Cwd::abs_path($self->get_builddir()));
+       }
+       return $path;
+}
+
+# XXX JEH I'm very leery of code that chdirs, it can be very hard to follow
+# and cause a lot of mess. (As we'll see in the buildsystem modules that
+# use this class.) It seems to me that this entire class could be
+# basically replaced by a doit_in_builddir() function.
+# XXX MDX implemented.
+
+sub _mkdir {
+       my ($cls, $dir)=@_;
+       if (-e $dir && ! -d $dir) {
+               error("error: unable to create '$dir': object already exists and is not a directory");
+       }
+       elsif (! -d $dir) {
+               verbose_print("mkdir '$dir'");
+               if (! $dh{NO_ACT}) {
+                       mkdir($dir, 0755) or error("error: unable to create '$dir': $!");
+               }
+               return 1;
+       }
+       return 0;
+}
+
+sub _cd {
+       my ($cls, $dir)=@_;
+       if (! $dh{NO_ACT}) {
+               chdir $dir or error("error: unable to chdir to $dir");
+       }
+}
+
+# Creates a build directory. Returns 1 if the directory was created
+# or 0 if it already exists or there is no need to create it.
+sub mkdir_builddir {
+       my $self=shift;
+       if ($self->get_builddir()) {
+               return $self->_mkdir($self->get_builddir());
+       }
+       return 0;
+}
+
+# Changes working directory the build directory (if needed), calls doit(@_)
+# and changes working directory back to the source directory.
+sub doit_in_builddir {
+       my $self=shift;
+       if ($self->get_builddir()) {
+               my $builddir = $self->get_builddir();
+               my $sourcedir = $self->get_rel2builddir_path();
+               verbose_print("cd to the build directory: $builddir");
+               $self->_cd($builddir);
+               doit(@_);
+               verbose_print("cd back to the source directory: $sourcedir");
+               $self->_cd($sourcedir);
+       }
+       else {
+               doit(@_);
+       }
+       return 1;
+}
+
+# In case of outside-source tree building, whole build directory
+# gets wiped (if it exists) and 1 is returned. Otherwise, nothing
+# is done and 0 is returned.
+sub clean_builddir {
+       my $self=shift;
+       if ($self->get_builddir()) {
+               if (-d $self->get_builddir()) {
+                       doit("rm", "-rf", $self->get_builddir());
+               }
+               return 1;
+       }
+       return 0;
+}
+
+
+# Instance method that is called before performing any action (see below).
+# Action name is passed as an argument. Derived classes overriding this
+# method should also call SUPER implementation of it.
+sub pre_action {
+       my $self=shift;
+       my $action=shift;
+
+       # Emit warnings pre action.
+       if (exists $self->{warnings}) {
+               for my $msg (@{$self->{warnings}}) {
+                       warning("warning: " . $msg);
+               }
+       }
+}
+
+# Instance method that is called after performing any action (see below).
+# Action name is passed as an argument. Derived classes overriding this
+# method should also call SUPER implementation of it.
+sub post_action {
+       my $self=shift;
+       my $action=shift;
+}
+
+# The instance methods below provide support for configuring,
+# building, testing, install and cleaning source packages.
+# In case of failure, the method may just error() out.
+#
+# These methods 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 {
+       my $self=shift;
+}
+
+sub build {
+       my $self=shift;
+}
+
+sub test {
+       my $self=shift;
+}
+
+# destdir parameter specifies where to install files.
+# XXX JEH I don't see where this destdir parameter is passed in
+# to a call to $object->install ? In Dh_Buildsystems it does:
+#                 return $buildsystem->$toolname(@_, @{$dh{U_PARAMS}});
+# Which passes a different parameter, to ALL these methods.
+# XXX MDX destdir is used in the dh_auto_install tool.
+sub install {
+       my $self=shift;
+       my $destdir=shift;
+}
+
+sub clean {
+       my $self=shift;
+}
+
+1;
index aa2dff99635710815b1f5193cc479b6db645be78..676551b9dce1ccf41ff1ccdb7f5c5ac31b124b4b 100644 (file)
@@ -1,4 +1,5 @@
 # A module for loading and managing debhelper buildsystem plugins.
+# This module is intended to be used by all dh_auto_* helper commands.
 #
 # Copyright: © 2009 Modestas Vainius
 # License: GPL-2+
@@ -9,124 +10,67 @@ use strict;
 use warnings;
 use Debian::Debhelper::Dh_Lib;
 
-use Exporter qw( import );
-our @EXPORT_OK = qw( DEFAULT_BUILD_DIRECTORY );
+use base 'Exporter';
+our @EXPORT=qw(&buildsystems_init &buildsystems_do &load_buildsystem);
 
-# IMPORTANT: more specific buildsystems should go first
 # XXX JEH as noted, this has to match historical order for back-compat
-my @BUILDSYSTEMS = (
+# XXX MDX Current dh_auto_* look like:
+# configure: autotools, perl_makemaker, perl_build
+# build:     makefile, python_distutils, perl_build
+# test:      makefile, perl_build
+# install:   makefile (with perl_makermaker) hack, python_distutils, perl_build
+# clean:     makefile, python_distutils, perl_build
+# So historical @BUILDSYSTEMS order (as per autodetection, see
+# is_auto_buildable() of the respective classes):
+#   autotools (+configure; the rest - next class)
+#   python_distutils (+build +install +clean; the rest - next class)
+#   perl_makemaker (+configure +install (special hack); the rest - next class)
+#   makefile (+build +test +install +clean; configure - next class)
+#   perl_build (handles everything)
+
+# Historical order must be kept for backwards compatibility. New
+# buildsystems MUST be added to the END of the list.
+our @BUILDSYSTEMS = (
     "autotools",
-    "cmake",
-    "perl_build",
-    "perl_makefile",
     "python_distutils",
+    "perl_makemaker",
     "makefile",
+    "perl_build",
+    "cmake",
 );
 
-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);
-
-       # XXX JEH AFAICS, these 2 env variables are never used or documented
-       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 {
-       # XXX JEH option argument is not used, would be less confusing to
-       # not pass extra getopt value in
-       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 create_buildsystem_instance {
+       my $system=shift;
+       my %bsopts=@_;
+       my $module = "Debian::Debhelper::Buildsystem::$system";
 
-# XXX JEH this sub is not used
-sub _dump_options {
-       my $self=shift;
-       for my $opt (qw(o_dir o_system)) {
-               if (defined $self->{$opt}) {
-                       print $opt, ": ", $self->{$opt}, "\n";
-               }
+       eval "use $module";
+       if ($@) {
+               error("unable to load buildsystem class '$system': $@");
        }
-}
-
-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;
+       if (!exists $bsopts{builddir} && exists $dh{BUILDDIR}) {
+               $bsopts{builddir} = $dh{BUILDDIR};
        }
-       return $module;
+       return $module->new(%bsopts);
 }
 
 sub load_buildsystem {
        # XXX JEH the $system param is never passed
        # by any call to this function
-       my ($self, $action, $system) = @_;
-
-       if (!defined $system) {
-               $system = $self->{o_system};
-       }
+       # XXX MDX Yes, it was sort of redudant. But see buildsystems_do() now.
+       my ($action, $system)=@_;
        if (defined $system) {
-               my $module =  $self->_get_buildsystem_module($system);
-               verbose_print("Selected buildsystem (specified): ".$module->NAME());
-               return $module->new($self->{o_dir});
+               my $inst = create_buildsystem_instance($system);
+               verbose_print("Selected buildsystem (specified): ".$inst->NAME());
+               return $inst;
        }
        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());
+                       my $inst = create_buildsystem_instance($system, is_auto=>1);
+                       if ($inst->is_auto_buildable($action)) {
+                               verbose_print("Selected buildsystem (auto): ". $inst->NAME());
                                return $inst;
                        }
                }
@@ -134,48 +78,67 @@ sub load_buildsystem {
        return;
 }
 
-sub load_all_buildsystems {
-       my $self=shift;
+sub list_buildsystems {
        for my $system (@BUILDSYSTEMS) {
-               $self->_get_buildsystem_module($system);
+               my $inst = create_buildsystem_instance($system);
+               printf("%s - %s.\n", $inst->NAME(), $inst->DESCRIPTION());
        }
-       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 buildsystems_init {
+       my %args=@_;
+
+       # XXX JEH AFAICS, these 2 env variables are never used or documented
+       # XXX MDX They are used (see below), not documented though.
+       # TODO: Not documented in the manual pages yet.
+       # Initialize options from environment variables
+       if (exists $ENV{DH_AUTO_BUILDDIRECTORY}) {
+               $dh{BUILDDIR} = $ENV{DH_AUTO_BUILDDIRECTORY};
        }
-}
+       if (exists $ENV{DH_AUTO_BUILDSYSTEM}) {
+               $dh{BUILDSYS} = $ENV{DH_AUTO_BUILDSYSTEM};
+       }
+
+       # Available command line options
+       my $list_bs = sub { list_buildsystems(); exit 0 };
+       my $set_builddir = sub { $dh{BUILDDIR} = $_[1] };
+       my %options = (
+           "b:s" => $set_builddir,
+           "build-directory:s" => $set_builddir,
+           "builddirectory:s" => $set_builddir,
 
-sub init_dh_auto_tool {
-       my $self=shift;
+           "m=s" => \$dh{BUILDSYS},
+           "build-system=s" => \$dh{BUILDSYS},
+           "buildsystem=s" => \$dh{BUILDSYS},
 
-       Debian::Debhelper::Dh_Lib::init(
-           options => $self->get_options(@_));
-       $self->{initialized}=1;
+           "l" => $list_bs,
+           "--list" => $list_bs,
+       );
+       map { $args{options}{$_} = $options{$_} } keys(%options);
+       Debian::Debhelper::Dh_Lib::init(%args);
 }
 
-sub run_dh_auto_tool {
-       my $self=shift;
-       my $toolname = basename($0);
-       my $buildsystem;
+sub buildsystems_do {
+       my $action=shift;
 
-       # XXX JEH does this if ever not fire?
-       if (!exists $self->{initialized}) {
-               $self->init_dh_auto_tool();
+       if (!defined $action) {
+               $action = basename($0);
+               $action =~ s/^dh_auto_//;
        }
 
-       # 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));
+       # XXX JEH does this if ever not fire?
+       # XXX MDX See dh_auto_install. I'm removing this anyway
+       # and making buildsystem_init() call in dh_auto_* mandatory.
+
+       if (grep(/^\Q$action\E$/, qw{configure build test install clean}) == 0) {
+               error("unrecognized auto action: ".basename($0));
        }
 
-       $buildsystem = $self->load_buildsystem($toolname);
+       my $buildsystem = load_buildsystem($action, $dh{BUILDSYS});
        if (defined $buildsystem) {
-               return $buildsystem->$toolname(@_, @{$dh{U_PARAMS}});
+               $buildsystem->pre_action($action);
+               $buildsystem->$action(@_, @{$dh{U_PARAMS}});
+               $buildsystem->post_action($action);
        }
        return 0;
 }
@@ -186,5 +149,10 @@ sub run_dh_auto_tool {
 # that parses the command line, loads the specified system, and uses it,
 # passing it the build directory. It would be both shorter and easier to
 # understand.
+# XXX I refactored this into a module rather than OO class. I do not agree
+# about a single sub though as it is more complicated than that and
+# I think it is more clear to have the code segmented a bit. See also
+# dh_auto_install why both buildsystems_init() and buildsystems_do()
+# are needed.
 
 1;
index 9cfe70ef9b1eeb1658d94eb44fb1de402c3853a1..56b9b5f078dddb4966b4831e81a5a2c2654b9dd8 100755 (executable)
@@ -37,8 +37,8 @@ or override any standard parameters that dh_auto_build passes.
 
 =cut
 
-my $manager = new Debian::Debhelper::Dh_Buildsystems;
-$manager->run_dh_auto_tool();
+buildsystems_init();
+buildsystems_do();
 
 =head1 SEE ALSO
 
index 75f3ce480e7b4b356a5ffa4fa60044b71d6b860c..1b7d46cd4abcc35e81e0d2d35e4c690d9c6207f6 100755 (executable)
@@ -38,8 +38,8 @@ or override the any standard parameters that dh_auto_clean passes.
 
 =cut
 
-my $manager = new Debian::Debhelper::Dh_Buildsystems;
-$manager->run_dh_auto_tool();
+buildsystems_init();
+buildsystems_do();
 
 =head1 SEE ALSO
 
index e846e99901fe80e17a15255649fc8bead0c67ac5..416c25b315139c72b6db0eadf2a04afa2b692efe 100755 (executable)
@@ -38,8 +38,8 @@ or override the standard parameters that dh_auto_configure passes.
 
 =cut
 
-my $manager = new Debian::Debhelper::Dh_Buildsystems;
-$manager->run_dh_auto_tool();
+buildsystems_init();
+buildsystems_do();
 
 =head1 SEE ALSO
 
index c115a184aa791d278fcb1e2500bbd354b9518eac..db2c6e900f050ca275f6ce69e0c8641e41ce5c26 100755 (executable)
@@ -49,8 +49,7 @@ or override the any standard parameters that dh_auto_install passes.
 
 =cut
 
-my $manager = new Debian::Debhelper::Dh_Buildsystems;
-$manager->init_dh_auto_tool();
+buildsystems_init();
 
 my $destdir;
 my @allpackages=getpackages();
@@ -62,7 +61,7 @@ else {
 }
 $destdir=cwd()."/".$destdir;
 
-$manager->run_dh_auto_tool($destdir);
+buildsystems_do("install", $destdir);
 
 =head1 SEE ALSO
 
index 9dda30fb15412c0c12bcf4d822ee001ac77d8c2d..e68bf09a043f745c26acab66e1f4d5876097d3a0 100755 (executable)
@@ -48,8 +48,8 @@ if (defined $ENV{DEB_BUILD_OPTIONS} && $ENV{DEB_BUILD_OPTIONS} =~ /nocheck/) {
        exit 0;
 }
 
-my $manager = new Debian::Debhelper::Dh_Buildsystems;
-$manager->run_dh_auto_tool();
+buildsystems_init();
+buildsystems_do();
 
 =head1 SEE ALSO