summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/__init__.py4
-rw-r--r--lib/spack/spack/build_systems/__init__.py0
-rw-r--r--lib/spack/spack/build_systems/autotools.py106
-rw-r--r--lib/spack/spack/build_systems/cmake.py143
-rw-r--r--lib/spack/spack/build_systems/editable_makefile.py77
-rw-r--r--lib/spack/spack/package.py155
6 files changed, 329 insertions, 156 deletions
diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index c7d592befb..918e17323b 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -196,7 +196,9 @@ __all__ = ['Package',
'alldeps',
'nolink']
from spack.package import Package, ExtensionConflictError
-from spack.package import CMakePackage, AutotoolsPackage, EditableMakefile
+from spack.build_systems.editable_makefile import EditableMakefile
+from spack.build_systems.autotools import AutotoolsPackage
+from spack.build_systems.cmake import CMakePackage
from spack.version import Version, ver
from spack.spec import DependencySpec, alldeps, nolink
from spack.multimethod import when
diff --git a/lib/spack/spack/build_systems/__init__.py b/lib/spack/spack/build_systems/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/spack/spack/build_systems/__init__.py
diff --git a/lib/spack/spack/build_systems/autotools.py b/lib/spack/spack/build_systems/autotools.py
new file mode 100644
index 0000000000..0bb5576708
--- /dev/null
+++ b/lib/spack/spack/build_systems/autotools.py
@@ -0,0 +1,106 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+import os.path
+
+import llnl.util.tty as tty
+from spack.package import PackageBase
+
+
+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
+
+ They all have sensible defaults and for many packages the only thing
+ necessary will be to override `configure_args`
+ """
+ phases = ['autoreconf', 'configure', 'build', 'install']
+ # To be used in UI queries that require to know which
+ # build-system class we are using
+ build_system_class = 'AutotoolsPackage'
+
+ def autoreconf(self, spec, prefix):
+ """Not needed usually, configure should be already there"""
+ pass
+
+ @PackageBase.sanity_check('autoreconf')
+ def is_configure_or_die(self):
+ """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()))
+
+ def configure_args(self):
+ """Method to be overridden. Should return an iterable containing
+ 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`
+ and an appropriately set prefix
+ """
+ options = ['--prefix={0}'.format(prefix)] + self.configure_args()
+ inspect.getmodule(self).configure(*options)
+
+ def build(self, spec, prefix):
+ """The usual `make` after configure"""
+ inspect.getmodule(self).make()
+
+ def install(self, spec, prefix):
+ """...and the final `make install` after configure"""
+ inspect.getmodule(self).make('install')
+
+ @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
+
+ It will search for a method named `check` and run it. A sensible
+ default is provided in the base class.
+ """
+ try:
+ fn = getattr(self, 'check')
+ tty.msg('Trying default sanity checks [check]')
+ fn()
+ except AttributeError:
+ 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`
+ and run them if found.
+ """
+ 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
new file mode 100644
index 0000000000..cb1076d7b7
--- /dev/null
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -0,0 +1,143 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+import os
+import platform
+
+import llnl.util.tty as tty
+import spack.build_environment
+from llnl.util.filesystem import working_dir, join_path
+from spack.package import PackageBase
+
+
+class CMakePackage(PackageBase):
+ """Specialized class for packages that are built using cmake
+
+ This class provides three phases that can be overridden:
+ - cmake
+ - build
+ - install
+
+ They all have sensible defaults and for many packages the only thing
+ necessary will be to override `cmake_args`
+ """
+ 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'
+
+ def build_type(self):
+ """Override to provide the correct build_type in case a complex
+ logic is needed
+ """
+ return 'RelWithDebInfo'
+
+ def root_cmakelists_dir(self):
+ """Directory where to find the root CMakeLists.txt"""
+ return self.stage.source_path
+
+ @property
+ def std_cmake_args(self):
+ """Standard cmake arguments provided as a property for
+ convenience of package writers
+ """
+ # standard CMake arguments
+ return CMakePackage._std_args(self)
+
+ @staticmethod
+ def _std_args(pkg):
+ """Computes the standard cmake arguments for a generic package"""
+ try:
+ build_type = pkg.build_type()
+ except AttributeError:
+ build_type = 'RelWithDebInfo'
+
+ args = ['-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix),
+ '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type),
+ '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON']
+ if platform.mac_ver()[0]:
+ args.append('-DCMAKE_FIND_FRAMEWORK:STRING=LAST')
+
+ # Set up CMake rpath
+ args.append('-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=FALSE')
+ rpaths = ':'.join(spack.build_environment.get_rpaths(pkg))
+ args.append('-DCMAKE_INSTALL_RPATH:STRING={0}'.format(rpaths))
+ return args
+
+ def build_directory(self):
+ """Override to provide another place to build the package"""
+ return join_path(self.stage.source_path, 'spack-build')
+
+ 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
+ """
+ return []
+
+ def cmake(self, spec, prefix):
+ """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):
+ inspect.getmodule(self).cmake(*options)
+
+ def build(self, spec, prefix):
+ """The usual `make` after cmake"""
+ with working_dir(self.build_directory()):
+ inspect.getmodule(self).make()
+
+ def install(self, spec, prefix):
+ """...and the final `make install` after cmake"""
+ with working_dir(self.build_directory()):
+ inspect.getmodule(self).make('install')
+
+ @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
+
+ It will search for a method named `check` and run it. A sensible
+ default is provided in the base class.
+ """
+ try:
+ fn = getattr(self, 'check')
+ tty.msg('Trying default build sanity checks [check]')
+ fn()
+ except AttributeError:
+ 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`
+ and run them if found.
+ """
+ with working_dir(self.build_directory()):
+ self._if_make_target_execute('test')
+
+ # Check that self.prefix is there after installation
+ PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
diff --git a/lib/spack/spack/build_systems/editable_makefile.py b/lib/spack/spack/build_systems/editable_makefile.py
new file mode 100644
index 0000000000..e3adea8363
--- /dev/null
+++ b/lib/spack/spack/build_systems/editable_makefile.py
@@ -0,0 +1,77 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+
+from llnl.util.filesystem import working_dir
+from spack.package import PackageBase
+
+
+class EditableMakefile(PackageBase):
+ """Specialized class for packages that are built using editable Makefiles
+
+ This class provides three phases that can be overridden:
+ - edit
+ - build
+ - install
+
+ It is necessary to override the 'edit' phase, while 'build' and 'install'
+ have sensible defaults.
+ """
+ phases = ['edit', 'build', 'install']
+ # To be used in UI queries that require to know which
+ # build-system class we are using
+ build_system_class = 'EditableMakefile'
+
+ def build_directory(self):
+ """Directory where the main Makefile is located"""
+ return self.stage.source_path
+
+ def build_args(self):
+ """List of arguments that should be passed to make at build time"""
+ return []
+
+ def install_args(self):
+ """List of arguments that should be passed to make at install time"""
+ return []
+
+ def edit(self, spec, prefix):
+ """This phase cannot be defaulted for obvious reasons..."""
+ raise NotImplementedError('\'edit\' function not implemented')
+
+ def build(self, spec, prefix):
+ """Default build phase : call make passing build_args"""
+ args = self.build_args()
+ with working_dir(self.build_directory()):
+ inspect.getmodule(self).make(*args)
+
+ def install(self, spec, prefix):
+ """Default install phase : call make passing install_args"""
+ args = self.install_args() + ['install']
+ with working_dir(self.build_directory()):
+ inspect.getmodule(self).make(*args)
+
+ # Check that self.prefix is there after installation
+ PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 9483f370dd..52dbd40f6f 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -38,7 +38,6 @@ import copy
import functools
import inspect
import os
-import platform
import re
import sys
import textwrap
@@ -48,7 +47,6 @@ from StringIO import StringIO
import llnl.util.lock
import llnl.util.tty as tty
import spack
-import spack.build_environment
import spack.compilers
import spack.directives
import spack.error
@@ -1698,159 +1696,6 @@ class Package(PackageBase):
PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-class EditableMakefile(PackageBase):
- phases = ['edit', 'build', 'install']
- # To be used in UI queries that require to know which
- # build-system class we are using
- build_system_class = 'EditableMakefile'
-
- def wdir(self):
- return self.stage.source_path
-
- def build_args(self):
- return []
-
- def install_args(self):
- return []
-
- def edit(self, spec, prefix):
- raise NotImplementedError('\'edit\' function not implemented')
-
- def build(self, spec, prefix):
- args = self.build_args()
- with working_dir(self.wdir()):
- inspect.getmodule(self).make(*args)
-
- def install(self, spec, prefix):
- args = self.install_args() + ['install']
- with working_dir(self.wdir()):
- inspect.getmodule(self).make(*args)
-
- PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-
-
-class AutotoolsPackage(PackageBase):
- phases = ['autoreconf', 'configure', 'build', 'install']
- # To be used in UI queries that require to know which
- # build-system class we are using
- build_system_class = 'AutotoolsPackage'
-
- def autoreconf(self, spec, prefix):
- """Not needed usually, configure should be already there"""
- pass
-
- @PackageBase.sanity_check('autoreconf')
- def is_configure_or_die(self):
- if not os.path.exists('configure'):
- raise RuntimeError(
- 'configure script not found in {0}'.format(os.getcwd()))
-
- def configure_args(self):
- return []
-
- def configure(self, spec, prefix):
- options = ['--prefix={0}'.format(prefix)] + self.configure_args()
- inspect.getmodule(self).configure(*options)
-
- def build(self, spec, prefix):
- inspect.getmodule(self).make()
-
- def install(self, spec, prefix):
- inspect.getmodule(self).make('install')
-
- @PackageBase.sanity_check('build')
- @PackageBase.on_package_attributes(run_tests=True)
- def _run_default_function(self):
- try:
- fn = getattr(self, 'check')
- tty.msg('Trying default sanity checks [check]')
- fn()
- except AttributeError:
- tty.msg('Skipping default sanity checks [method `check` not implemented]') # NOQA: ignore=E501
-
- def check(self):
- self._if_make_target_execute('test')
- self._if_make_target_execute('check')
-
- # This will be used as a registration decorator in user
- # packages, if need be
- PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-
-
-class CMakePackage(PackageBase):
- 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'
-
- def build_type(self):
- return 'RelWithDebInfo'
-
- def root_cmakelists_dir(self):
- return self.stage.source_path
-
- @property
- def std_cmake_args(self):
- # standard CMake arguments
- return CMakePackage._std_args(self)
-
- @staticmethod
- def _std_args(pkg):
- try:
- build_type = pkg.build_type()
- except AttributeError:
- build_type = 'RelWithDebInfo'
-
- args = ['-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix),
- '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type),
- '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON']
- if platform.mac_ver()[0]:
- args.append('-DCMAKE_FIND_FRAMEWORK:STRING=LAST')
-
- # Set up CMake rpath
- args.append('-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=FALSE')
- rpaths = ':'.join(spack.build_environment.get_rpaths(pkg))
- args.append('-DCMAKE_INSTALL_RPATH:STRING={0}'.format(rpaths))
- return args
-
- def build_directory(self):
- return join_path(self.stage.source_path, 'spack-build')
-
- def cmake_args(self):
- return []
-
- def cmake(self, spec, prefix):
- 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):
- inspect.getmodule(self).cmake(*options)
-
- def build(self, spec, prefix):
- with working_dir(self.build_directory()):
- inspect.getmodule(self).make()
-
- def install(self, spec, prefix):
- with working_dir(self.build_directory()):
- inspect.getmodule(self).make('install')
-
- @PackageBase.sanity_check('build')
- @PackageBase.on_package_attributes(run_tests=True)
- def _run_default_function(self):
- try:
- fn = getattr(self, 'check')
- tty.msg('Trying default build sanity checks [check]')
- fn()
- except AttributeError:
- tty.msg('Skipping default build sanity checks [method `check` not implemented]') # NOQA: ignore=E501
-
- def check(self):
- with working_dir(self.build_directory()):
- self._if_make_target_execute('test')
-
- PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-
-
def install_dependency_symlinks(pkg, spec, prefix):
"""Execute a dummy install and flatten dependencies"""
flatten_dependencies(spec, prefix)