summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/docs/build_systems.rst1
-rw-r--r--lib/spack/docs/build_systems/mesonpackage.rst85
-rw-r--r--lib/spack/spack/build_environment.py19
-rw-r--r--lib/spack/spack/build_systems/meson.py184
-rw-r--r--lib/spack/spack/cmd/build.py2
-rw-r--r--lib/spack/spack/cmd/configure.py2
-rw-r--r--lib/spack/spack/cmd/create.py14
-rw-r--r--lib/spack/spack/pkgkit.py1
-rw-r--r--lib/spack/spack/test/build_system_guess.py1
9 files changed, 309 insertions, 0 deletions
diff --git a/lib/spack/docs/build_systems.rst b/lib/spack/docs/build_systems.rst
index 562e5c9fd0..b84c9fe450 100644
--- a/lib/spack/docs/build_systems.rst
+++ b/lib/spack/docs/build_systems.rst
@@ -33,6 +33,7 @@ on these ideas for each distinct build system that Spack supports:
build_systems/autotoolspackage
build_systems/cmakepackage
+ build_systems/mesonpackage
build_systems/qmakepackage
.. toctree::
diff --git a/lib/spack/docs/build_systems/mesonpackage.rst b/lib/spack/docs/build_systems/mesonpackage.rst
new file mode 100644
index 0000000000..a3379d7772
--- /dev/null
+++ b/lib/spack/docs/build_systems/mesonpackage.rst
@@ -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
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 01a5a9ed17..7a47da13f7 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -66,6 +66,7 @@ from llnl.util.tty.color import cescape, colorize
from llnl.util.filesystem import mkdirp, install, install_tree
import spack.build_systems.cmake
+import spack.build_systems.meson
import spack.config
import spack.main
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.
m.configure = Executable('./configure')
+ m.meson = Executable('meson')
m.cmake = Executable('cmake')
m.ctest = Executable('ctest')
# Standard CMake arguments
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.
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)
+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):
"""
Get list of superclass modules that descend from spack.package.PackageBase
diff --git a/lib/spack/spack/build_systems/meson.py b/lib/spack/spack/build_systems/meson.py
new file mode 100644
index 0000000000..442c836391
--- /dev/null
+++ b/lib/spack/spack/build_systems/meson.py
@@ -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)
diff --git a/lib/spack/spack/cmd/build.py b/lib/spack/spack/cmd/build.py
index 7aa02a8747..d544d1c43e 100644
--- a/lib/spack/spack/cmd/build.py
+++ b/lib/spack/spack/cmd/build.py
@@ -31,6 +31,7 @@ from spack.build_systems.scons import SConsPackage
from spack.build_systems.waf import WafPackage
from spack.build_systems.python import PythonPackage
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'
section = "build"
@@ -45,6 +46,7 @@ build_system_to_phase = {
WafPackage: 'build',
PythonPackage: 'build',
PerlPackage: 'build',
+ MesonPackage: 'build',
}
diff --git a/lib/spack/spack/cmd/configure.py b/lib/spack/spack/cmd/configure.py
index 04ce8641e4..8135bfb994 100644
--- a/lib/spack/spack/cmd/configure.py
+++ b/lib/spack/spack/cmd/configure.py
@@ -34,6 +34,7 @@ from spack.build_systems.qmake import QMakePackage
from spack.build_systems.waf import WafPackage
from spack.build_systems.perl import PerlPackage
from spack.build_systems.intel import IntelPackage
+from spack.build_systems.meson import MesonPackage
description = 'stage and configure a package but do not install'
section = "build"
@@ -47,6 +48,7 @@ build_system_to_phase = {
WafPackage: 'configure',
PerlPackage: 'configure',
IntelPackage: 'configure',
+ MesonPackage: 'meson',
}
diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py
index eae6e6da3a..a9d0a8e999 100644
--- a/lib/spack/spack/cmd/create.py
+++ b/lib/spack/spack/cmd/create.py
@@ -195,6 +195,18 @@ class CMakePackageTemplate(PackageTemplate):
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):
"""Provides appropriate overrides for QMake-based packages"""
@@ -389,6 +401,7 @@ templates = {
'octave': OctavePackageTemplate,
'makefile': MakefilePackageTemplate,
'intel': IntelPackageTemplate,
+ 'meson': MesonPackageTemplate,
'generic': PackageTemplate,
}
@@ -459,6 +472,7 @@ class BuildSystemGuesser:
(r'/.*\.pro$', 'qmake'),
(r'/(GNU)?[Mm]akefile$', 'makefile'),
(r'/DESCRIPTION$', 'octave'),
+ (r'/meson\.build$', 'meson'),
]
# Peek inside the compressed file.
diff --git a/lib/spack/spack/pkgkit.py b/lib/spack/spack/pkgkit.py
index 563fe0f64a..bb688d1acd 100644
--- a/lib/spack/spack/pkgkit.py
+++ b/lib/spack/spack/pkgkit.py
@@ -44,6 +44,7 @@ from spack.build_systems.python import PythonPackage
from spack.build_systems.r import RPackage
from spack.build_systems.perl import PerlPackage
from spack.build_systems.intel import IntelPackage
+from spack.build_systems.meson import MesonPackage
from spack.mixins import filter_compiler_wrappers
diff --git a/lib/spack/spack/test/build_system_guess.py b/lib/spack/spack/test/build_system_guess.py
index 88c788f587..53bfa4ffb6 100644
--- a/lib/spack/spack/test/build_system_guess.py
+++ b/lib/spack/spack/test/build_system_guess.py
@@ -45,6 +45,7 @@ import spack.stage
('GNUmakefile', 'makefile'),
('makefile', 'makefile'),
('Makefile', 'makefile'),
+ ('meson.build', 'meson'),
('foobar', 'generic')
]
)