From 4017bf40de512e977d59c12f4e3f6c91f5dd953d Mon Sep 17 00:00:00 2001 From: Gregor Jasny Date: Sat, 4 Nov 2017 15:27:48 +0100 Subject: [PATCH] Darwin: Emit deployment target that matches the SDK Closes: #17431 --- Help/release/dev/iphone-deployment-target.rst | 11 +++++++ Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst | 10 +++--- Help/variable/CMAKE_OSX_VARIABLE.txt | 5 ++- Modules/Platform/Darwin-Clang.cmake | 15 +++++++++ Source/cmGlobalXCodeGenerator.cxx | 23 ++++++++++++- Source/cmGlobalXCodeGenerator.h | 2 ++ Source/cmMakefile.cxx | 31 ++++++++++++------ Source/cmMakefile.h | 15 +++++++++ .../RunCMake/XcodeProject/DeploymentTarget.c | 26 +++++++++++++++ .../XcodeProject/DeploymentTarget.cmake | 32 +++++++++++++++++++ .../RunCMake/XcodeProject/RunCMakeTest.cmake | 18 +++++++++++ .../RunCMake/XcodeProject/XcodeBundles.cmake | 3 ++ .../XcodeIOSInstallCombined.cmake | 3 ++ .../XcodeIOSInstallCombinedPrune.cmake | 3 ++ .../XcodeIOSInstallCombinedSingleArch.cmake | 3 ++ 15 files changed, 185 insertions(+), 15 deletions(-) create mode 100644 Help/release/dev/iphone-deployment-target.rst create mode 100644 Tests/RunCMake/XcodeProject/DeploymentTarget.c create mode 100644 Tests/RunCMake/XcodeProject/DeploymentTarget.cmake diff --git a/Help/release/dev/iphone-deployment-target.rst b/Help/release/dev/iphone-deployment-target.rst new file mode 100644 index 0000000000..e586df69a6 --- /dev/null +++ b/Help/release/dev/iphone-deployment-target.rst @@ -0,0 +1,11 @@ +iphone-deployment-target +------------------------ + +* The minimum deployment target set in the + :variable:`CMAKE_OSX_DEPLOYMENT_TARGET` variable used to be only + applied for macOS regardless of the selected SDK. It is now properly + set for the target platform selected by :variable:`CMAKE_OSX_SYSROOT`. + + If for example the sysroot variable specifies an iOS SDK then the + value in ``CMAKE_OSX_DEPLOYMENT_TARGET`` is interpreted as minium + iOS version. diff --git a/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst b/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst index 4fb2caa4f2..9df5edda64 100644 --- a/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst +++ b/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst @@ -1,10 +1,12 @@ CMAKE_OSX_DEPLOYMENT_TARGET --------------------------- -Specify the minimum version of OS X on which the target binaries are -to be deployed. CMake uses this value for the ``-mmacosx-version-min`` -flag and to help choose the default SDK -(see :variable:`CMAKE_OSX_SYSROOT`). +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, diff --git a/Help/variable/CMAKE_OSX_VARIABLE.txt b/Help/variable/CMAKE_OSX_VARIABLE.txt index 385f871f3e..5b84726048 100644 --- a/Help/variable/CMAKE_OSX_VARIABLE.txt +++ b/Help/variable/CMAKE_OSX_VARIABLE.txt @@ -3,4 +3,7 @@ The value of this variable should be set prior to the first because it may influence configuration of the toolchain and flags. It is intended to be set locally by the user creating a build tree. -This variable is ignored on platforms other than OS X. +Despite the ``OSX`` part in the variable name(s) they apply also to +other SDKs than macOS like iOS, tvOS, or watchOS. + +This variable is ignored on platforms other than Apple. diff --git a/Modules/Platform/Darwin-Clang.cmake b/Modules/Platform/Darwin-Clang.cmake index a6661a849d..f8a07ec2dd 100644 --- a/Modules/Platform/Darwin-Clang.cmake +++ b/Modules/Platform/Darwin-Clang.cmake @@ -17,4 +17,19 @@ macro(__darwin_compiler_clang lang) if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.2) set(CMAKE_${lang}_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ") endif() + if(_CMAKE_OSX_SYSROOT_PATH MATCHES "/iPhoneOS") + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-miphoneos-version-min=") + elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/iPhoneSimulator") + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mios-simulator-version-min=") + elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/AppleTVOS") + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mtvos-version-min=") + elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/AppleTVSimulator") + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mtvos-simulator-version-min=") + elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/WatchOS") + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mwatchos-version-min=") + elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/WatchSimulator") + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mwatchos-simulator-version-min=") + else() + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=") + endif() endmacro() diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index f392589f90..5c6a846247 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2992,7 +2992,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( buildSettings->AddAttribute("ARCHS", this->CreateString(archs)); } if (deploymentTarget && *deploymentTarget) { - buildSettings->AddAttribute("MACOSX_DEPLOYMENT_TARGET", + buildSettings->AddAttribute(GetDeploymentPlatform(root->GetMakefile()), this->CreateString(deploymentTarget)); } if (!this->GeneratorToolset.empty()) { @@ -3627,3 +3627,24 @@ void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory( dir += "/"; gt->ObjectDirectory = dir; } + +std::string cmGlobalXCodeGenerator::GetDeploymentPlatform(const cmMakefile* mf) +{ + switch (mf->GetAppleSDKType()) { + case cmMakefile::AppleSDK::AppleTVOS: + case cmMakefile::AppleSDK::AppleTVSimulator: + return "TVOS_DEPLOYMENT_TARGET"; + + case cmMakefile::AppleSDK::IPhoneOS: + case cmMakefile::AppleSDK::IPhoneSimulator: + return "IPHONEOS_DEPLOYMENT_TARGET"; + + case cmMakefile::AppleSDK::WatchOS: + case cmMakefile::AppleSDK::WatchSimulator: + return "WATCHOS_DEPLOYMENT_TARGET"; + + case cmMakefile::AppleSDK::MacOS: + default: + return "MACOSX_DEPLOYMENT_TARGET"; + } +} diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index b758e97ff0..2269b258df 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -254,6 +254,8 @@ private: const std::string& configName, const cmGeneratorTarget* t) const; + static std::string GetDeploymentPlatform(const cmMakefile* mf); + void ComputeArchitectures(cmMakefile* mf); void ComputeObjectDirArch(cmMakefile* mf); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index c70a7ae5d1..5d6029ca42 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2244,25 +2244,38 @@ bool cmMakefile::PlatformIsx32() const return false; } -bool cmMakefile::PlatformIsAppleEmbedded() const +cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const { std::string sdkRoot; sdkRoot = this->GetSafeDefinition("CMAKE_OSX_SYSROOT"); sdkRoot = cmSystemTools::LowerCase(sdkRoot); - const std::string embedded[] = { - "appletvos", "appletvsimulator", "iphoneos", - "iphonesimulator", "watchos", "watchsimulator", + struct + { + std::string name; + AppleSDK sdk; + } const sdkDatabase[]{ + { "appletvos", AppleSDK::AppleTVOS }, + { "appletvsimulator", AppleSDK::AppleTVSimulator }, + { "iphoneos", AppleSDK::IPhoneOS }, + { "iphonesimulator", AppleSDK::IPhoneSimulator }, + { "watchos", AppleSDK::WatchOS }, + { "watchsimulator", AppleSDK::WatchSimulator }, }; - for (std::string const& i : embedded) { - if (sdkRoot.find(i) == 0 || - sdkRoot.find(std::string("/") + i) != std::string::npos) { - return true; + for (auto entry : sdkDatabase) { + if (sdkRoot.find(entry.name) == 0 || + sdkRoot.find(std::string("/") + entry.name) != std::string::npos) { + return entry.sdk; } } - return false; + return AppleSDK::MacOS; +} + +bool cmMakefile::PlatformIsAppleEmbedded() const +{ + return GetAppleSDKType() != AppleSDK::MacOS; } const char* cmMakefile::GetSONameFlag(const std::string& language) const diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index e1ec8edc08..40e8148768 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -439,6 +439,21 @@ public: /** Return whether the target platform is x32. */ bool PlatformIsx32() const; + /** Apple SDK Type */ + enum class AppleSDK + { + MacOS, + IPhoneOS, + IPhoneSimulator, + AppleTVOS, + AppleTVSimulator, + WatchOS, + WatchSimulator, + }; + + /** What SDK type points CMAKE_OSX_SYSROOT to? */ + AppleSDK GetAppleSDKType() const; + /** Return whether the target platform is Apple iOS. */ bool PlatformIsAppleEmbedded() const; diff --git a/Tests/RunCMake/XcodeProject/DeploymentTarget.c b/Tests/RunCMake/XcodeProject/DeploymentTarget.c new file mode 100644 index 0000000000..51af046216 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/DeploymentTarget.c @@ -0,0 +1,26 @@ +#include +#include + +#if TARGET_OS_OSX +#if __MAC_OS_X_VERSION_MIN_REQUIRED != __MAC_10_11 +#error macOS deployment version mismatch +#endif +#elif TARGET_OS_IOS +#if __IPHONE_OS_VERSION_MIN_REQUIRED != __IPHONE_9_1 +#error iOS deployment version mismatch +#endif +#elif TARGET_OS_WATCH +#if __WATCH_OS_VERSION_MIN_REQUIRED != __WATCHOS_2_0 +#error watchOS deployment version mismatch +#endif +#elif TARGET_OS_TV +#if __TV_OS_VERSION_MIN_REQUIRED != __TVOS_9_0 +#error tvOS deployment version mismatch +#endif +#else +#error unknown OS +#endif + +void foo() +{ +} diff --git a/Tests/RunCMake/XcodeProject/DeploymentTarget.cmake b/Tests/RunCMake/XcodeProject/DeploymentTarget.cmake new file mode 100644 index 0000000000..6281352e70 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/DeploymentTarget.cmake @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.10) +project(DeploymentTarget C) + +# using Xcode 7.1 SDK versions for deployment targets + +if(SDK MATCHES iphone) + set(CMAKE_OSX_SYSROOT ${SDK}) + set(CMAKE_OSX_ARCHITECTURES "armv7;x86_64") + set(CMAKE_OSX_DEPLOYMENT_TARGET "9.1") + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") +elseif(SDK MATCHES watch) + set(CMAKE_OSX_SYSROOT ${SDK}) + set(CMAKE_OSX_ARCHITECTURES "armv7k;i386") + set(CMAKE_OSX_DEPLOYMENT_TARGET "2.0") + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES") +elseif(SDK MATCHES appletv) + set(CMAKE_OSX_SYSROOT ${SDK}) + set(CMAKE_OSX_DEPLOYMENT_TARGET "9.0") + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES") +else() + set(CMAKE_OSX_SYSROOT ${SDK}) + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11") +endif() + +add_library(myFramework STATIC DeploymentTarget.c) +set_target_properties(myFramework PROPERTIES FRAMEWORK TRUE) diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 7eb624c0e8..1313cb5aa3 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -216,3 +216,21 @@ endfunction() if(NOT XCODE_VERSION VERSION_LESS 7) XcodeSchemaGeneration() endif() + +if(XCODE_VERSION VERSION_GREATER_EQUAL 8) + function(deploymeny_target_test SDK) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DeploymentTarget-${SDK}-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_OPTIONS "-DSDK=${SDK}") + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(DeploymentTarget) + run_cmake_command(DeploymentTarget-${SDK} ${CMAKE_COMMAND} --build .) + endfunction() + + foreach(SDK macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator) + deploymeny_target_test(${SDK}) + endforeach() +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake index 0b854d80a4..5d19ee8187 100644 --- a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake +++ b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake @@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.3) enable_language(C) +# due to lack of toolchain file it might point to running macOS version +unset(CMAKE_OSX_DEPLOYMENT_TARGET CACHE) + if(TEST_IOS) set(CMAKE_OSX_SYSROOT iphoneos) set(CMAKE_OSX_ARCHITECTURES "armv7") diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake index fc830b19e2..d7f3920211 100644 --- a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.3) project(IOSInstallCombined CXX) +# due to lack of toolchain file it might point to running macOS version +unset(CMAKE_OSX_DEPLOYMENT_TARGET CACHE) + set(CMAKE_OSX_SYSROOT iphoneos) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf") diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake index b47d3a5973..28ab883d7e 100644 --- a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.3) project(XcodeIOSInstallCombinedPrune CXX) +# due to lack of toolchain file it might point to running macOS version +unset(CMAKE_OSX_DEPLOYMENT_TARGET CACHE) + set(CMAKE_OSX_SYSROOT iphoneos) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf") diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake index 4b5e7ce360..5e7961a779 100644 --- a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.3) project(XcodeIOSInstallCombinedSingleArch CXX) +# due to lack of toolchain file it might point to running macOS version +unset(CMAKE_OSX_DEPLOYMENT_TARGET CACHE) + set(CMAKE_OSX_SYSROOT iphoneos) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")