Repository: conan-io/conan
Pull request #16846 (2024-08-19 14:45:06)

Add test to show users about `compiler.cppstd` when it's hardcoded in the CmakeLists
Changelog: Omit
Docs: Omit

To be able to show to users why we would ask to remove that line in upstream cmakelists in CCI


Patch:
diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py
index 0455ae45e..ab4a71293 100644
--- a/conan/tools/microsoft/visual.py
+++ b/conan/tools/microsoft/visual.py
@@ -367,11 +367,12 @@ def is_msvc_static_runtime(conanfile):
 
 def msvs_toolset(conanfile):
     """
-    Returns the corresponding platform toolset based on the compiler of the given conanfile.
+    Returns the corresponding platform toolset based on the compiler setting.
     In case no toolset is configured in the profile, it will return a toolset based on the
     compiler version, otherwise, it will return the toolset from the profile.
     When there is no compiler version neither toolset configured, it will return None
-    It supports Visual Studio, msvc and Intel.
+    It supports msvc, intel-cc and clang compilers. For clang, is assumes the ClangCl toolset,
+    as provided by the Visual Studio installer.
 
     :param conanfile: Conanfile instance to access settings.compiler
     :return: A toolset when compiler.version is valid or compiler.toolset is configured. Otherwise, None.
@@ -384,5 +385,7 @@ def msvs_toolset(conanfile):
         if subs_toolset:
             return subs_toolset
         return msvc_version_to_toolset_version(compiler_version)
+    if compiler == "clang":
+        return "ClangCl"
     if compiler == "intel-cc":
         return IntelCC(conanfile).ms_toolset


Test patch:
diff --git a/test/functional/toolchains/cmake/test_cmake_toolchain.py b/test/functional/toolchains/cmake/test_cmake_toolchain.py
index b64c5c791..ce014b821 100644
--- a/test/functional/toolchains/cmake/test_cmake_toolchain.py
+++ b/test/functional/toolchains/cmake/test_cmake_toolchain.py
@@ -2016,3 +2016,22 @@ def test_cmake_toolchain_ninja_multi_config():
     assert 'DEFINE conan_test_answer=456!' in c.out
     assert 'DEFINE conan_test_other=abc!' in c.out
     assert 'DEFINE conan_test_complex="1 2"!' in c.out
+
+
+@pytest.mark.tool("cmake")
+@pytest.mark.skipif(platform.system() != "Darwin", reason="Only needs to run once, no need for extra platforms")
+def test_cxx_version_not_overriden_if_hardcoded():
+    """Any C++ standard set in the CMakeLists.txt will have priority even if the
+    compiler.cppstd is set in the profile"""
+    tc = TestClient()
+    tc.run("new cmake_exe -dname=foo -dversion=1.0")
+
+    cml_contents = tc.load("CMakeLists.txt")
+    cml_contents = cml_contents.replace("project(foo CXX)\n", "project(foo CXX)\nset(CMAKE_CXX_STANDARD 17)\n")
+    tc.save({"CMakeLists.txt": cml_contents})
+
+    # The compiler.cppstd will not override the CXX_STANDARD variable
+    tc.run("create . -s=compiler.cppstd=11")
+    assert "Conan toolchain: C++ Standard 11 with extensions OFF" in tc.out
+    # Conan says yes! But alas, the compiled code is C++17
+    assert "foo/1.0: __cplusplus2017" in tc.out
diff --git a/test/unittests/tools/microsoft/test_msvs_toolset.py b/test/unittests/tools/microsoft/test_msvs_toolset.py
index e7b70a3f9..e1c7f3098 100644
--- a/test/unittests/tools/microsoft/test_msvs_toolset.py
+++ b/test/unittests/tools/microsoft/test_msvs_toolset.py
@@ -81,3 +81,10 @@ def test_intel_cc_default(compiler_version, compiler_mode, expected_toolset):
                                        "compiler.version": compiler_version,
                                        "compiler.mode": compiler_mode})
     assert msvs_toolset(conanfile) == expected_toolset
+
+def test_clang_platform_toolset():
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "clang",
+                             "compiler.version": "17",
+                             "compiler.runtime": "dynamic"})
+    assert msvs_toolset(conanfile) == "ClangCl"