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.
|
||||
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::
|
||||
|
@ -165,6 +165,7 @@
|
||||
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 @@
|
||||
'run_after',
|
||||
'on_package_attributes',
|
||||
'Package',
|
||||
'CMakePackage',
|
||||
'AutotoolsPackage',
|
||||
'MakefilePackage',
|
||||
'AutotoolsPackage',
|
||||
'CMakePackage',
|
||||
'WafPackage',
|
||||
'PythonPackage',
|
||||
'RPackage',
|
||||
'PerlPackage'
|
||||
'PerlPackage',
|
||||
]
|
||||
|
||||
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'
|
||||
|
||||
build_system_to_phase = {
|
||||
CMakePackage: 'build',
|
||||
AutotoolsPackage: 'build',
|
||||
CMakePackage: 'build',
|
||||
WafPackage: 'build',
|
||||
PythonPackage: 'build',
|
||||
PerlPackage: 'build'
|
||||
PerlPackage: 'build',
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,9 +34,10 @@
|
||||
|
||||
|
||||
build_system_to_phase = {
|
||||
CMakePackage: 'cmake',
|
||||
AutotoolsPackage: 'configure',
|
||||
PerlPackage: 'configure'
|
||||
CMakePackage: 'cmake',
|
||||
WafPackage: 'configure',
|
||||
PerlPackage: 'configure',
|
||||
}
|
||||
|
||||
|
||||
|
@ -204,6 +204,16 @@ def install(self, spec, prefix):
|
||||
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 @@ def edit(self, spec, prefix):
|
||||
'autoreconf': AutoreconfPackageTemplate,
|
||||
'cmake': CMakePackageTemplate,
|
||||
'scons': SconsPackageTemplate,
|
||||
'waf': WafPackageTemplate,
|
||||
'bazel': BazelPackageTemplate,
|
||||
'python': PythonPackageTemplate,
|
||||
'r': RPackageTemplate,
|
||||
@ -354,7 +365,7 @@ def edit(self, spec, prefix):
|
||||
'perlbuild': PerlbuildPackageTemplate,
|
||||
'octave': OctavePackageTemplate,
|
||||
'makefile': MakefilePackageTemplate,
|
||||
'generic': PackageTemplate
|
||||
'generic': PackageTemplate,
|
||||
}
|
||||
|
||||
|
||||
@ -413,6 +424,7 @@ def __call__(self, stage, url):
|
||||
('/Makefile.am$', 'autoreconf'),
|
||||
('/CMakeLists.txt$', 'cmake'),
|
||||
('/SConstruct$', 'scons'),
|
||||
('/waf$', 'waf'),
|
||||
('/setup.py$', 'python'),
|
||||
('/NAMESPACE$', 'r'),
|
||||
('/WORKSPACE$', 'bazel'),
|
||||
|
@ -35,6 +35,7 @@
|
||||
('configure', 'autotools'),
|
||||
('CMakeLists.txt', 'cmake'),
|
||||
('SConstruct', 'scons'),
|
||||
('waf', 'waf'),
|
||||
('setup.py', 'python'),
|
||||
('NAMESPACE', 'r'),
|
||||
('WORKSPACE', 'bazel'),
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user