Add a WafPackage base class (#3975)
* Add a WafPackage base class * Correct comment in docstring * Be more specific about the Python versions supported
This commit is contained in:
parent
b3ce04cba3
commit
2511520b32
@ -2085,33 +2085,34 @@ The package base class, usually specialized for a given build system, determines
|
|||||||
actual set of entities available for overriding.
|
actual set of entities available for overriding.
|
||||||
The classes that are currently provided by Spack are:
|
The classes that are currently provided by Spack are:
|
||||||
|
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| | **Base class purpose** |
|
| **Base Class** | **Purpose** |
|
||||||
+====================================+==================================+
|
+===============================+==================================+
|
||||||
| :py:class:`.Package` | General base class not |
|
| :py:class:`.Package` | General base class not |
|
||||||
| | specialized for any build system |
|
| | specialized for any build system |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| :py:class:`.MakefilePackage` | Specialized class for packages |
|
| :py:class:`.MakefilePackage` | Specialized class for packages |
|
||||||
| | built invoking |
|
| | built invoking |
|
||||||
| | hand-written Makefiles |
|
| | hand-written Makefiles |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| :py:class:`.AutotoolsPackage` | Specialized class for packages |
|
| :py:class:`.AutotoolsPackage` | Specialized class for packages |
|
||||||
| | built using GNU Autotools |
|
| | built using GNU Autotools |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| :py:class:`.CMakePackage` | Specialized class for packages |
|
| :py:class:`.CMakePackage` | Specialized class for packages |
|
||||||
| | built using CMake |
|
| | built using CMake |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| :py:class:`.RPackage` | Specialized class for |
|
| :py:class:`.WafPackage` | Specialize class for packages |
|
||||||
| | :py:class:`.R` extensions |
|
| | built using Waf |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| :py:class:`.PythonPackage` | Specialized class for |
|
| :py:class:`.RPackage` | Specialized class for |
|
||||||
| | :py:class:`.Python` extensions |
|
| | :py:class:`.R` extensions |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
| :py:class:`.PerlPackage` | Specialized class for |
|
| :py:class:`.PythonPackage` | Specialized class for |
|
||||||
| | :py:class:`.Perl` extensions |
|
| | :py:class:`.Python` extensions |
|
||||||
+------------------------------------+----------------------------------+
|
+-------------------------------+----------------------------------+
|
||||||
|
| :py:class:`.PerlPackage` | Specialized class for |
|
||||||
|
| | :py:class:`.Perl` extensions |
|
||||||
|
+-------------------------------+----------------------------------+
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -165,6 +165,7 @@
|
|||||||
from spack.build_systems.makefile import MakefilePackage
|
from spack.build_systems.makefile import MakefilePackage
|
||||||
from spack.build_systems.autotools import AutotoolsPackage
|
from spack.build_systems.autotools import AutotoolsPackage
|
||||||
from spack.build_systems.cmake import CMakePackage
|
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.python import PythonPackage
|
||||||
from spack.build_systems.r import RPackage
|
from spack.build_systems.r import RPackage
|
||||||
from spack.build_systems.perl import PerlPackage
|
from spack.build_systems.perl import PerlPackage
|
||||||
@ -174,12 +175,13 @@
|
|||||||
'run_after',
|
'run_after',
|
||||||
'on_package_attributes',
|
'on_package_attributes',
|
||||||
'Package',
|
'Package',
|
||||||
'CMakePackage',
|
|
||||||
'AutotoolsPackage',
|
|
||||||
'MakefilePackage',
|
'MakefilePackage',
|
||||||
|
'AutotoolsPackage',
|
||||||
|
'CMakePackage',
|
||||||
|
'WafPackage',
|
||||||
'PythonPackage',
|
'PythonPackage',
|
||||||
'RPackage',
|
'RPackage',
|
||||||
'PerlPackage'
|
'PerlPackage',
|
||||||
]
|
]
|
||||||
|
|
||||||
from spack.version import Version, ver
|
from spack.version import Version, ver
|
||||||
|
148
lib/spack/spack/build_systems/waf.py
Normal file
148
lib/spack/spack/build_systems/waf.py
Normal file
@ -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)
|
@ -29,10 +29,11 @@
|
|||||||
description = 'stops at build stage when installing a package, if possible'
|
description = 'stops at build stage when installing a package, if possible'
|
||||||
|
|
||||||
build_system_to_phase = {
|
build_system_to_phase = {
|
||||||
CMakePackage: 'build',
|
|
||||||
AutotoolsPackage: 'build',
|
AutotoolsPackage: 'build',
|
||||||
|
CMakePackage: 'build',
|
||||||
|
WafPackage: 'build',
|
||||||
PythonPackage: 'build',
|
PythonPackage: 'build',
|
||||||
PerlPackage: 'build'
|
PerlPackage: 'build',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,9 +34,10 @@
|
|||||||
|
|
||||||
|
|
||||||
build_system_to_phase = {
|
build_system_to_phase = {
|
||||||
CMakePackage: 'cmake',
|
|
||||||
AutotoolsPackage: 'configure',
|
AutotoolsPackage: 'configure',
|
||||||
PerlPackage: 'configure'
|
CMakePackage: 'cmake',
|
||||||
|
WafPackage: 'configure',
|
||||||
|
PerlPackage: 'configure',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,6 +204,16 @@ def install(self, spec, prefix):
|
|||||||
scons('install')"""
|
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):
|
class BazelPackageTemplate(PackageTemplate):
|
||||||
"""Provides appropriate overrides for Bazel-based packages"""
|
"""Provides appropriate overrides for Bazel-based packages"""
|
||||||
|
|
||||||
@ -347,6 +357,7 @@ def edit(self, spec, prefix):
|
|||||||
'autoreconf': AutoreconfPackageTemplate,
|
'autoreconf': AutoreconfPackageTemplate,
|
||||||
'cmake': CMakePackageTemplate,
|
'cmake': CMakePackageTemplate,
|
||||||
'scons': SconsPackageTemplate,
|
'scons': SconsPackageTemplate,
|
||||||
|
'waf': WafPackageTemplate,
|
||||||
'bazel': BazelPackageTemplate,
|
'bazel': BazelPackageTemplate,
|
||||||
'python': PythonPackageTemplate,
|
'python': PythonPackageTemplate,
|
||||||
'r': RPackageTemplate,
|
'r': RPackageTemplate,
|
||||||
@ -354,7 +365,7 @@ def edit(self, spec, prefix):
|
|||||||
'perlbuild': PerlbuildPackageTemplate,
|
'perlbuild': PerlbuildPackageTemplate,
|
||||||
'octave': OctavePackageTemplate,
|
'octave': OctavePackageTemplate,
|
||||||
'makefile': MakefilePackageTemplate,
|
'makefile': MakefilePackageTemplate,
|
||||||
'generic': PackageTemplate
|
'generic': PackageTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -413,6 +424,7 @@ def __call__(self, stage, url):
|
|||||||
('/Makefile.am$', 'autoreconf'),
|
('/Makefile.am$', 'autoreconf'),
|
||||||
('/CMakeLists.txt$', 'cmake'),
|
('/CMakeLists.txt$', 'cmake'),
|
||||||
('/SConstruct$', 'scons'),
|
('/SConstruct$', 'scons'),
|
||||||
|
('/waf$', 'waf'),
|
||||||
('/setup.py$', 'python'),
|
('/setup.py$', 'python'),
|
||||||
('/NAMESPACE$', 'r'),
|
('/NAMESPACE$', 'r'),
|
||||||
('/WORKSPACE$', 'bazel'),
|
('/WORKSPACE$', 'bazel'),
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
('configure', 'autotools'),
|
('configure', 'autotools'),
|
||||||
('CMakeLists.txt', 'cmake'),
|
('CMakeLists.txt', 'cmake'),
|
||||||
('SConstruct', 'scons'),
|
('SConstruct', 'scons'),
|
||||||
|
('waf', 'waf'),
|
||||||
('setup.py', 'python'),
|
('setup.py', 'python'),
|
||||||
('NAMESPACE', 'r'),
|
('NAMESPACE', 'r'),
|
||||||
('WORKSPACE', 'bazel'),
|
('WORKSPACE', 'bazel'),
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
from spack import *
|
from spack import *
|
||||||
|
|
||||||
|
|
||||||
class PyPy2cairo(Package):
|
class PyPy2cairo(WafPackage):
|
||||||
"""Pycairo is a set of Python bindings for the cairo graphics library."""
|
"""Pycairo is a set of Python bindings for the cairo graphics library."""
|
||||||
|
|
||||||
homepage = "https://www.cairographics.org/pycairo/"
|
homepage = "https://www.cairographics.org/pycairo/"
|
||||||
@ -35,10 +35,15 @@ class PyPy2cairo(Package):
|
|||||||
|
|
||||||
extends('python')
|
extends('python')
|
||||||
|
|
||||||
depends_on('cairo')
|
depends_on('python', type=('build', 'run'))
|
||||||
|
depends_on('cairo@1.10.0:')
|
||||||
depends_on('pixman')
|
depends_on('pixman')
|
||||||
|
depends_on('pkg-config', type='build')
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
# TODO: Add a 'test' deptype
|
||||||
python('waf', 'configure', '--prefix={0}'.format(prefix))
|
# depends_on('py-pytest', type='test')
|
||||||
python('waf', 'build')
|
|
||||||
python('waf', 'install')
|
def installtest(self):
|
||||||
|
with working_dir('test'):
|
||||||
|
pytest = which('py.test')
|
||||||
|
pytest()
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
from spack import *
|
from spack import *
|
||||||
|
|
||||||
|
|
||||||
class Tut(Package):
|
class Tut(WafPackage):
|
||||||
"""TUT is a small and portable unit test framework for C++."""
|
"""TUT is a small and portable unit test framework for C++."""
|
||||||
|
|
||||||
homepage = "http://mrzechonek.github.io/tut-framework/"
|
homepage = "http://mrzechonek.github.io/tut-framework/"
|
||||||
@ -33,9 +33,11 @@ class Tut(Package):
|
|||||||
|
|
||||||
version('2016-12-19', '8b1967fa295ae1ce4d4431c2f811e521')
|
version('2016-12-19', '8b1967fa295ae1ce4d4431c2f811e521')
|
||||||
|
|
||||||
extends('python')
|
def build_args(self, spec, prefix):
|
||||||
|
args = []
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
if self.run_tests:
|
||||||
python('waf', 'configure', '--prefix={0}'.format(prefix))
|
# Run unit tests
|
||||||
python('waf', 'build')
|
args.append('--test')
|
||||||
python('waf', 'install')
|
|
||||||
|
return args
|
||||||
|
Loading…
Reference in New Issue
Block a user