diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py index b7e616150e2..43739a955ca 100644 --- a/conan/tools/cmake/presets.py +++ b/conan/tools/cmake/presets.py @@ -5,7 +5,7 @@ from conan.api.output import ConanOutput, Color from conan.tools.cmake.layout import get_build_folder_custom_vars -from conan.tools.cmake.toolchain.blocks import GenericSystemBlock +from conan.tools.cmake.toolchain.blocks import GenericSystemBlock, CompilersBlock from conan.tools.cmake.utils import is_multi_configuration from conan.tools.build import build_jobs from conan.tools.microsoft import is_msvc @@ -158,6 +158,13 @@ def _configure_preset(conanfile, generator, cache_variables, toolchain_file, mul "strategy": "external" } + # Set the compiler like in the toolchain. Some IDEs like VS or VSCode require the compiler + # being set to cl.exe in order to activate the environment using vcvarsall.bat according to + # the toolset and architecture settings. + compilers = CompilersBlock.get_compilers(conanfile) + for lang, compiler in compilers.items(): + ret["cacheVariables"][f"CMAKE_{lang}_COMPILER"] = compiler.replace("\\", "/") + ret["toolchainFile"] = toolchain_file if conanfile.build_folder: # If we are installing a ref: "conan install ", we don't have build_folder, because diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py index 425e62b2af3..1343865c906 100644 --- a/conan/tools/cmake/toolchain/blocks.py +++ b/conan/tools/cmake/toolchain/blocks.py @@ -852,9 +852,13 @@ class CompilersBlock(Block): """) def context(self): + return {"compilers": self.get_compilers(self._conanfile)} + + @staticmethod + def get_compilers(conanfile): # Reading configuration from "tools.build:compiler_executables" -> {"C": "/usr/bin/gcc"} - compilers_by_conf = self._conanfile.conf.get("tools.build:compiler_executables", default={}, - check_type=dict) + compilers_by_conf = conanfile.conf.get("tools.build:compiler_executables", default={}, + check_type=dict) # Map the possible languages compilers = {} # Allowed variables (and _LAUNCHER) @@ -865,7 +869,7 @@ def context(self): # To set CMAKE__COMPILER if comp in compilers_by_conf: compilers[lang] = compilers_by_conf[comp] - return {"compilers": compilers} + return compilers class GenericSystemBlock(Block): diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py index 38ac9049b82..c174193ece6 100644 --- a/test/integration/toolchains/cmake/test_cmaketoolchain.py +++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py @@ -1046,6 +1046,30 @@ def test_set_cmake_lang_compilers_and_launchers(): assert 'set(CMAKE_RC_COMPILER "C:/local/rc.exe")' in toolchain +def test_cmake_presets_compiler(): + profile = textwrap.dedent(r""" + [settings] + os=Windows + arch=x86_64 + compiler=msvc + compiler.version=193 + compiler.runtime=dynamic + [conf] + tools.build:compiler_executables={"c": "cl", "cpp": "cl.exe", "rc": "C:\\local\\rc.exe"} + """) + client = TestClient() + conanfile = GenConanfile().with_settings("os", "arch", "compiler")\ + .with_generator("CMakeToolchain") + client.save({"conanfile.py": conanfile, + "profile": profile}) + client.run("install . -pr:b profile -pr:h profile") + presets = json.loads(client.load("CMakePresets.json")) + cache_variables = presets["configurePresets"][0]["cacheVariables"] + assert cache_variables["CMAKE_C_COMPILER"] == "cl" + assert cache_variables["CMAKE_CXX_COMPILER"] == "cl.exe" + assert cache_variables["CMAKE_RC_COMPILER"] == "C:/local/rc.exe" + + def test_cmake_layout_toolchain_folder(): """ in single-config generators, the toolchain is a different file per configuration https://github.com/conan-io/conan/issues/12827