From f480e3449eeb047e055af5bbfdf41eefd8de8d1a Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Sun, 15 Jan 2017 18:23:16 -0600 Subject: Added customization for make targets in 'build' and 'install' phases for CMakePackage (#2742) * Added customization for make targets in 'build' and 'install' phases for CMakePackage * Use rst in build system docs so that Sphinx generates nice API docs * Allow AutotoolsPackages to be built in a different directory * Flake8 * Fix missing import * Allow configure to be located in different directory * Update espressopp to use build targets * Flake8 * Sphinx fix, lists must be a new paragraph * Back out change that allowed a configure script in a different directory than build_directory * Add missing deps, build in parallel * Missing space for rst list --- lib/spack/spack/build_systems/autotools.py | 52 ++++++++++++++++++------------ lib/spack/spack/build_systems/cmake.py | 40 +++++++++++++---------- lib/spack/spack/build_systems/makefile.py | 11 ++++--- lib/spack/spack/build_systems/r.py | 1 + 4 files changed, 62 insertions(+), 42 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/build_systems/autotools.py b/lib/spack/spack/build_systems/autotools.py index dea4ae002f..78a4df5e11 100644 --- a/lib/spack/spack/build_systems/autotools.py +++ b/lib/spack/spack/build_systems/autotools.py @@ -31,6 +31,7 @@ from subprocess import PIPE from subprocess import check_call import llnl.util.tty as tty +from llnl.util.filesystem import working_dir from spack.package import PackageBase @@ -38,16 +39,17 @@ class AutotoolsPackage(PackageBase): """Specialized class for packages that are built using GNU Autotools This class provides four phases that can be overridden: - - autoreconf - - configure - - build - - install + + * autoreconf + * configure + * build + * install They all have sensible defaults and for many packages the only thing - necessary will be to override `configure_args` + necessary will be to override ``configure_args`` Additionally, you may specify make targets for build and install - phases by overriding `build_targets` and `install_targets` + phases by overriding ``build_targets`` and ``install_targets`` """ phases = ['autoreconf', 'configure', 'build', 'install'] # To be used in UI queries that require to know which @@ -124,6 +126,10 @@ class AutotoolsPackage(PackageBase): return False + def build_directory(self): + """Override to provide another place to build the package""" + return self.stage.source_path + def patch(self): """Perform any required patches.""" @@ -138,39 +144,44 @@ class AutotoolsPackage(PackageBase): @PackageBase.sanity_check('autoreconf') def is_configure_or_die(self): - """Checks the presence of a `configure` file after the + """Checks the presence of a ``configure`` file after the autoreconf phase""" - if not os.path.exists('configure'): - raise RuntimeError( - 'configure script not found in {0}'.format(os.getcwd())) + with working_dir(self.build_directory()): + if not os.path.exists('configure'): + raise RuntimeError( + 'configure script not found in {0}'.format(os.getcwd())) def configure_args(self): """Method to be overridden. Should return an iterable containing - all the arguments that must be passed to configure, except --prefix + all the arguments that must be passed to configure, except ``--prefix`` """ return [] def configure(self, spec, prefix): - """Runs configure with the arguments specified in `configure_args` + """Runs configure with the arguments specified in ``configure_args`` and an appropriately set prefix """ options = ['--prefix={0}'.format(prefix)] + self.configure_args() - inspect.getmodule(self).configure(*options) + + with working_dir(self.build_directory()): + inspect.getmodule(self).configure(*options) def build(self, spec, prefix): """Make the build targets""" - inspect.getmodule(self).make(*self.build_targets) + with working_dir(self.build_directory()): + inspect.getmodule(self).make(*self.build_targets) def install(self, spec, prefix): """Make the install targets""" - inspect.getmodule(self).make(*self.install_targets) + with working_dir(self.build_directory()): + inspect.getmodule(self).make(*self.install_targets) @PackageBase.sanity_check('build') @PackageBase.on_package_attributes(run_tests=True) def _run_default_function(self): - """This function is run after build if self.run_tests == True + """This function is run after build if ``self.run_tests == True`` - It will search for a method named `check` and run it. A sensible + It will search for a method named ``check`` and run it. A sensible default is provided in the base class. """ try: @@ -181,11 +192,12 @@ class AutotoolsPackage(PackageBase): tty.msg('Skipping default sanity checks [method `check` not implemented]') # NOQA: ignore=E501 def check(self): - """Default test : search the Makefile for targets `test` and `check` + """Default test: search the Makefile for targets ``test`` and ``check`` and run them if found. """ - self._if_make_target_execute('test') - self._if_make_target_execute('check') + with working_dir(self.build_directory()): + self._if_make_target_execute('test') + self._if_make_target_execute('check') # Check that self.prefix is there after installation PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix) diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py index e097f7e44f..61d45784e8 100644 --- a/lib/spack/spack/build_systems/cmake.py +++ b/lib/spack/spack/build_systems/cmake.py @@ -24,7 +24,6 @@ ############################################################################## import inspect -import os import platform import llnl.util.tty as tty @@ -35,21 +34,28 @@ from spack.package import PackageBase class CMakePackage(PackageBase): - """Specialized class for packages that are built using cmake + """Specialized class for packages that are built using CMake This class provides three phases that can be overridden: - - cmake - - build - - install + + * cmake + * build + * install They all have sensible defaults and for many packages the only thing - necessary will be to override `cmake_args` + necessary will be to override ``cmake_args`` + + Additionally, you may specify make targets for build and install + phases by overriding ``build_targets`` and ``install_targets`` """ phases = ['cmake', 'build', 'install'] # To be used in UI queries that require to know which # build-system class we are using build_system_class = 'CMakePackage' + build_targets = [] + install_targets = ['install'] + depends_on('cmake', type='build') def build_type(self): @@ -97,8 +103,9 @@ class CMakePackage(PackageBase): def cmake_args(self): """Method to be overridden. Should return an iterable containing all the arguments that must be passed to configure, except: - - CMAKE_INSTALL_PREFIX - - CMAKE_BUILD_TYPE + + * CMAKE_INSTALL_PREFIX + * CMAKE_BUILD_TYPE """ return [] @@ -106,26 +113,25 @@ class CMakePackage(PackageBase): """Run cmake in the build directory""" options = [self.root_cmakelists_dir()] + self.std_cmake_args + \ self.cmake_args() - create = not os.path.exists(self.build_directory()) - with working_dir(self.build_directory(), create=create): + with working_dir(self.build_directory(), create=True): inspect.getmodule(self).cmake(*options) def build(self, spec, prefix): - """The usual `make` after cmake""" + """Make the build targets""" with working_dir(self.build_directory()): - inspect.getmodule(self).make() + inspect.getmodule(self).make(*self.build_targets) def install(self, spec, prefix): - """...and the final `make install` after cmake""" + """Make the install targets""" with working_dir(self.build_directory()): - inspect.getmodule(self).make('install') + inspect.getmodule(self).make(*self.install_targets) @PackageBase.sanity_check('build') @PackageBase.on_package_attributes(run_tests=True) def _run_default_function(self): - """This function is run after build if self.run_tests == True + """This function is run after build if ``self.run_tests == True`` - It will search for a method named `check` and run it. A sensible + It will search for a method named ``check`` and run it. A sensible default is provided in the base class. """ try: @@ -136,7 +142,7 @@ class CMakePackage(PackageBase): tty.msg('Skipping default build sanity checks [method `check` not implemented]') # NOQA: ignore=E501 def check(self): - """Default test : search the Makefile for the target `test` + """Default test: search the Makefile for the target ``test`` and run them if found. """ with working_dir(self.build_directory()): diff --git a/lib/spack/spack/build_systems/makefile.py b/lib/spack/spack/build_systems/makefile.py index fcc7ed2c99..a56f316109 100644 --- a/lib/spack/spack/build_systems/makefile.py +++ b/lib/spack/spack/build_systems/makefile.py @@ -34,9 +34,10 @@ class MakefilePackage(PackageBase): """Specialized class for packages that are built using editable Makefiles This class provides three phases that can be overridden: - - edit - - build - - install + + * edit + * build + * install It is necessary to override the 'edit' phase, while 'build' and 'install' have sensible defaults. @@ -58,12 +59,12 @@ class MakefilePackage(PackageBase): tty.msg('Using default implementation: skipping edit phase.') def build(self, spec, prefix): - """Default build phase : call make passing build_args""" + """Make the build targets""" with working_dir(self.build_directory()): inspect.getmodule(self).make(*self.build_targets) def install(self, spec, prefix): - """Default install phase : call make passing install_args""" + """Make the install targets""" with working_dir(self.build_directory()): inspect.getmodule(self).make(*self.install_targets) diff --git a/lib/spack/spack/build_systems/r.py b/lib/spack/spack/build_systems/r.py index 52b3d82c60..f642f2dfd8 100644 --- a/lib/spack/spack/build_systems/r.py +++ b/lib/spack/spack/build_systems/r.py @@ -33,6 +33,7 @@ class RPackage(PackageBase): """Specialized class for packages that are built using R This class provides a single phase that can be overridden: + * install It has sensible defaults and for many packages the only thing -- cgit v1.2.3-60-g2f50