Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache variables declaration in CMakeToolchain #11503

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 9 additions & 6 deletions conan/tools/cmake/presets.py
Expand Up @@ -42,7 +42,6 @@ def _configure_preset_name(conanfile, multiconfig):
return str(build_type).lower()



def _add_configure_preset(conanfile, generator, cache_variables, toolchain_file, multiconfig):
build_type = conanfile.settings.get_safe("build_type")
name = _configure_preset_name(conanfile, multiconfig)
Expand Down Expand Up @@ -78,15 +77,19 @@ def _contents(conanfile, toolchain_file, cache_variables, generator):
return ret


def write_cmake_presets(conanfile, toolchain_file, generator):
cache_variables = {}
def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
cache_variables = cache_variables or {}
if platform.system() == "Windows" and generator == "MinGW Makefiles":
cache_variables["CMAKE_SH"] = "CMAKE_SH-NOTFOUND"
cmake_make_program = conanfile.conf.get("tools.gnu:make_program", default=None)
if "CMAKE_SH" not in cache_variables:
cache_variables["CMAKE_SH"] = "CMAKE_SH-NOTFOUND"

cmake_make_program = conanfile.conf.get("tools.gnu:make_program", default=cache_variables.get("CMAKE_MAKE_PROGRAM"))
if cmake_make_program:
cmake_make_program = cmake_make_program.replace("\\", "/")
cache_variables["CMAKE_MAKE_PROGRAM"] = cmake_make_program
cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] = "NEW"

if "CMAKE_POLICY_DEFAULT_CMP0091" not in cache_variables:
cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] = "NEW"

preset_path = os.path.join(conanfile.generators_folder, "CMakePresets.json")
multiconfig = is_multi_configuration(generator)
Expand Down
11 changes: 10 additions & 1 deletion conan/tools/cmake/toolchain/toolchain.py
Expand Up @@ -119,6 +119,8 @@ def __init__(self, conanfile, generator=None):
self._conanfile = conanfile
self.generator = self._get_generator(generator)
self.variables = Variables()
# This doesn't support multi-config, they go to the same configPreset common in multi-config
self.cache_variables = {}
self.preprocessor_definitions = Variables()

self.blocks = ToolchainBlocks(self._conanfile, self,
Expand Down Expand Up @@ -175,7 +177,14 @@ def generate(self):
elif self.generator is not None and "Visual" not in self.generator:
VCVars(self._conanfile).generate()
toolchain = os.path.join(self._conanfile.generators_folder, toolchain_file or self.filename)
write_cmake_presets(self._conanfile, toolchain, self.generator)
cache_variables = {}
for name, value in self.cache_variables.items():
if isinstance(value, bool):
cache_variables[name] = "ON" if value else "OFF"
else:
cache_variables[name] = value

write_cmake_presets(self._conanfile, toolchain, self.generator, cache_variables)

def _get_generator(self, recipe_generator):
# Returns the name of the generator to be used by CMake
Expand Down
34 changes: 34 additions & 0 deletions conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
Expand Up @@ -4,6 +4,7 @@
import textwrap

import pytest
from mock import mock

from conan.tools.cmake.presets import load_cmake_presets
from conans.test.assets.genconanfile import GenConanfile
Expand Down Expand Up @@ -439,3 +440,36 @@ def test_cmake_presets_singleconfig():
client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Debug --profile:h=profile")
presets = json.loads(client.load("CMakePresets.json"))
assert len(presets["configurePresets"]) == 2


def test_toolchain_cache_variables():
client = TestClient()
conanfile = textwrap.dedent("""
from conans import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake

class Conan(ConanFile):
settings = "os", "arch", "compiler", "build_type"

def generate(self):
toolchain = CMakeToolchain(self)
toolchain.cache_variables["foo"] = True
toolchain.cache_variables["foo2"] = False
toolchain.cache_variables["var"] = "23"
toolchain.cache_variables["CMAKE_SH"] = "THIS VALUE HAS PRIORITY"
toolchain.cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] = "THIS VALUE HAS PRIORITY"
toolchain.cache_variables["CMAKE_MAKE_PROGRAM"] = "THIS VALUE HAS NO PRIORITY"
toolchain.generate()
""")
client.save({"conanfile.py": conanfile})
with mock.patch("platform.system", mock.MagicMock(return_value="Windows")):
client.run("install . mylib/1.0@ -c tools.cmake.cmaketoolchain:generator='MinGW Makefiles' "
"-c tools.gnu:make_program='MyMake'")
presets = json.loads(client.load("CMakePresets.json"))
cache_variables = presets["configurePresets"][0]["cacheVariables"]
assert cache_variables["foo"] == 'ON'
assert cache_variables["foo2"] == 'OFF'
assert cache_variables["var"] == '23'
assert cache_variables["CMAKE_SH"] == "THIS VALUE HAS PRIORITY"
assert cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] == "THIS VALUE HAS PRIORITY"
assert cache_variables["CMAKE_MAKE_PROGRAM"] == "MyMake"
Expand Up @@ -40,7 +40,7 @@ def run(command):
conanfile.conf.define("tools.gnu:make_program", "C:\\mymake.exe")

with mock.patch("platform.system", mock.MagicMock(return_value='Windows')):
write_cmake_presets(conanfile, "the_toolchain.cmake", "MinGW Makefiles")
write_cmake_presets(conanfile, "the_toolchain.cmake", "MinGW Makefiles", {})

cmake = CMake(conanfile)
cmake.configure()
Expand Down