summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/docs/packaging_guide.rst55
-rw-r--r--lib/spack/spack/__init__.py8
-rw-r--r--lib/spack/spack/build_systems/waf.py148
-rw-r--r--lib/spack/spack/cmd/build.py5
-rw-r--r--lib/spack/spack/cmd/configure.py5
-rw-r--r--lib/spack/spack/cmd/create.py14
-rw-r--r--lib/spack/spack/test/build_system_guess.py1
-rw-r--r--var/spack/repos/builtin/packages/py-py2cairo/package.py17
-rw-r--r--var/spack/repos/builtin/packages/tut/package.py14
9 files changed, 220 insertions, 47 deletions
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index 6f4a3ecf1a..bf6f3f3cf9 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -2085,33 +2085,34 @@ The package base class, usually specialized for a given build system, determines
actual set of entities available for overriding.
The classes that are currently provided by Spack are:
- +------------------------------------+----------------------------------+
- | | **Base class purpose** |
- +====================================+==================================+
- | :py:class:`.Package` | General base class not |
- | | specialized for any build system |
- +------------------------------------+----------------------------------+
- | :py:class:`.MakefilePackage` | Specialized class for packages |
- | | built invoking |
- | | hand-written Makefiles |
- +------------------------------------+----------------------------------+
- | :py:class:`.AutotoolsPackage` | Specialized class for packages |
- | | built using GNU Autotools |
- +------------------------------------+----------------------------------+
- | :py:class:`.CMakePackage` | Specialized class for packages |
- | | built using CMake |
- +------------------------------------+----------------------------------+
- | :py:class:`.RPackage` | Specialized class for |
- | | :py:class:`.R` extensions |
- +------------------------------------+----------------------------------+
- | :py:class:`.PythonPackage` | Specialized class for |
- | | :py:class:`.Python` extensions |
- +------------------------------------+----------------------------------+
- | :py:class:`.PerlPackage` | Specialized class for |
- | | :py:class:`.Perl` extensions |
- +------------------------------------+----------------------------------+
-
-
+ +-------------------------------+----------------------------------+
+ | **Base Class** | **Purpose** |
+ +===============================+==================================+
+ | :py:class:`.Package` | General base class not |
+ | | specialized for any build system |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.MakefilePackage` | Specialized class for packages |
+ | | built invoking |
+ | | hand-written Makefiles |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.AutotoolsPackage` | Specialized class for packages |
+ | | built using GNU Autotools |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.CMakePackage` | Specialized class for packages |
+ | | built using CMake |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.WafPackage` | Specialize class for packages |
+ | | built using Waf |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.RPackage` | Specialized class for |
+ | | :py:class:`.R` extensions |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.PythonPackage` | Specialized class for |
+ | | :py:class:`.Python` extensions |
+ +-------------------------------+----------------------------------+
+ | :py:class:`.PerlPackage` | Specialized class for |
+ | | :py:class:`.Perl` extensions |
+ +-------------------------------+----------------------------------+
.. note::
diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index 85d881a769..73963b848c 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -165,6 +165,7 @@ from spack.package import Package, run_before, run_after, on_package_attributes
from spack.build_systems.makefile import MakefilePackage
from spack.build_systems.autotools import AutotoolsPackage
from spack.build_systems.cmake import CMakePackage
+from spack.build_systems.waf import WafPackage
from spack.build_systems.python import PythonPackage
from spack.build_systems.r import RPackage
from spack.build_systems.perl import PerlPackage
@@ -174,12 +175,13 @@ __all__ += [
'run_after',
'on_package_attributes',
'Package',
- 'CMakePackage',
- 'AutotoolsPackage',
'MakefilePackage',
+ 'AutotoolsPackage',
+ 'CMakePackage',
+ 'WafPackage',
'PythonPackage',
'RPackage',
- 'PerlPackage'
+ 'PerlPackage',
]
from spack.version import Version, ver
diff --git a/lib/spack/spack/build_systems/waf.py b/lib/spack/spack/build_systems/waf.py
new file mode 100644
index 0000000000..bb4fa6c369
--- /dev/null
+++ b/lib/spack/spack/build_systems/waf.py
@@ -0,0 +1,148 @@
+##############################################################################
+# 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 spack.directives import depends_on
+from spack.package import PackageBase, run_after
+
+from llnl.util.filesystem import working_dir
+
+
+class WafPackage(PackageBase):
+ """Specialized class for packages that are built using the
+ Waf build system. See https://waf.io/book/ for more information.
+
+ This class provides the following phases that can be overridden:
+
+ * configure
+ * build
+ * install
+
+ These are all standard Waf commands and can be found by running:
+
+ .. code-block:: console
+
+ $ python waf --help
+
+ Each phase provides a function <phase> that runs:
+
+ .. code-block:: console
+
+ $ python waf -j<jobs> <phase>
+
+ where <jobs> is the number of parallel jobs to build with. Each phase
+ also has a <phase_args> function that can pass arguments to this call.
+ All of these functions are empty except for the ``configure_args``
+ function, which passes ``--prefix=/path/to/installation/prefix``.
+ """
+ # Default phases
+ phases = ['configure', 'build', 'install']
+
+ # To be used in UI queries that require to know which
+ # build-system class we are using
+ build_system_class = 'WafPackage'
+
+ # Callback names for build-time test
+ build_time_test_callbacks = ['test']
+
+ # Callback names for install-time test
+ install_time_test_callbacks = ['installtest']
+
+ # Much like AutotoolsPackage does not require automake and autoconf
+ # to build, WafPackage does not require waf to build. It only requires
+ # python to run the waf build script.
+ depends_on('python@2.5:', type='build')
+
+ @property
+ def build_directory(self):
+ """The directory containing the ``waf`` file."""
+ return self.stage.source_path
+
+ def python(self, *args, **kwargs):
+ """The python ``Executable``."""
+ inspect.getmodule(self).python(*args, **kwargs)
+
+ def waf(self, *args, **kwargs):
+ """Runs the waf ``Executable``."""
+ jobs = inspect.getmodule(self).make_jobs
+
+ with working_dir(self.build_directory):
+ self.python('waf', '-j{0}'.format(jobs), *args, **kwargs)
+
+ def configure(self, spec, prefix):
+ """Configures the project."""
+ args = self.configure_args(spec, prefix)
+
+ self.waf('configure', *args)
+
+ def configure_args(self, spec, prefix):
+ """Arguments to pass to configure."""
+ return ['--prefix={0}'.format(prefix)]
+
+ def build(self, spec, prefix):
+ """Executes the build."""
+ args = self.build_args(spec, prefix)
+
+ self.waf('build', *args)
+
+ def build_args(self, spec, prefix):
+ """Arguments to pass to build."""
+ return []
+
+ def install(self, spec, prefix):
+ """Installs the targets on the system."""
+ args = self.install_args(spec, prefix)
+
+ self.waf('install', *args)
+
+ def install_args(self, spec, prefix):
+ """Arguments to pass to install."""
+ return []
+
+ # Testing
+
+ def test(self):
+ """Run unit tests after build.
+
+ By default, does nothing. Override this if you want to
+ add package-specific tests.
+ """
+ pass
+
+ run_after('build')(PackageBase._run_default_build_time_test_callbacks)
+
+ def installtest(self):
+ """Run unit tests after install.
+
+ By default, does nothing. Override this if you want to
+ add package-specific tests.
+ """
+ pass
+
+ run_after('install')(PackageBase._run_default_install_time_test_callbacks)
+
+ # Check that self.prefix is there after installation
+ run_after('install')(PackageBase.sanity_check_prefix)
diff --git a/lib/spack/spack/cmd/build.py b/lib/spack/spack/cmd/build.py
index 90157a85af..877f2ce0cf 100644
--- a/lib/spack/spack/cmd/build.py
+++ b/lib/spack/spack/cmd/build.py
@@ -29,10 +29,11 @@ from spack import *
description = 'stops at build stage when installing a package, if possible'
build_system_to_phase = {
- CMakePackage: 'build',
AutotoolsPackage: 'build',
+ CMakePackage: 'build',
+ WafPackage: 'build',
PythonPackage: 'build',
- PerlPackage: 'build'
+ PerlPackage: 'build',
}
diff --git a/lib/spack/spack/cmd/configure.py b/lib/spack/spack/cmd/configure.py
index 037705f480..7f6c07c34b 100644
--- a/lib/spack/spack/cmd/configure.py
+++ b/lib/spack/spack/cmd/configure.py
@@ -34,9 +34,10 @@ description = 'stops at configuration stage when installing a package, if possib
build_system_to_phase = {
- CMakePackage: 'cmake',
AutotoolsPackage: 'configure',
- PerlPackage: 'configure'
+ CMakePackage: 'cmake',
+ WafPackage: 'configure',
+ PerlPackage: 'configure',
}
diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py
index 504ac9d844..adaf388387 100644
--- a/lib/spack/spack/cmd/create.py
+++ b/lib/spack/spack/cmd/create.py
@@ -204,6 +204,16 @@ class SconsPackageTemplate(PackageTemplate):
scons('install')"""
+class WafPackageTemplate(PackageTemplate):
+ """Provides appropriate override for Waf-based packages"""
+
+ base_class_name = 'WafPackage'
+
+ body = """\
+ # FIXME: Override configure_args(), build_args(),
+ # or install_args() if necessary."""
+
+
class BazelPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for Bazel-based packages"""
@@ -347,6 +357,7 @@ templates = {
'autoreconf': AutoreconfPackageTemplate,
'cmake': CMakePackageTemplate,
'scons': SconsPackageTemplate,
+ 'waf': WafPackageTemplate,
'bazel': BazelPackageTemplate,
'python': PythonPackageTemplate,
'r': RPackageTemplate,
@@ -354,7 +365,7 @@ templates = {
'perlbuild': PerlbuildPackageTemplate,
'octave': OctavePackageTemplate,
'makefile': MakefilePackageTemplate,
- 'generic': PackageTemplate
+ 'generic': PackageTemplate,
}
@@ -413,6 +424,7 @@ class BuildSystemGuesser:
('/Makefile.am$', 'autoreconf'),
('/CMakeLists.txt$', 'cmake'),
('/SConstruct$', 'scons'),
+ ('/waf$', 'waf'),
('/setup.py$', 'python'),
('/NAMESPACE$', 'r'),
('/WORKSPACE$', 'bazel'),
diff --git a/lib/spack/spack/test/build_system_guess.py b/lib/spack/spack/test/build_system_guess.py
index 9ea76e7bfc..73b619cb22 100644
--- a/lib/spack/spack/test/build_system_guess.py
+++ b/lib/spack/spack/test/build_system_guess.py
@@ -35,6 +35,7 @@ import spack.stage
('configure', 'autotools'),
('CMakeLists.txt', 'cmake'),
('SConstruct', 'scons'),
+ ('waf', 'waf'),
('setup.py', 'python'),
('NAMESPACE', 'r'),
('WORKSPACE', 'bazel'),
diff --git a/var/spack/repos/builtin/packages/py-py2cairo/package.py b/var/spack/repos/builtin/packages/py-py2cairo/package.py
index 5626784e34..2eacf540c9 100644
--- a/var/spack/repos/builtin/packages/py-py2cairo/package.py
+++ b/var/spack/repos/builtin/packages/py-py2cairo/package.py
@@ -25,7 +25,7 @@
from spack import *
-class PyPy2cairo(Package):
+class PyPy2cairo(WafPackage):
"""Pycairo is a set of Python bindings for the cairo graphics library."""
homepage = "https://www.cairographics.org/pycairo/"
@@ -35,10 +35,15 @@ class PyPy2cairo(Package):
extends('python')
- depends_on('cairo')
+ depends_on('python', type=('build', 'run'))
+ depends_on('cairo@1.10.0:')
depends_on('pixman')
+ depends_on('pkg-config', type='build')
- def install(self, spec, prefix):
- python('waf', 'configure', '--prefix={0}'.format(prefix))
- python('waf', 'build')
- python('waf', 'install')
+ # TODO: Add a 'test' deptype
+ # depends_on('py-pytest', type='test')
+
+ def installtest(self):
+ with working_dir('test'):
+ pytest = which('py.test')
+ pytest()
diff --git a/var/spack/repos/builtin/packages/tut/package.py b/var/spack/repos/builtin/packages/tut/package.py
index 9b135e0964..6c6c6bdb27 100644
--- a/var/spack/repos/builtin/packages/tut/package.py
+++ b/var/spack/repos/builtin/packages/tut/package.py
@@ -25,7 +25,7 @@
from spack import *
-class Tut(Package):
+class Tut(WafPackage):
"""TUT is a small and portable unit test framework for C++."""
homepage = "http://mrzechonek.github.io/tut-framework/"
@@ -33,9 +33,11 @@ class Tut(Package):
version('2016-12-19', '8b1967fa295ae1ce4d4431c2f811e521')
- extends('python')
+ def build_args(self, spec, prefix):
+ args = []
- def install(self, spec, prefix):
- python('waf', 'configure', '--prefix={0}'.format(prefix))
- python('waf', 'build')
- python('waf', 'install')
+ if self.run_tests:
+ # Run unit tests
+ args.append('--test')
+
+ return args