diff --git a/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst b/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst index 9df5edda64..ef10c75b32 100644 --- a/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst +++ b/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. +Specify the minimum version of the target platform, e.g., macOS or iOS, +on which the target binaries are to be deployed. -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. +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 diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake index 09d02a74c7..0c0a206ced 100644 --- a/Modules/Platform/Darwin-Initialize.cmake +++ b/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()