From c5aee4d9b4840bc23041fa5d3339012598619cca Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Fri, 19 Nov 2021 14:10:00 +0100 Subject: define_from_variant: return an empty string for non-existing variants (#27503) This permits to use conditional variants without a lot of boilerplate. --- lib/spack/docs/build_systems/cmakepackage.rst | 14 ++++++++++++++ lib/spack/spack/build_systems/cmake.py | 7 +++++++ lib/spack/spack/test/build_systems.py | 8 ++++++++ .../packages/cmake-conditional-variants-test/package.py | 9 +++++++++ 4 files changed, 38 insertions(+) create mode 100644 var/spack/repos/builtin.mock/packages/cmake-conditional-variants-test/package.py 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 `` 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:') -- cgit v1.2.3-70-g09d2