define_from_variant: return an empty string for non-existing variants (#27503)

This permits to use conditional variants without a lot of boilerplate.
This commit is contained in:
Harmen Stoppels 2021-11-19 14:10:00 +01:00 committed by GitHub
parent 3db918b1cd
commit c5aee4d9b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 0 deletions

View File

@ -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

View File

@ -267,6 +267,10 @@ def define_from_variant(self, cmake_var, variant=None):
"-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 @@ def define_from_variant(self, cmake_var, variant=None):
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

View File

@ -429,3 +429,11 @@ def test_define(self):
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') == ''

View File

@ -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:')