Repository: conan-io/conan

Issue:
CMAKE_SYSTEM_VERSION is not correctly set when autodetected
As stated in the CMake documentation when in Apple systems [CMAKE_SYSTEM_VERSION](https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_VERSION.html)  is the version for the Darwin version, but we are setting the sdk version, which does not seem correct.
In general the best approach for cross-building would be to set these variables via the conf or user toolchain, but we may fix this by converting from the [OS version to the Darwin version](https://en.wikipedia.org/wiki/Darwin_(operating_system)).

https://github.com/conan-io/conan/blob/151c1dd3b5c45b2c968a1bbe50b220027d415a37/conan/tools/cmake/toolchain/blocks.py#L905




Discussion:

Patch:
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 02d6c4723f5..8b3da508fb6 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -18,6 +18,7 @@
 from conan.tools.microsoft.visual import msvc_version_to_toolset_version
 from conans.client.subsystems import deduce_subsystem, WINDOWS
 from conan.errors import ConanException
+from conans.model.version import Version
 from conans.util.files import load
 
 
@@ -533,7 +534,7 @@ def _get_host_runtime_dirs(self, host_req):
         for req in host_req:
             cppinfo = req.cpp_info.aggregated_components()
             runtime_dirs.extend(cppinfo.bindirs if is_win else cppinfo.libdirs)
-        
+
         build_type = settings.get_safe("build_type")
         host_runtime_dirs[build_type] = [s.replace("\\", "/") for s in runtime_dirs]
 
@@ -919,6 +920,34 @@ def _is_apple_cross_building(self):
         return os_host in ('iOS', 'watchOS', 'tvOS', 'visionOS') or (
                 os_host == 'Macos' and (arch_host != arch_build or os_build != os_host))
 
+    def _get_darwin_version(self, os_name, os_version):
+        # version mapping from https://en.wikipedia.org/wiki/Darwin_(operating_system)
+        version_mapping = {
+            "Macos": {
+                "10.6": "10", "10.7": "11", "10.8": "12", "10.9": "13", "10.10": "14", "10.11": "15",
+                "10.12": "16", "10.13": "17", "10.14": "18", "10.15": "19", "11": "20", "12": "21",
+                "13": "22", "14": "23",
+            },
+            "iOS": {
+                "7": "14", "8": "14", "9": "15", "10": "16", "11": "17", "12": "18", "13": "19",
+                "14": "20", "15": "21", "16": "22", "17": "23"
+            },
+            "watchOS": {
+                "4": "17", "5": "18", "6": "19", "7": "20",
+                "8": "21", "9": "22", "10": "23"
+            },
+            "tvOS": {
+                "11": "17", "12": "18", "13": "19", "14": "20",
+                "15": "21", "16": "22", "17": "23"
+            },
+            "visionOS": {
+                "1": "23"
+            }
+        }
+        os_version = Version(os_version).major if os_name != "Macos" or (os_name == "Macos" and Version(
+            os_version) >= Version("11")) else os_version
+        return version_mapping.get(os_name, {}).get(str(os_version))
+
     def _get_cross_build(self):
         user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain")
 
@@ -930,6 +959,7 @@ def _get_cross_build(self):
         if not user_toolchain and not is_universal_arch(self._conanfile.settings.get_safe("arch"),
                                                         self._conanfile.settings.possible_values().get("arch")):
             os_host = self._conanfile.settings.get_safe("os")
+            os_host_version = self._conanfile.settings.get_safe("os.version")
             arch_host = self._conanfile.settings.get_safe("arch")
             if arch_host == "armv8":
                 arch_host = {"Windows": "ARM64", "Macos": "arm64"}.get(os_host, "aarch64")
@@ -940,12 +970,12 @@ def _get_cross_build(self):
                 if self._is_apple_cross_building():
                     # cross-build in Macos also for M1
                     system_name = {'Macos': 'Darwin'}.get(os_host, os_host)
-                    #  CMAKE_SYSTEM_VERSION for Apple sets the sdk version, not the os version
-                    _system_version = self._conanfile.settings.get_safe("os.sdk_version")
+                    #  CMAKE_SYSTEM_VERSION for Apple sets the Darwin version, not the os version
+                    _system_version = self._get_darwin_version(os_host, os_host_version)
                     _system_processor = to_apple_arch(self._conanfile)
                 elif os_host != 'Android':
                     system_name = self._get_generic_system_name()
-                    _system_version = self._conanfile.settings.get_safe("os.version")
+                    _system_version = os_host_version
                     _system_processor = arch_host
 
                 if system_name is not None and system_version is None:


Test patch:
diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 81ad493a1ef..df1fff5ef2c 100644
--- a/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -68,7 +68,7 @@ def test_cross_build_linux_to_macos():
     macos_profile = textwrap.dedent("""
         [settings]
         os=Macos
-        os.sdk_version=13.1
+        os.version=13.1
         arch=x86_64
         compiler=apple-clang
         compiler.version=13
@@ -85,7 +85,7 @@ def test_cross_build_linux_to_macos():
     toolchain = client.load("conan_toolchain.cmake")
 
     assert "set(CMAKE_SYSTEM_NAME Darwin)" in toolchain
-    assert "set(CMAKE_SYSTEM_VERSION 13.1)" in toolchain
+    assert "set(CMAKE_SYSTEM_VERSION 22)" in toolchain
     assert "set(CMAKE_SYSTEM_PROCESSOR x86_64)" in toolchain
 
 
@@ -437,7 +437,7 @@ def test_cmaketoolchain_cmake_system_processor_cross_apple():
     client.run("install hello.py -pr:h=./profile_ios -pr:b=default -g CMakeToolchain")
     toolchain = client.load("conan_toolchain.cmake")
     assert "set(CMAKE_SYSTEM_NAME iOS)" in toolchain
-    assert "set(CMAKE_SYSTEM_VERSION 15.0)" in toolchain
+    assert "set(CMAKE_SYSTEM_VERSION 21)" in toolchain
     assert "set(CMAKE_SYSTEM_PROCESSOR arm64)" in toolchain