Jelajahi Sumber

Xcode: Restore default CMAKE_OSX_DEPLOYMENT_TARGET to run on host

Xcode by default targets the SDK's macOS version rather than the host's
macOS version.  In commit 7b19531291 (macOS: Do not pass any
SDK/-isysroot to compilers by default, 2024-11-06, v4.0.0-rc1~511^2) we
reverted commit 24aafbde11 (Xcode: Adjust deployment target SDK version
to host version, 2015-10-11, v3.4.0-rc2~6^2), but it is still needed for
Xcode.  Restore the behavior so binaries run on the host by default.

Fixes: #27309
Brad King 3 bulan lalu
induk
melakukan
1a37c83c7e

+ 34 - 10
Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst

@@ -1,15 +1,39 @@
 CMAKE_OSX_DEPLOYMENT_TARGET
 ---------------------------
 
-Specify the minimum version of the target platform (e.g. macOS or iOS)
-on which the target binaries are to be deployed.  CMake uses this
-variable value for the ``-mmacosx-version-min`` flag or their respective
-target platform equivalents.  For older Xcode versions that shipped
-multiple macOS SDKs this variable also helps to choose the SDK in case
-:variable:`CMAKE_OSX_SYSROOT` is unset.
-
-If not set explicitly the value is initialized by the
-``MACOSX_DEPLOYMENT_TARGET`` environment variable, if set,
-and otherwise computed based on the host platform.
+Specify the minimum version of the target platform, e.g., macOS or iOS,
+on which the target binaries are to be deployed.
+
+For builds targeting macOS (:variable:`CMAKE_SYSTEM_NAME` is ``Darwin``), if
+``CMAKE_OSX_DEPLOYMENT_TARGET`` is not explicitly set, a default is set:
+
+* If the ``MACOSX_DEPLOYMENT_TARGET`` environment variable is non-empty,
+  its value is the default.
+
+* Otherwise, if using the :generator:`Xcode` generator, and the host's
+  macOS version is older than the macOS SDK (:variable:`CMAKE_OSX_SYSROOT`,
+  if set, or Xcode's default SDK), the host's macOS version is the default.
+
+  .. versionchanged:: 4.0
+
+    Previously this was done for all generators, not just Xcode.
+
+* Otherwise, the default is empty.
+
+The effects of ``CMAKE_OSX_DEPLOYMENT_TARGET`` depend on the generator:
+
+:generator:`Xcode`
+
+  If ``CMAKE_OSX_DEPLOYMENT_TARGET`` is set to a non-empty value, it is added
+  to the generated Xcode project as the ``MACOSX_DEPLOYMENT_TARGET`` setting.
+  Otherwise, no such setting is added, so Xcode's default deployed target is
+  used, typically based on the SDK version.
+
+Other Generators
+
+  If ``CMAKE_OSX_DEPLOYMENT_TARGET`` is set to a non-empty value, it is passed
+  to the compiler via the ``-mmacosx-version-min`` flag or equivalent.
+  Otherwise, no such flag is added, so the compiler's default deployment
+  target is used.
 
 .. include:: CMAKE_OSX_VARIABLE.txt

+ 33 - 3
Modules/Platform/Darwin-Initialize.cmake

@@ -291,8 +291,38 @@ if(NOT CMAKE_CROSSCOMPILING)
     OUTPUT_STRIP_TRAILING_WHITESPACE)
 endif()
 
-# Set cache variable - end user may change this during ccmake or cmake-gui configure.
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-  set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
+  set(_CMAKE_OSX_DEPLOYMENT_TARGET_DEFAULT "$ENV{MACOSX_DEPLOYMENT_TARGET}")
+
+  # Xcode chooses a default macOS deployment target based on the macOS SDK
+  # version, which may be too new for binaries to run on the host.
+  if(NOT _CMAKE_OSX_DEPLOYMENT_TARGET_DEFAULT
+      AND CMAKE_GENERATOR STREQUAL "Xcode" AND NOT CMAKE_CROSSCOMPILING
+      AND _CMAKE_HOST_OSX_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
+    set(_macos_version "${CMAKE_MATCH_1}")
+    if(CMAKE_OSX_SYSROOT)
+      set(_sdk_macosx --sdk ${CMAKE_OSX_SYSROOT})
+    else()
+      set(_sdk_macosx)
+    endif()
+    execute_process(
+      COMMAND xcrun ${_sdk_macosx} --show-sdk-version
+      OUTPUT_VARIABLE _sdk_version OUTPUT_STRIP_TRAILING_WHITESPACE
+      ERROR_VARIABLE _sdk_version_error
+      RESULT_VARIABLE _sdk_version_result
+    )
+    if(_sdk_version_result EQUAL 0 AND _sdk_version
+        AND "${_macos_version}" VERSION_LESS "${_sdk_version}")
+      set(_CMAKE_OSX_DEPLOYMENT_TARGET_DEFAULT "${_macos_version}")
+    endif()
+    unset(_sdk_macosx)
+    unset(_sdk_version_result)
+    unset(_sdk_version_error)
+    unset(_sdk_version)
+    unset(_macos_version)
+  endif()
+
+  set(CMAKE_OSX_DEPLOYMENT_TARGET "${_CMAKE_OSX_DEPLOYMENT_TARGET_DEFAULT}" CACHE STRING
     "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value.")
+  unset(_CMAKE_OSX_DEPLOYMENT_TARGET_DEFAULT)
 endif()