Skip to content

Commit

Permalink
Cache variables declaration in CMakeToolchain (#11503)
Browse files Browse the repository at this point in the history
* Implementation + test

* Fix test

* Priority conf

* Update conan/tools/cmake/presets.py

Co-authored-by: Francisco Ramírez <franchuti688@gmail.com>

Co-authored-by: Francisco Ramírez <franchuti688@gmail.com>
  • Loading branch information
lasote and franramirez688 committed Jun 23, 2022
1 parent c843bb7 commit a5eab30
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 8 deletions.
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

0 comments on commit a5eab30

Please sign in to comment.