Branch with the meson build-system (#8467)
* Branch with the meson build-system * Fix build_environment for dual loads and add create code * Add documentation * Fixed option list * Update build_system_guess for meson * Fixed documentation errors * Added meson to build and configure and updated documentation * fix typos
This commit is contained in:
parent
2a94d59433
commit
b1182741d4
@ -33,6 +33,7 @@ on these ideas for each distinct build system that Spack supports:
|
|||||||
|
|
||||||
build_systems/autotoolspackage
|
build_systems/autotoolspackage
|
||||||
build_systems/cmakepackage
|
build_systems/cmakepackage
|
||||||
|
build_systems/mesonpackage
|
||||||
build_systems/qmakepackage
|
build_systems/qmakepackage
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
85
lib/spack/docs/build_systems/mesonpackage.rst
Normal file
85
lib/spack/docs/build_systems/mesonpackage.rst
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
.. _mesonpackage:
|
||||||
|
|
||||||
|
------------
|
||||||
|
MesonPackage
|
||||||
|
------------
|
||||||
|
|
||||||
|
Much like Autotools and CMake, Meson is a build system. But it is
|
||||||
|
meant to be both fast and as user friendly as possible. GNOME's goal
|
||||||
|
is to port modules to use the Meson build system.
|
||||||
|
|
||||||
|
^^^^^^
|
||||||
|
Phases
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
The ``MesonPackage`` base class comes with the following phases:
|
||||||
|
|
||||||
|
#. ``meson`` - generate ninja files
|
||||||
|
#. ``build`` - build the project
|
||||||
|
#. ``install`` - install the project
|
||||||
|
|
||||||
|
By default, these phases run:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ mkdir spack-build
|
||||||
|
$ cd spack-build
|
||||||
|
$ meson .. --prefix=/path/to/installation/prefix
|
||||||
|
$ ninja
|
||||||
|
$ ninja test # optional
|
||||||
|
$ ninja install
|
||||||
|
|
||||||
|
|
||||||
|
Any of these phases can be overridden in your package as necessary.
|
||||||
|
There is also a ``check`` method that looks for a ``test`` target
|
||||||
|
in the build file. If a ``test`` target exists and the user runs:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ spack install --test=root <meson-package>
|
||||||
|
|
||||||
|
|
||||||
|
Spack will run ``ninja test`` after the build phase.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
Important files
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Packages that use the Meson build system can be identified by the
|
||||||
|
presence of a ``meson.build`` file. This file declares things
|
||||||
|
like build instructions and dependencies.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Build system dependencies
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
At the bare minimum, packages that use the Meson build system need
|
||||||
|
``meson`` and ```ninja``` dependencies. Since this is always the case,
|
||||||
|
the ``MesonPackage`` base class already contains:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
depends_on('meson', type='build')
|
||||||
|
depends_on('ninja', type='build')
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Passing arguments to meson
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If you need to pass any arguments to the ``meson`` call, you can
|
||||||
|
override the ``meson_args`` method like so:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def meson_args(self):
|
||||||
|
return ['--default-library=both']
|
||||||
|
|
||||||
|
|
||||||
|
This method can be used to pass flags as well as variables.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
External documentation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
For more information on the Meson build system, see:
|
||||||
|
https://mesonbuild.com/index.html
|
@ -66,6 +66,7 @@
|
|||||||
from llnl.util.filesystem import mkdirp, install, install_tree
|
from llnl.util.filesystem import mkdirp, install, install_tree
|
||||||
|
|
||||||
import spack.build_systems.cmake
|
import spack.build_systems.cmake
|
||||||
|
import spack.build_systems.meson
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.main
|
import spack.main
|
||||||
import spack.paths
|
import spack.paths
|
||||||
@ -384,11 +385,13 @@ def set_module_variables_for_package(pkg, module):
|
|||||||
# Don't use which for this; we want to find it in the current dir.
|
# Don't use which for this; we want to find it in the current dir.
|
||||||
m.configure = Executable('./configure')
|
m.configure = Executable('./configure')
|
||||||
|
|
||||||
|
m.meson = Executable('meson')
|
||||||
m.cmake = Executable('cmake')
|
m.cmake = Executable('cmake')
|
||||||
m.ctest = Executable('ctest')
|
m.ctest = Executable('ctest')
|
||||||
|
|
||||||
# Standard CMake arguments
|
# Standard CMake arguments
|
||||||
m.std_cmake_args = spack.build_systems.cmake.CMakePackage._std_args(pkg)
|
m.std_cmake_args = spack.build_systems.cmake.CMakePackage._std_args(pkg)
|
||||||
|
m.std_meson_args = spack.build_systems.meson.MesonPackage._std_args(pkg)
|
||||||
|
|
||||||
# Put spack compiler paths in module scope.
|
# Put spack compiler paths in module scope.
|
||||||
link_dir = spack.paths.build_env_path
|
link_dir = spack.paths.build_env_path
|
||||||
@ -557,6 +560,22 @@ def get_std_cmake_args(pkg):
|
|||||||
return spack.build_systems.cmake.CMakePackage._std_args(pkg)
|
return spack.build_systems.cmake.CMakePackage._std_args(pkg)
|
||||||
|
|
||||||
|
|
||||||
|
def get_std_meson_args(pkg):
|
||||||
|
"""List of standard arguments used if a package is a MesonPackage.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list of str: standard arguments that would be used if this
|
||||||
|
package were a MesonPackage instance.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pkg (PackageBase): package under consideration
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list of str: arguments for meson
|
||||||
|
"""
|
||||||
|
return spack.build_systems.meson.MesonPackage._std_args(pkg)
|
||||||
|
|
||||||
|
|
||||||
def parent_class_modules(cls):
|
def parent_class_modules(cls):
|
||||||
"""
|
"""
|
||||||
Get list of superclass modules that descend from spack.package.PackageBase
|
Get list of superclass modules that descend from spack.package.PackageBase
|
||||||
|
184
lib/spack/spack/build_systems/meson.py
Normal file
184
lib/spack/spack/build_systems/meson.py
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
##############################################################################
|
||||||
|
# Copyright (c) 2013-2018, 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/spack/spack
|
||||||
|
# Please also see the NOTICE and LICENSE files 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
|
||||||
|
|
||||||
|
from llnl.util.filesystem import working_dir
|
||||||
|
from spack.directives import depends_on, variant
|
||||||
|
from spack.package import PackageBase, run_after
|
||||||
|
|
||||||
|
|
||||||
|
class MesonPackage(PackageBase):
|
||||||
|
"""Specialized class for packages built using Meson
|
||||||
|
|
||||||
|
For more information on the Meson build system, see:
|
||||||
|
https://mesonbuild.com/
|
||||||
|
|
||||||
|
This class provides three phases that can be overridden:
|
||||||
|
|
||||||
|
1. :py:meth:`~.MesonPackage.meson`
|
||||||
|
2. :py:meth:`~.MesonPackage.build`
|
||||||
|
3. :py:meth:`~.MesonPackage.install`
|
||||||
|
|
||||||
|
They all have sensible defaults and for many packages the only thing
|
||||||
|
necessary will be to override :py:meth:`~.MesonPackage.meson_args`.
|
||||||
|
For a finer tuning you may also override:
|
||||||
|
|
||||||
|
+-----------------------------------------------+--------------------+
|
||||||
|
| **Method** | **Purpose** |
|
||||||
|
+===============================================+====================+
|
||||||
|
| :py:meth:`~.MesonPackage.root_mesonlists_dir` | Location of the |
|
||||||
|
| | root MesonLists.txt|
|
||||||
|
+-----------------------------------------------+--------------------+
|
||||||
|
| :py:meth:`~.MesonPackage.build_directory` | Directory where to |
|
||||||
|
| | build the package |
|
||||||
|
+-----------------------------------------------+--------------------+
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
#: Phases of a Meson package
|
||||||
|
phases = ['meson', 'build', 'install']
|
||||||
|
#: This attribute is used in UI queries that need to know the build
|
||||||
|
#: system base class
|
||||||
|
build_system_class = 'MesonPackage'
|
||||||
|
|
||||||
|
build_targets = []
|
||||||
|
install_targets = ['install']
|
||||||
|
|
||||||
|
build_time_test_callbacks = ['check']
|
||||||
|
|
||||||
|
variant('buildtype', default='release',
|
||||||
|
description='Meson build type',
|
||||||
|
values=('plain', 'debug', 'debugoptimized', 'release', 'minsize'))
|
||||||
|
|
||||||
|
depends_on('meson', type='build')
|
||||||
|
depends_on('ninja', type='build')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def archive_files(self):
|
||||||
|
"""Files to archive for packages based on Meson"""
|
||||||
|
return [os.path.join(self.build_directory, 'meson-logs/meson-log.txt')]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def root_mesonlists_dir(self):
|
||||||
|
"""The relative path to the directory containing meson.build
|
||||||
|
|
||||||
|
This path is relative to the root of the extracted tarball,
|
||||||
|
not to the ``build_directory``. Defaults to the current directory.
|
||||||
|
|
||||||
|
:return: directory containing meson.build
|
||||||
|
"""
|
||||||
|
return self.stage.source_path
|
||||||
|
|
||||||
|
@property
|
||||||
|
def std_meson_args(self):
|
||||||
|
"""Standard meson arguments provided as a property for
|
||||||
|
convenience of package writers
|
||||||
|
|
||||||
|
:return: standard meson arguments
|
||||||
|
"""
|
||||||
|
# standard Meson arguments
|
||||||
|
std_meson_args = MesonPackage._std_args(self)
|
||||||
|
std_meson_args += getattr(self, 'meson_flag_args', [])
|
||||||
|
return std_meson_args
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _std_args(pkg):
|
||||||
|
"""Computes the standard meson arguments for a generic package"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
build_type = pkg.spec.variants['buildtype'].value
|
||||||
|
except KeyError:
|
||||||
|
build_type = 'release'
|
||||||
|
|
||||||
|
args = [
|
||||||
|
'--prefix={0}'.format(pkg.prefix),
|
||||||
|
'--buildtype={0}'.format(build_type),
|
||||||
|
'--strip',
|
||||||
|
]
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
def flags_to_build_system_args(self, flags):
|
||||||
|
"""Produces a list of all command line arguments to pass the specified
|
||||||
|
compiler flags to meson."""
|
||||||
|
# Has to be dynamic attribute due to caching
|
||||||
|
setattr(self, 'meson_flag_args', [])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def build_directory(self):
|
||||||
|
"""Returns the directory to use when building the package
|
||||||
|
|
||||||
|
:return: directory where to build the package
|
||||||
|
"""
|
||||||
|
return os.path.join(self.stage.source_path, 'spack-build')
|
||||||
|
|
||||||
|
def meson_args(self):
|
||||||
|
"""Produces a list containing all the arguments that must be passed to
|
||||||
|
meson, except:
|
||||||
|
|
||||||
|
* ``--prefix``
|
||||||
|
* ``--buildtype``
|
||||||
|
* ``--strip``
|
||||||
|
|
||||||
|
which will be set automatically.
|
||||||
|
|
||||||
|
:return: list of arguments for meson
|
||||||
|
"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def meson(self, spec, prefix):
|
||||||
|
"""Runs ``meson`` in the build directory"""
|
||||||
|
options = [os.path.abspath(self.root_mesonlists_dir)]
|
||||||
|
options += self.std_meson_args
|
||||||
|
options += self.meson_args()
|
||||||
|
with working_dir(self.build_directory, create=True):
|
||||||
|
inspect.getmodule(self).meson(*options)
|
||||||
|
|
||||||
|
def build(self, spec, prefix):
|
||||||
|
"""Make the build targets"""
|
||||||
|
options = ['-v']
|
||||||
|
options += self.build_targets
|
||||||
|
with working_dir(self.build_directory):
|
||||||
|
inspect.getmodule(self).ninja(*options)
|
||||||
|
|
||||||
|
def install(self, spec, prefix):
|
||||||
|
"""Make the install targets"""
|
||||||
|
with working_dir(self.build_directory):
|
||||||
|
inspect.getmodule(self).ninja(*self.install_targets)
|
||||||
|
|
||||||
|
run_after('build')(PackageBase._run_default_build_time_test_callbacks)
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
"""Searches the Meson-generated file for the target ``test``
|
||||||
|
and runs it if found.
|
||||||
|
"""
|
||||||
|
with working_dir(self.build_directory):
|
||||||
|
self._if_ninja_target_execute('test')
|
||||||
|
self._if_ninja_target_execute('check')
|
||||||
|
|
||||||
|
# Check that self.prefix is there after installation
|
||||||
|
run_after('install')(PackageBase.sanity_check_prefix)
|
@ -31,6 +31,7 @@
|
|||||||
from spack.build_systems.waf import WafPackage
|
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.perl import PerlPackage
|
from spack.build_systems.perl import PerlPackage
|
||||||
|
from spack.build_systems.meson import MesonPackage
|
||||||
|
|
||||||
description = 'stops at build stage when installing a package, if possible'
|
description = 'stops at build stage when installing a package, if possible'
|
||||||
section = "build"
|
section = "build"
|
||||||
@ -45,6 +46,7 @@
|
|||||||
WafPackage: 'build',
|
WafPackage: 'build',
|
||||||
PythonPackage: 'build',
|
PythonPackage: 'build',
|
||||||
PerlPackage: 'build',
|
PerlPackage: 'build',
|
||||||
|
MesonPackage: 'build',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
from spack.build_systems.waf import WafPackage
|
from spack.build_systems.waf import WafPackage
|
||||||
from spack.build_systems.perl import PerlPackage
|
from spack.build_systems.perl import PerlPackage
|
||||||
from spack.build_systems.intel import IntelPackage
|
from spack.build_systems.intel import IntelPackage
|
||||||
|
from spack.build_systems.meson import MesonPackage
|
||||||
|
|
||||||
description = 'stage and configure a package but do not install'
|
description = 'stage and configure a package but do not install'
|
||||||
section = "build"
|
section = "build"
|
||||||
@ -47,6 +48,7 @@
|
|||||||
WafPackage: 'configure',
|
WafPackage: 'configure',
|
||||||
PerlPackage: 'configure',
|
PerlPackage: 'configure',
|
||||||
IntelPackage: 'configure',
|
IntelPackage: 'configure',
|
||||||
|
MesonPackage: 'meson',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,6 +195,18 @@ def cmake_args(self):
|
|||||||
return args"""
|
return args"""
|
||||||
|
|
||||||
|
|
||||||
|
class MesonPackageTemplate(PackageTemplate):
|
||||||
|
"""Provides appropriate overrides for meson-based packages"""
|
||||||
|
|
||||||
|
base_class_name = 'MesonPackage'
|
||||||
|
|
||||||
|
body = """\
|
||||||
|
def meson_args(self):
|
||||||
|
# FIXME: If not needed delete this function
|
||||||
|
args = []
|
||||||
|
return args"""
|
||||||
|
|
||||||
|
|
||||||
class QMakePackageTemplate(PackageTemplate):
|
class QMakePackageTemplate(PackageTemplate):
|
||||||
"""Provides appropriate overrides for QMake-based packages"""
|
"""Provides appropriate overrides for QMake-based packages"""
|
||||||
|
|
||||||
@ -389,6 +401,7 @@ class IntelPackageTemplate(PackageTemplate):
|
|||||||
'octave': OctavePackageTemplate,
|
'octave': OctavePackageTemplate,
|
||||||
'makefile': MakefilePackageTemplate,
|
'makefile': MakefilePackageTemplate,
|
||||||
'intel': IntelPackageTemplate,
|
'intel': IntelPackageTemplate,
|
||||||
|
'meson': MesonPackageTemplate,
|
||||||
'generic': PackageTemplate,
|
'generic': PackageTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,6 +472,7 @@ def __call__(self, stage, url):
|
|||||||
(r'/.*\.pro$', 'qmake'),
|
(r'/.*\.pro$', 'qmake'),
|
||||||
(r'/(GNU)?[Mm]akefile$', 'makefile'),
|
(r'/(GNU)?[Mm]akefile$', 'makefile'),
|
||||||
(r'/DESCRIPTION$', 'octave'),
|
(r'/DESCRIPTION$', 'octave'),
|
||||||
|
(r'/meson\.build$', 'meson'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Peek inside the compressed file.
|
# Peek inside the compressed file.
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
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
|
||||||
from spack.build_systems.intel import IntelPackage
|
from spack.build_systems.intel import IntelPackage
|
||||||
|
from spack.build_systems.meson import MesonPackage
|
||||||
|
|
||||||
from spack.mixins import filter_compiler_wrappers
|
from spack.mixins import filter_compiler_wrappers
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
('GNUmakefile', 'makefile'),
|
('GNUmakefile', 'makefile'),
|
||||||
('makefile', 'makefile'),
|
('makefile', 'makefile'),
|
||||||
('Makefile', 'makefile'),
|
('Makefile', 'makefile'),
|
||||||
|
('meson.build', 'meson'),
|
||||||
('foobar', 'generic')
|
('foobar', 'generic')
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user