diff --git a/conan/tools/cmake/toolchain.py b/conan/tools/cmake/toolchain.py index b1168ebc354..580a86b29ac 100644 --- a/conan/tools/cmake/toolchain.py +++ b/conan/tools/cmake/toolchain.py @@ -515,6 +515,12 @@ def _get_toolset(self, generator): return "version=14.{}".format(minor) else: return "v14{}".format(minor) + elif compiler == "clang": + if generator and "Visual" in generator: + if "Visual Studio 16" in generator: + return "ClangCL" + else: + raise ConanException("CMakeToolchain compiler=clang only supported VS 16") return None def _get_generator_platform(self, generator): diff --git a/conans/test/conftest.py b/conans/test/conftest.py index 2cc65a1d376..161a1973654 100644 --- a/conans/test/conftest.py +++ b/conans/test/conftest.py @@ -34,8 +34,11 @@ tools_locations = { + "clang": {"disabled": True}, 'visual_studio': {"default": "15", - "15": {}}, + "15": {}, + "16": {"disabled": True}}, + 'pkg_config': {"exe": "pkg-config", "default": "system", # pacman -S pkg-config inside msys2-mingw64 @@ -147,6 +150,7 @@ def _get_tool(name, version): version = version or tool.get("default") tool_version = tool.get(version) if tool_version is not None: + assert isinstance(tool_version, dict) if tool_version.get("disabled"): _cached_tools[name][version] = False return False diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py new file mode 100644 index 00000000000..797d7e03dd4 --- /dev/null +++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py @@ -0,0 +1,102 @@ +import platform +import textwrap + +import pytest + +from conans.test.assets.cmake import gen_cmakelists +from conans.test.assets.sources import gen_function_cpp +from conans.test.utils.tools import TestClient +from conans.util.files import save + + +@pytest.fixture +def client(): + c = TestClient() + save(c.cache.new_config_path, "tools.env.virtualenv:auto_use=True") + clang_profile = textwrap.dedent(""" + [settings] + os=Windows + arch=x86_64 + build_type=Release + compiler=clang + compiler.version=12 + + [buildenv] + CC=clang + CXX=clang++ + RC=clang + """) + conanfile = textwrap.dedent(""" + import os + from conans import ConanFile + from conan.tools.cmake import CMake + from conan.tools.layout import cmake_layout + class Pkg(ConanFile): + settings = "os", "compiler", "build_type", "arch" + exports_sources = "*" + generators = "CMakeToolchain" + + def layout(self): + cmake_layout(self) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + cmd = os.path.join(self.cpp.build.bindirs[0], "my_app") + self.run(cmd, env=["conanrunenv"]) + """) + c.save({"conanfile.py": conanfile, + "clang": clang_profile, + "src/CMakeLists.txt": gen_cmakelists(appname="my_app", appsources=["main.cpp"]), + "src/main.cpp": gen_function_cpp(name="main")}) + return c + + +@pytest.mark.tool_cmake +@pytest.mark.tool_mingw64 +@pytest.mark.tool_clang(version="12") +@pytest.mark.skipif(platform.system() != "Windows", reason="requires Win") +def test_clang(client): + client.run("create . pkg/0.1@ -pr=clang") + # clang compilations in Windows will use MinGW Makefiles by default + assert 'cmake -G "MinGW Makefiles"' in client.out + assert "main __clang_major__12" in client.out + # Check this! Clang compiler in Windows is reporting MSC_VER and MSVC_LANG! + assert "main _MSC_VER19" in client.out + assert "main _MSVC_LANG2014" in client.out + + +@pytest.mark.tool_cmake +@pytest.mark.tool_clang(version="12") +@pytest.mark.skipif(platform.system() != "Windows", reason="requires Win") +def test_clang_cmake_ninja(client): + client.run("create . pkg/0.1@ -pr=clang -c tools.cmake.cmaketoolchain:generator=Ninja") + assert 'cmake -G "Ninja"' in client.out + assert "main __clang_major__12" in client.out + # Check this! Clang compiler in Windows is reporting MSC_VER and MSVC_LANG! + assert "main _MSC_VER19" in client.out + assert "main _MSVC_LANG2014" in client.out + + +@pytest.mark.tool_cmake +@pytest.mark.tool_visual_studio(version="16") # With Clang distributed in VS! +@pytest.mark.skipif(platform.system() != "Windows", reason="requires Win") +def test_clang_cmake_visual(client): + clang_profile = textwrap.dedent(""" + [settings] + os=Windows + arch=x86_64 + build_type=Release + compiler=clang + compiler.version=11 + """) + # TODO: Clang version is unused, it can change, still 11 from inside VS is used + client.save({"clang": clang_profile}) + client.run("create . pkg/0.1@ -pr=clang " + '-c tools.cmake.cmaketoolchain:generator="Visual Studio 16"') + assert 'cmake -G "Visual Studio 16"' in client.out + assert "main __clang_major__11" in client.out + # Check this! Clang compiler in Windows is reporting MSC_VER and MSVC_LANG! + assert "main _MSC_VER19" in client.out + assert "main _MSVC_LANG2014" in client.out