diff --git a/lib/spack/spack/build_systems/autotools.py b/lib/spack/spack/build_systems/autotools.py
index d08ea0242831b66e2cce260c63cfbe2e264c5ab3..af6f5507b23f40c195b98e4c31cb418b0cd92443 100644
--- a/lib/spack/spack/build_systems/autotools.py
+++ b/lib/spack/spack/build_systems/autotools.py
@@ -30,8 +30,10 @@
 from subprocess import PIPE
 from subprocess import check_call
 
-from llnl.util.filesystem import working_dir
-from spack.package import PackageBase, run_after
+import llnl.util.tty as tty
+from llnl.util.filesystem import working_dir, join_path, force_remove
+from spack.package import PackageBase, run_after, run_before
+from spack.util.executable import Executable
 
 
 class AutotoolsPackage(PackageBase):
@@ -79,8 +81,14 @@ class AutotoolsPackage(PackageBase):
     #: phase
     install_targets = ['install']
 
+    #: Callback names for build-time test
     build_time_test_callbacks = ['check']
 
+    #: Set to true to force the autoreconf step even if configure is present
+    force_autoreconf = False
+    #: Options to be passed to autoreconf when using the default implementation
+    autoreconf_extra_args = []
+
     def _do_patch_config_guess(self):
         """Some packages ship with an older config.guess and need to have
         this updated when installed on a newer architecture."""
@@ -147,9 +155,26 @@ def _do_patch_config_guess(self):
 
         return False
 
+    @property
+    def configure_directory(self):
+        """Returns the directory where 'configure' resides.
+
+        :return: directory where to find configure
+        """
+        return self.stage.source_path
+
+    @property
+    def configure_abs_path(self):
+        # Absolute path to configure
+        configure_abs_path = join_path(
+            os.path.abspath(self.configure_directory), 'configure'
+        )
+        return configure_abs_path
+
+    @property
     def build_directory(self):
         """Override to provide another place to build the package"""
-        return self.stage.source_path
+        return self.configure_directory
 
     def patch(self):
         """Patches config.guess if
@@ -165,21 +190,62 @@ def patch(self):
             if not self._do_patch_config_guess():
                 raise RuntimeError('Failed to find suitable config.guess')
 
+    @run_before('autoreconf')
+    def delete_configure_to_force_update(self):
+        if self.force_autoreconf:
+            force_remove(self.configure_abs_path)
+
     def autoreconf(self, spec, prefix):
         """Not needed usually, configure should be already there"""
-        pass
+        # If configure exists nothing needs to be done
+        if os.path.exists(self.configure_abs_path):
+            return
+        # Else try to regenerate it
+        autotools = ['m4', 'autoconf', 'automake', 'libtool']
+        missing = [x for x in autotools if x not in spec]
+        if missing:
+            msg = 'Cannot generate configure: missing dependencies {0}'
+            raise RuntimeError(msg.format(missing))
+        tty.msg('Configure script not found: trying to generate it')
+        tty.warn('*********************************************************')
+        tty.warn('* If the default procedure fails, consider implementing *')
+        tty.warn('*        a custom AUTORECONF phase in the package       *')
+        tty.warn('*********************************************************')
+        with working_dir(self.configure_directory):
+            m = inspect.getmodule(self)
+            # This part should be redundant in principle, but
+            # won't hurt
+            m.libtoolize()
+            m.aclocal()
+            # This line is what is needed most of the time
+            # --install, --verbose, --force
+            autoreconf_args = ['-ivf']
+            if 'pkg-config' in spec:
+                autoreconf_args += [
+                    '-I',
+                    join_path(spec['pkg-config'].prefix, 'share', 'aclocal'),
+                ]
+            autoreconf_args += self.autoreconf_extra_args
+            m.autoreconf(*autoreconf_args)
 
     @run_after('autoreconf')
-    def is_configure_or_die(self):
-        """Checks the presence of a `configure` file after the
-        :py:meth:`.autoreconf` phase.
+    def set_configure_or_die(self):
+        """Checks the presence of a ``configure`` file after the
+        autoreconf phase. If it is found sets a module attribute
+        appropriately, otherwise raises an error.
 
-        :raise RuntimeError: if the ``configure`` script does not exist.
+        :raises RuntimeError: if a configure script is not found in
+            :py:meth:`~.configure_directory`
         """
-        with working_dir(self.build_directory()):
-            if not os.path.exists('configure'):
-                raise RuntimeError(
-                    'configure script not found in {0}'.format(os.getcwd()))
+        # Check if a configure script is there. If not raise a RuntimeError.
+        if not os.path.exists(self.configure_abs_path):
+            msg = 'configure script not found in {0}'
+            raise RuntimeError(msg.format(self.configure_directory))
+
+        # Monkey-patch the configure script in the corresponding module
+        inspect.getmodule(self).configure = Executable(
+            self.configure_abs_path
+        )
 
     def configure_args(self):
         """Produces a list containing all the arguments that must be passed to
@@ -195,21 +261,21 @@ def configure(self, spec, prefix):
         """
         options = ['--prefix={0}'.format(prefix)] + self.configure_args()
 
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory, create=True):
             inspect.getmodule(self).configure(*options)
 
     def build(self, spec, prefix):
         """Makes the build targets specified by
         :py:attr:``~.AutotoolsPackage.build_targets``
         """
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             inspect.getmodule(self).make(*self.build_targets)
 
     def install(self, spec, prefix):
         """Makes the install targets specified by
         :py:attr:``~.AutotoolsPackage.install_targets``
         """
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             inspect.getmodule(self).make(*self.install_targets)
 
     run_after('build')(PackageBase._run_default_build_time_test_callbacks)
@@ -218,7 +284,7 @@ def check(self):
         """Searches the Makefile for targets ``test`` and ``check``
         and runs them if found.
         """
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             self._if_make_target_execute('test')
             self._if_make_target_execute('check')
 
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
index 823ef502c408a2e95b1ef32eb4348f85b902127c..43d177d3cb67a1fcac4657a6db4c4f4048ee7468 100644
--- a/lib/spack/spack/build_systems/cmake.py
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -82,6 +82,7 @@ def build_type(self):
         """
         return 'RelWithDebInfo'
 
+    @property
     def root_cmakelists_dir(self):
         """Returns the location of the root CMakeLists.txt
 
@@ -119,6 +120,7 @@ def _std_args(pkg):
         args.append('-DCMAKE_INSTALL_RPATH:STRING={0}'.format(rpaths))
         return args
 
+    @property
     def build_directory(self):
         """Returns the directory to use when building the package
 
@@ -141,19 +143,19 @@ def cmake_args(self):
 
     def cmake(self, spec, prefix):
         """Runs ``cmake`` in the build directory"""
-        options = [self.root_cmakelists_dir()] + self.std_cmake_args + \
+        options = [self.root_cmakelists_dir] + self.std_cmake_args + \
             self.cmake_args()
-        with working_dir(self.build_directory(), create=True):
+        with working_dir(self.build_directory, create=True):
             inspect.getmodule(self).cmake(*options)
 
     def build(self, spec, prefix):
         """Make the build targets"""
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             inspect.getmodule(self).make(*self.build_targets)
 
     def install(self, spec, prefix):
         """Make the install targets"""
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             inspect.getmodule(self).make(*self.install_targets)
 
     run_after('build')(PackageBase._run_default_build_time_test_callbacks)
@@ -162,7 +164,7 @@ def check(self):
         """Searches the CMake-generated Makefile for the target ``test``
         and runs it if found.
         """
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             self._if_make_target_execute('test')
 
     # Check that self.prefix is there after installation
diff --git a/lib/spack/spack/build_systems/makefile.py b/lib/spack/spack/build_systems/makefile.py
index f07bcd62ab6ab99205d8757adea675c22987f920..727438447827fb6edea16985408df7f21130e04e 100644
--- a/lib/spack/spack/build_systems/makefile.py
+++ b/lib/spack/spack/build_systems/makefile.py
@@ -72,6 +72,7 @@ class MakefilePackage(PackageBase):
     #: phase
     install_targets = ['install']
 
+    @property
     def build_directory(self):
         """Returns the directory containing the main Makefile
 
@@ -89,14 +90,14 @@ def build(self, spec, prefix):
         """Calls make, passing :py:attr:`~.MakefilePackage.build_targets`
         as targets.
         """
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             inspect.getmodule(self).make(*self.build_targets)
 
     def install(self, spec, prefix):
         """Calls make, passing :py:attr:`~.MakefilePackage.install_targets`
         as targets.
         """
-        with working_dir(self.build_directory()):
+        with working_dir(self.build_directory):
             inspect.getmodule(self).make(*self.install_targets)
 
     # Check that self.prefix is there after installation
diff --git a/lib/spack/spack/build_systems/python.py b/lib/spack/spack/build_systems/python.py
index 5e7c1c356d031fadd5921fb061b5d6c6a45ae6e0..60a850d35636987e61f0797956558558fec55b4a 100644
--- a/lib/spack/spack/build_systems/python.py
+++ b/lib/spack/spack/build_systems/python.py
@@ -97,10 +97,11 @@ def configure(self, spec, prefix):
 
     extends('python')
 
-    def setup_file(self, spec, prefix):
+    def setup_file(self):
         """Returns the name of the setup file to use."""
         return 'setup.py'
 
+    @property
     def build_directory(self):
         """The directory containing the ``setup.py`` file."""
         return self.stage.source_path
@@ -109,7 +110,7 @@ def python(self, *args):
         inspect.getmodule(self).python(*args)
 
     def setup_py(self, *args):
-        setup = self.setup_file(self.spec, self.prefix)
+        setup = self.setup_file()
 
         with working_dir(self.build_directory()):
             self.python(setup, '--no-user-cfg', *args)
diff --git a/var/spack/repos/builtin/packages/astyle/package.py b/var/spack/repos/builtin/packages/astyle/package.py
index 16c59469fab114791bca36de08ce7162dae5f07d..851952be6606b855a354784110deb819b8d65d16 100644
--- a/var/spack/repos/builtin/packages/astyle/package.py
+++ b/var/spack/repos/builtin/packages/astyle/package.py
@@ -39,6 +39,7 @@ class Astyle(MakefilePackage):
 
     parallel = False
 
+    @property
     def build_directory(self):
         return join_path(self.stage.source_path, 'build', self.compiler.name)
 
diff --git a/var/spack/repos/builtin/packages/autoconf/package.py b/var/spack/repos/builtin/packages/autoconf/package.py
index d812350ae8fc4710f5bce148b16c20fcff892a70..3dcf8f36b5f03ea0597491c88f5d7919a161c6af 100644
--- a/var/spack/repos/builtin/packages/autoconf/package.py
+++ b/var/spack/repos/builtin/packages/autoconf/package.py
@@ -38,6 +38,8 @@ class Autoconf(AutotoolsPackage):
 
     depends_on('m4@1.4.6:',   type='build')
 
+    build_directory = 'spack-build'
+
     def _make_executable(self, name):
         return Executable(join_path(self.prefix.bin, name))
 
diff --git a/var/spack/repos/builtin/packages/automake/package.py b/var/spack/repos/builtin/packages/automake/package.py
index 6c0a47ff95a14a67f0e9663a3cffee7b2476695c..8643f5d836429fb9fc61972b0f09c248ae8f1528 100644
--- a/var/spack/repos/builtin/packages/automake/package.py
+++ b/var/spack/repos/builtin/packages/automake/package.py
@@ -37,6 +37,8 @@ class Automake(AutotoolsPackage):
 
     depends_on('autoconf', type='build')
 
+    build_directory = 'spack-build'
+
     def _make_executable(self, name):
         return Executable(join_path(self.prefix.bin, name))
 
diff --git a/var/spack/repos/builtin/packages/bash-completion/package.py b/var/spack/repos/builtin/packages/bash-completion/package.py
index 666a1bef13e69acd8cc91ee18998d90843b8a23a..0bd4d7c294add767683f5d48aab69ed37ab20812 100644
--- a/var/spack/repos/builtin/packages/bash-completion/package.py
+++ b/var/spack/repos/builtin/packages/bash-completion/package.py
@@ -25,10 +25,10 @@
 from spack import *
 
 
-class BashCompletion(Package):
+class BashCompletion(AutotoolsPackage):
     """Programmable completion functions for bash."""
     homepage = "https://github.com/scop/bash-completion"
-    url      = "https://github.com/scop/bash-completion/archive/2.3.tar.gz"
+    url = "https://github.com/scop/bash-completion/archive/2.3.tar.gz"
 
     version('2.3', '67e50f5f3c804350b43f2b664c33dde811d24292')
     version('develop',  git='https://github.com/scop/bash-completion.git')
@@ -41,16 +41,9 @@ class BashCompletion(Package):
     # Other dependencies
     depends_on('bash@4.1:', type='run')
 
-    def install(self, spec, prefix):
-        make_args = ['--prefix=%s' % prefix]
-
-        autoreconf('-i')
-        configure(*make_args)
-        make()
-        # make("check") # optional, requires dejagnu and tcllib
-        make("install",
-             parallel=False)
-
+    @run_after('install')
+    def show_message_to_user(self):
+        prefix = self.prefix
         # Guidelines for individual user as provided by the author at
         # https://github.com/scop/bash-completion
         print('=====================================================')
@@ -59,6 +52,6 @@ def install(self, spec, prefix):
         print('')
         print('# Use bash-completion, if available')
         print('[[ $PS1 && -f %s/share/bash-completion/bash_completion ]] && \ ' % prefix)  # NOQA: ignore=E501
-        print('    . %s/share/bash-completion/bash_completion'  % prefix)
+        print('    . %s/share/bash-completion/bash_completion' % prefix)
         print('')
         print('=====================================================')
diff --git a/var/spack/repos/builtin/packages/bison/package.py b/var/spack/repos/builtin/packages/bison/package.py
index cc2d10dea11c2082e93ce4e4be2f3c7722fef958..a9691fab8b1b565e64e84b145753c73d27b768d1 100644
--- a/var/spack/repos/builtin/packages/bison/package.py
+++ b/var/spack/repos/builtin/packages/bison/package.py
@@ -36,3 +36,5 @@ class Bison(AutotoolsPackage):
     version('3.0.4', 'a586e11cd4aff49c3ff6d3b6a4c9ccf8')
 
     depends_on("m4", type='build')
+
+    build_directory = 'spack-build'
diff --git a/var/spack/repos/builtin/packages/czmq/package.py b/var/spack/repos/builtin/packages/czmq/package.py
index f7791967b3674262b0516fdfe048638ed09de26f..fd50197326dabc78e61542e90f0991c719224997 100644
--- a/var/spack/repos/builtin/packages/czmq/package.py
+++ b/var/spack/repos/builtin/packages/czmq/package.py
@@ -38,19 +38,3 @@ class Czmq(AutotoolsPackage):
     depends_on('autoconf', type='build')
     depends_on('pkg-config', type='build')
     depends_on('zeromq')
-
-    def autoreconf(self, spec, prefix):
-        # Work around autogen.sh oddities
-        # bash = which("bash")
-        # bash("./autogen.sh")
-        mkdirp("config")
-        autoreconf = which("autoreconf")
-        autoreconf("--install", "--verbose", "--force",
-                   "-I", "config",
-                   "-I", join_path(spec['pkg-config'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['automake'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['libtool'].prefix,
-                                   "share", "aclocal"),
-                   )
diff --git a/var/spack/repos/builtin/packages/elfutils/package.py b/var/spack/repos/builtin/packages/elfutils/package.py
index bdc858e121eae7cf6d49b27765f5eabefcc4a263..4a91c7db304bb4ed6728dc5ffe7f3fe7c0ec6794 100644
--- a/var/spack/repos/builtin/packages/elfutils/package.py
+++ b/var/spack/repos/builtin/packages/elfutils/package.py
@@ -35,15 +35,15 @@ class Elfutils(AutotoolsPackage):
 
     homepage = "https://fedorahosted.org/elfutils/"
 
+    depends_on('libtool', type='build')
+    depends_on('automake', type='build')
+    depends_on('autoconf', type='build')
+
     version('0.163',
             git='git://git.fedorahosted.org/git/elfutils.git',
             tag='elfutils-0.163')
 
     provides('elf')
 
-    def autoreconf(self, spec, prefix):
-        autoreconf = which('autoreconf')
-        autoreconf('-if')
-
     def configure_args(self):
         return ['--enable-maintainer-mode']
diff --git a/var/spack/repos/builtin/packages/flex/package.py b/var/spack/repos/builtin/packages/flex/package.py
index e4117877c17de41158e42aba2316a48ed062fc0c..0314950140fe006f89bf883a7843adda5a1b1a0e 100644
--- a/var/spack/repos/builtin/packages/flex/package.py
+++ b/var/spack/repos/builtin/packages/flex/package.py
@@ -61,11 +61,3 @@ def url_for_version(self, version):
             url += "/archive/flex-{0}.tar.gz".format(version.dashed)
 
         return url
-
-    def autoreconf(self, spec, prefix):
-        pass
-
-    @when('@:2.6.0')
-    def autoreconf(self, spec, prefix):
-        libtoolize('--install', '--force')
-        autoreconf('--install', '--force')
diff --git a/var/spack/repos/builtin/packages/gcc/package.py b/var/spack/repos/builtin/packages/gcc/package.py
index 31da068d72d2442c9991d7056e1ae347ab20563b..a9fed4d8dd25059054fb87d22d7a990dec68ec1d 100644
--- a/var/spack/repos/builtin/packages/gcc/package.py
+++ b/var/spack/repos/builtin/packages/gcc/package.py
@@ -30,7 +30,7 @@
 from os.path import isfile
 
 
-class Gcc(Package):
+class Gcc(AutotoolsPackage):
     """The GNU Compiler Collection includes front ends for C, C++,
        Objective-C, Fortran, and Java."""
     homepage = "https://gcc.gnu.org"
@@ -85,7 +85,9 @@ class Gcc(Package):
     patch('piclibs.patch', when='+piclibs')
     patch('gcc-backport.patch', when='@4.7:4.9.2,5:5.3')
 
-    def install(self, spec, prefix):
+    def configure_args(self):
+        spec = self.spec
+        prefix = self.spec.prefix
         # libjava/configure needs a minor fix to install into spack paths.
         filter_file(r"'@.*@'", "'@[[:alnum:]]*@'", 'libjava/configure',
                     string=True)
@@ -138,18 +140,15 @@ def install(self, spec, prefix):
             darwin_options = ["--with-build-config=bootstrap-debug"]
             options.extend(darwin_options)
 
-        build_dir = join_path(self.stage.path, 'spack-build')
-        configure = Executable(join_path(self.stage.source_path, 'configure'))
-        with working_dir(build_dir, create=True):
-            # Rest of install is straightforward.
-            configure(*options)
-            if sys.platform == 'darwin':
-                make("bootstrap")
-            else:
-                make()
-            make("install")
+        return options
 
-        self.write_rpath_specs()
+    build_directory = 'spack-build'
+
+    @property
+    def build_targets(self):
+        if sys.platform == 'darwin':
+            return ['bootstrap']
+        return []
 
     @property
     def spec_dir(self):
@@ -157,6 +156,7 @@ def spec_dir(self):
         spec_dir = glob("%s/lib64/gcc/*/*" % self.prefix)
         return spec_dir[0] if spec_dir else None
 
+    @run_after('install')
     def write_rpath_specs(self):
         """Generate a spec file so the linker adds a rpath to the libs
            the compiler used to build the executable."""
diff --git a/var/spack/repos/builtin/packages/glib/package.py b/var/spack/repos/builtin/packages/glib/package.py
index a4d8c289d73d8a69c2d62bc1d3a085be86d436b1..e2eb984876c02e88cc8c289f50a7b2fb3b4a52bf 100644
--- a/var/spack/repos/builtin/packages/glib/package.py
+++ b/var/spack/repos/builtin/packages/glib/package.py
@@ -53,22 +53,9 @@ class Glib(AutotoolsPackage):
     # around a legitimate usage.
     patch('no-Werror=format-security.patch')
 
+    force_autoreconf = True
+
     def url_for_version(self, version):
         """Handle glib's version-based custom URLs."""
         url = 'http://ftp.gnome.org/pub/gnome/sources/glib'
         return url + '/%s/glib-%s.tar.xz' % (version.up_to(2), version)
-
-    def autoreconf(self, spec, prefix):
-        autoreconf = which("autoreconf")
-        autoreconf("--install", "--verbose", "--force",
-                   "-I", "config",
-                   "-I", join_path(spec['pkg-config'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['automake'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['libtool'].prefix,
-                                   "share", "aclocal"),
-                   )
-
-    def install(self, spec, prefix):
-        make("install", parallel=False)
diff --git a/var/spack/repos/builtin/packages/gource/package.py b/var/spack/repos/builtin/packages/gource/package.py
index dda00420a3816c0d8b9312e30bc3c2be1e2b54ad..21994ad42ca7981006a4d6f89025f859c3ccd93b 100644
--- a/var/spack/repos/builtin/packages/gource/package.py
+++ b/var/spack/repos/builtin/packages/gource/package.py
@@ -25,11 +25,11 @@
 from spack import *
 
 
-class Gource(Package):
+class Gource(AutotoolsPackage):
     """Software version control visualization."""
 
     homepage = "http://gource.io"
-    url      = "https://github.com/acaudwell/Gource/releases/download/gource-0.44/gource-0.44.tar.gz"
+    url = "https://github.com/acaudwell/Gource/releases/download/gource-0.44/gource-0.44.tar.gz"
 
     version('0.44', '79cda1bfaad16027d59cce55455bfab88b57c69d')
 
@@ -49,15 +49,17 @@ class Gource(Package):
     depends_on('sdl2')
     depends_on('sdl2-image')
 
-    def install(self, spec, prefix):
-        make_args = ['--prefix=%s' % prefix,
-                     '--disable-dependency-tracking',
-                     '--without-x',
-                     '--with-boost=%s' % spec['boost'].prefix]
+    parallel = False
+    force_autoreconf = True
 
-        autoreconf('-i')
-        configure(*make_args)
-        make()
+    def url_for_version(self, version):
+        tmp = 'https://github.com/acaudwell/Gource/releases/download/gource-{0}/gource-{0}.tar.gz'  # NOQA: ignore=E501
+        return tmp.format(version.dotted)
 
-        make("install",
-             parallel=False)
+    def configure_args(self):
+        spec = self.spec
+        return [
+            '--disable-dependency-tracking',
+            '--without-x',
+            '--with-boost=%s' % spec['boost'].prefix
+        ]
diff --git a/var/spack/repos/builtin/packages/libgd/package.py b/var/spack/repos/builtin/packages/libgd/package.py
index 42eb23d85ab344cc6a908b9c8ffc86cfb6347d44..58867c85f8d3e95f150193dc2564e760eb472f75 100644
--- a/var/spack/repos/builtin/packages/libgd/package.py
+++ b/var/spack/repos/builtin/packages/libgd/package.py
@@ -38,8 +38,9 @@ class Libgd(AutotoolsPackage):
     """
 
     homepage = "https://github.com/libgd/libgd"
-    url      = "https://github.com/libgd/libgd/archive/gd-2.1.1.tar.gz"
+    url      = 'https://github.com/libgd/libgd/releases/download/gd-2.2.4/libgd-2.2.4.tar.gz'
 
+    version('2.2.4', '0a3c307b5075edbe1883543dd1153c02')
     version('2.2.3', 'a67bd15fa33d4aac0a1c7904aed19f49')
     version('2.1.1', 'e91a1a99903e460e7ba00a794e72cc1e')
 
@@ -54,16 +55,3 @@ class Libgd(AutotoolsPackage):
     depends_on('libpng')
     depends_on('libtiff')
     depends_on('fontconfig')
-
-    def autoreconf(self, spec, prefix):
-        autoreconf("--install", "--force",
-                   "-I", "m4",
-                   "-I", join_path(spec['gettext'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['pkg-config'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['automake'].prefix,
-                                   "share", "aclocal"),
-                   "-I", join_path(spec['libtool'].prefix,
-                                   "share", "aclocal")
-                   )
diff --git a/var/spack/repos/builtin/packages/libquo/package.py b/var/spack/repos/builtin/packages/libquo/package.py
index 3e574f700470f1b892234feb9cd911da8adffb6b..76a508f9c612a0c91830e37d72e9a51364dbf8c0 100644
--- a/var/spack/repos/builtin/packages/libquo/package.py
+++ b/var/spack/repos/builtin/packages/libquo/package.py
@@ -23,10 +23,9 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import os
 
 
-class Libquo(Package):
+class Libquo(AutotoolsPackage):
 
     """QUO (as in "status quo") is a runtime library that aids in accommodating
     thread-level heterogeneity in dynamic, phased MPI+X applications comprising
@@ -42,25 +41,8 @@ class Libquo(Package):
     depends_on('automake', type='build')
     depends_on('libtool', type='build')
 
-    def install(self, spec, prefix):
-        autoreconf_options = [
-            '--install',
-            '--verbose',
-            '--force',
-            '-I', 'config',
-            '-I', os.path.join(spec['automake'].prefix,
-                               'share', 'aclocal'),
-            '-I', os.path.join(spec['libtool'].prefix,
-                               'share', 'aclocal')
+    def configure_args(self):
+        return [
+            'CC={0}'.format(self.spec['mpi'].mpicc),
+            'FC={0}'.format(self.spec['mpi'].mpifc)
         ]
-        autoreconf(*autoreconf_options)
-
-        configure_options = [
-            '--prefix={0}'.format(prefix),
-            'CC=%s' % join_path(spec['mpi'].prefix.bin, "mpicc"),
-            'FC=%s' % join_path(spec['mpi'].prefix.bin, "mpif90")
-        ]
-        configure(*configure_options)
-
-        make()
-        make('install')
diff --git a/var/spack/repos/builtin/packages/libtool/package.py b/var/spack/repos/builtin/packages/libtool/package.py
index cd12503681403e4f8b03d6992d8a360d5b038d04..ae706089c9757fed6ebc36129ef29058d019826d 100644
--- a/var/spack/repos/builtin/packages/libtool/package.py
+++ b/var/spack/repos/builtin/packages/libtool/package.py
@@ -36,6 +36,8 @@ class Libtool(AutotoolsPackage):
 
     depends_on('m4@1.4.6:', type='build')
 
+    build_directory = 'spack-build'
+
     def _make_executable(self, name):
         return Executable(join_path(self.prefix.bin, name))
 
diff --git a/var/spack/repos/builtin/packages/libuv/package.py b/var/spack/repos/builtin/packages/libuv/package.py
index 5254239019055cc819d50d47b0202316344825a5..2f303280daf436e0f6cdf6aaa7682e1ad41ce2fa 100644
--- a/var/spack/repos/builtin/packages/libuv/package.py
+++ b/var/spack/repos/builtin/packages/libuv/package.py
@@ -37,5 +37,7 @@ class Libuv(AutotoolsPackage):
     depends_on('libtool', type='build')
 
     def autoreconf(self, spec, prefix):
+        # This is needed because autogen.sh generates on-the-fly
+        # an m4 macro needed during configuration
         bash = which("bash")
         bash('autogen.sh')
diff --git a/var/spack/repos/builtin/packages/m4/package.py b/var/spack/repos/builtin/packages/m4/package.py
index 415c55b21a5cf801d9f09f69337a3447708f96d1..a8b04239330994bb9a108bfe48333690963b9566 100644
--- a/var/spack/repos/builtin/packages/m4/package.py
+++ b/var/spack/repos/builtin/packages/m4/package.py
@@ -41,6 +41,8 @@ class M4(AutotoolsPackage):
 
     depends_on('libsigsegv', when='+sigsegv')
 
+    build_directory = 'spack-build'
+
     def configure_args(self):
         spec = self.spec
         args = ['--enable-c++']
diff --git a/var/spack/repos/builtin/packages/netcdf-cxx4/package.py b/var/spack/repos/builtin/packages/netcdf-cxx4/package.py
index 2da30c7b0c0b9353da57c8b9e4a3d2d077c342b2..36ab8766b927130fe0aa4953a1c37b9b59d635b9 100644
--- a/var/spack/repos/builtin/packages/netcdf-cxx4/package.py
+++ b/var/spack/repos/builtin/packages/netcdf-cxx4/package.py
@@ -34,8 +34,9 @@ class NetcdfCxx4(AutotoolsPackage):
     version('4.2.1', 'd019853802092cf686254aaba165fc81')
 
     depends_on('netcdf')
+
+    depends_on('automake', type='build')
     depends_on('autoconf', type='build')
+    depends_on('libtool', type='build')
 
-    def autoreconf(self, spec, prefix):
-        # Rebuild to prevent problems of inconsistency in git repo
-        which('autoreconf')('-ivf')
+    force_autoreconf = True
diff --git a/var/spack/repos/builtin/packages/plumed/package.py b/var/spack/repos/builtin/packages/plumed/package.py
index 60dfdf74055faac9e4e8d0f1ac69bc0e13b3b437..69949b0017d6470a182898bf425af23f50fd0b3e 100644
--- a/var/spack/repos/builtin/packages/plumed/package.py
+++ b/var/spack/repos/builtin/packages/plumed/package.py
@@ -27,7 +27,7 @@
 from spack import *
 
 
-class Plumed(Package):
+class Plumed(AutotoolsPackage):
     """PLUMED is an open source library for free energy calculations in
     molecular systems which works together with some of the most popular
     molecular dynamics engines.
@@ -67,6 +67,8 @@ class Plumed(Package):
     depends_on('gsl', when='+gsl')
 
     depends_on('autoconf', type='build')
+    depends_on('automake', type='build')
+    depends_on('libtool', type='build')
 
     # Dictionary mapping PLUMED versions to the patches it provides
     # interactively
@@ -84,6 +86,8 @@ class Plumed(Package):
         }
     }
 
+    force_autoreconf = True
+
     def apply_patch(self, other):
         plumed = subprocess.Popen(
             [join_path(self.spec.prefix.bin, 'plumed'), 'patch', '-p'],
@@ -99,12 +103,15 @@ def setup_dependent_package(self, module, ext_spec):
         # Make plumed visible from dependent packages
         module.plumed = Executable(join_path(self.spec.prefix.bin, 'plumed'))
 
-    def install(self, spec, prefix):
+    @run_before('autoreconf')
+    def filter_gslcblas(self):
         # This part is needed to avoid linking with gsl cblas
         # interface which will mask the cblas interface
         # provided by optimized libraries due to linking order
         filter_file('-lgslcblas', '', 'configure.ac')
-        autoreconf('-ivf')
+
+    def configure_args(self):
+        spec = self.spec
 
         # From plumed docs :
         # Also consider that this is different with respect to what some other
@@ -114,8 +121,7 @@ def install(self, spec, prefix):
         # with MPI you should use:
         #
         # > ./configure CXX="$MPICXX"
-        configure_opts = ['--prefix=' + prefix]
-
+        configure_opts = []
         # If using MPI then ensure the correct compiler wrapper is used.
         if '+mpi' in spec:
             configure_opts.extend([
@@ -153,6 +159,4 @@ def install(self, spec, prefix):
             configure_opts.extend([
                 '--enable-modules={0}'.format("".join(module_opts))])
 
-        configure(*configure_opts)
-        make()
-        make('install')
+        return configure_opts
diff --git a/var/spack/repos/builtin/packages/py-meep/package.py b/var/spack/repos/builtin/packages/py-meep/package.py
index 0ebba77ac628c0eaafac3c290d9bb67e0c517a64..64ca4e25d93caa8f57033e0310dc367df29120b0 100644
--- a/var/spack/repos/builtin/packages/py-meep/package.py
+++ b/var/spack/repos/builtin/packages/py-meep/package.py
@@ -51,8 +51,8 @@ class PyMeep(PythonPackage):
 
     phases = ['clean', 'build_ext', 'install', 'bdist']
 
-    def setup_file(self, spec, prefix):
-        return 'setup-mpi.py' if '+mpi' in spec else 'setup.py'
+    def setup_file(self):
+        return 'setup-mpi.py' if '+mpi' in self.spec else 'setup.py'
 
     def common_args(self, spec, prefix):
         include_dirs = [
diff --git a/var/spack/repos/builtin/packages/py-pypar/package.py b/var/spack/repos/builtin/packages/py-pypar/package.py
index f10b6d807f3f93c24e38b2f2c7545daab58aec0f..6ba999c063fa2792503e621f36956396511eacc6 100644
--- a/var/spack/repos/builtin/packages/py-pypar/package.py
+++ b/var/spack/repos/builtin/packages/py-pypar/package.py
@@ -37,8 +37,7 @@ class PyPypar(PythonPackage):
     depends_on('mpi')
     depends_on('py-numpy', type=('build', 'run'))
 
+    build_directory = 'source'
+
     def url_for_version(self, version):
         return "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/pypar/pypar-%s.tgz" % version
-
-    def build_directory(self):
-        return 'source'
diff --git a/var/spack/repos/builtin/packages/swiftsim/package.py b/var/spack/repos/builtin/packages/swiftsim/package.py
index 1c424b5ca0e975d31d8acaa19fc32f06727042c7..2ebdc1fdcbe78742817488c39ba36b5ff036da94 100644
--- a/var/spack/repos/builtin/packages/swiftsim/package.py
+++ b/var/spack/repos/builtin/packages/swiftsim/package.py
@@ -58,13 +58,6 @@ def setup_environment(self, spack_env, run_env):
         tty.warn('This is needed to clone SWIFT repository')
         spack_env.set('GIT_SSL_NO_VERIFY', 1)
 
-    def autoreconf(self, spec, prefix):
-        libtoolize()
-        aclocal()
-        autoconf()
-        autogen = Executable('./autogen.sh')
-        autogen()
-
     def configure_args(self):
         return ['--prefix=%s' % self.prefix,
                 '--enable-mpi' if '+mpi' in self.spec else '--disable-mpi',
diff --git a/var/spack/repos/builtin/packages/tcl/package.py b/var/spack/repos/builtin/packages/tcl/package.py
index 2ec8bb5236d015d67dd415ed055674364cb9456e..a9bc3cceaabfe381bc8106f5ac760210c6154d34 100644
--- a/var/spack/repos/builtin/packages/tcl/package.py
+++ b/var/spack/repos/builtin/packages/tcl/package.py
@@ -42,6 +42,8 @@ class Tcl(AutotoolsPackage):
 
     depends_on('zlib')
 
+    configure_directory = 'unix'
+
     def url_for_version(self, version):
         base_url = 'http://prdownloads.sourceforge.net/tcl'
         return '{0}/tcl{1}-src.tar.gz'.format(base_url, version)
@@ -52,9 +54,6 @@ def setup_environment(self, spack_env, env):
         env.set('TCL_LIBRARY', join_path(self.prefix.lib, 'tcl{0}'.format(
                 self.spec.version.up_to(2))))
 
-    def build_directory(self):
-        return 'unix'
-
     @run_after('install')
     def symlink_tclsh(self):
         with working_dir(self.prefix.bin):
diff --git a/var/spack/repos/builtin/packages/tk/package.py b/var/spack/repos/builtin/packages/tk/package.py
index 071db04e6352058e3a43122e7136155449e7fa22..66573eaa45117e6613b54dfb2f07549d67078927 100644
--- a/var/spack/repos/builtin/packages/tk/package.py
+++ b/var/spack/repos/builtin/packages/tk/package.py
@@ -42,6 +42,8 @@ class Tk(AutotoolsPackage):
     depends_on("tcl")
     depends_on("libx11", when='+X')
 
+    configure_directory = 'unix'
+
     def url_for_version(self, version):
         base_url = "http://prdownloads.sourceforge.net/tcl"
         return "{0}/tk{1}-src.tar.gz".format(base_url, version)
@@ -52,9 +54,6 @@ def setup_environment(self, spack_env, run_env):
         run_env.set('TK_LIBRARY', join_path(self.prefix.lib, 'tk{0}'.format(
             self.spec.version.up_to(2))))
 
-    def build_directory(self):
-        return 'unix'
-
     def configure_args(self):
         spec = self.spec
         return ['--with-tcl={0}'.format(spec['tcl'].prefix.lib)]