summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/docs/build_systems/cmakepackage.rst14
-rw-r--r--lib/spack/spack/build_systems/cmake.py7
-rw-r--r--lib/spack/spack/test/build_systems.py8
-rw-r--r--var/spack/repos/builtin.mock/packages/cmake-conditional-variants-test/package.py9
4 files changed, 38 insertions, 0 deletions
diff --git a/lib/spack/docs/build_systems/cmakepackage.rst b/lib/spack/docs/build_systems/cmakepackage.rst
index 3c3c96f92c..7ebac48734 100644
--- a/lib/spack/docs/build_systems/cmakepackage.rst
+++ b/lib/spack/docs/build_systems/cmakepackage.rst
@@ -145,6 +145,20 @@ and without the :meth:`~spack.build_systems.cmake.CMakePackage.define` and
return args
+Spack supports CMake defines from conditional variants too. Whenever the condition on
+the variant is not met, ``define_from_variant()`` will simply return an empty string,
+and CMake simply ignores the empty command line argument. For example the following
+
+.. code-block:: python
+
+ variant('example', default=True, when='@2.0:')
+
+ def cmake_args(self):
+ return [self.define_from_variant('EXAMPLE', 'example')]
+
+will generate ``'cmake' '-DEXAMPLE=ON' ...`` when `@2.0: +example` is met, but will
+result in ``'cmake' '' ...`` when the spec version is below ``2.0``.
+
^^^^^^^^^^
Generators
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
index bf431e139d..e7ea30c6a2 100644
--- a/lib/spack/spack/build_systems/cmake.py
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -267,6 +267,10 @@ class CMakePackage(PackageBase):
"-DSWR:STRING=avx;avx2]
for ``<spec-name> cxxstd=14 +shared swr=avx,avx2``
+
+ Note: if the provided variant is conditional, and the condition is not met,
+ this function returns an empty string. CMake discards empty strings
+ provided on the command line.
"""
if variant is None:
@@ -276,6 +280,9 @@ class CMakePackage(PackageBase):
raise KeyError(
'"{0}" is not a variant of "{1}"'.format(variant, self.name))
+ if variant not in self.spec.variants:
+ return ''
+
value = self.spec.variants[variant].value
if isinstance(value, (tuple, list)):
# Sort multi-valued variants for reproducibility
diff --git a/lib/spack/spack/test/build_systems.py b/lib/spack/spack/test/build_systems.py
index b9105538b2..1a46a83d45 100644
--- a/lib/spack/spack/test/build_systems.py
+++ b/lib/spack/spack/test/build_systems.py
@@ -429,3 +429,11 @@ class TestXorgPackage(object):
assert pkg.urls[0] == 'https://www.x.org/archive/individual/' \
'util/util-macros-1.19.1.tar.bz2'
+
+
+def test_cmake_define_from_variant_conditional(config, mock_packages):
+ """Test that define_from_variant returns empty string when a condition on a variant
+ is not met. When this is the case, the variant is not set in the spec."""
+ s = Spec('cmake-conditional-variants-test').concretized()
+ assert 'example' not in s.variants
+ assert s.package.define_from_variant('EXAMPLE', 'example') == ''
diff --git a/var/spack/repos/builtin.mock/packages/cmake-conditional-variants-test/package.py b/var/spack/repos/builtin.mock/packages/cmake-conditional-variants-test/package.py
new file mode 100644
index 0000000000..53ecd1e287
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/cmake-conditional-variants-test/package.py
@@ -0,0 +1,9 @@
+# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+class CmakeConditionalVariantsTest(CMakePackage):
+ homepage = "https://dev.null"
+ version('1.0')
+ variant('example', default=True, description='nope', when='@2.0:')