Bläddra i källkod

Merge topic '17431-iphone-deployment-target'

4017bf40 Darwin: Emit deployment target that matches the SDK
8f4663ff Xcode: rename embedded SDK query function

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1447
Brad King 7 år sedan
förälder
incheckning
a3bba2a5ad

+ 11 - 0
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.

+ 6 - 4
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,

+ 4 - 1
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.

+ 15 - 0
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()

+ 7 - 4
Source/cmGeneratorTarget.cxx

@@ -1529,7 +1529,8 @@ std::string cmGeneratorTarget::GetAppBundleDirectory(
     ext = "app";
   }
   fpath += ext;
-  if (shouldAddContentLevel(level) && !this->Makefile->PlatformIsAppleIos()) {
+  if (shouldAddContentLevel(level) &&
+      !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Contents";
     if (shouldAddFullLevel(level)) {
       fpath += "/MacOS";
@@ -1559,7 +1560,8 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(
     }
   }
   fpath += ext;
-  if (shouldAddContentLevel(level) && !this->Makefile->PlatformIsAppleIos()) {
+  if (shouldAddContentLevel(level) &&
+      !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Contents";
     if (shouldAddFullLevel(level)) {
       fpath += "/MacOS";
@@ -1579,7 +1581,8 @@ std::string cmGeneratorTarget::GetFrameworkDirectory(
     ext = "framework";
   }
   fpath += ext;
-  if (shouldAddFullLevel(level) && !this->Makefile->PlatformIsAppleIos()) {
+  if (shouldAddFullLevel(level) &&
+      !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Versions/";
     fpath += this->GetFrameworkVersion();
   }
@@ -3004,7 +3007,7 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name, std::string& soName,
 
   if (this->IsFrameworkOnApple()) {
     realName = prefix;
-    if (!this->Makefile->PlatformIsAppleIos()) {
+    if (!this->Makefile->PlatformIsAppleEmbedded()) {
       realName += "Versions/";
       realName += this->GetFrameworkVersion();
       realName += "/";

+ 1 - 1
Source/cmGlobalGenerator.cxx

@@ -2609,7 +2609,7 @@ std::string cmGlobalGenerator::GenerateRuleFile(
 
 bool cmGlobalGenerator::ShouldStripResourcePath(cmMakefile* mf) const
 {
-  return mf->PlatformIsAppleIos();
+  return mf->PlatformIsAppleEmbedded();
 }
 
 std::string cmGlobalGenerator::GetSharedLibFlagsForLanguage(

+ 24 - 3
Source/cmGlobalXCodeGenerator.cxx

@@ -1172,7 +1172,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
           // dstPath in frameworks is relative to Versions/<version>
           ostr << keySources.first;
         } else if (keySources.first != "MacOS") {
-          if (gtgt->Target->GetMakefile()->PlatformIsAppleIos()) {
+          if (gtgt->Target->GetMakefile()->PlatformIsAppleEmbedded()) {
             ostr << keySources.first;
           } else {
             // dstPath in bundles is relative to Contents/MacOS
@@ -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()) {
@@ -3605,7 +3605,7 @@ bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
       "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
 
   if (!epnValue) {
-    return mf->PlatformIsAppleIos();
+    return mf->PlatformIsAppleEmbedded();
   }
 
   return cmSystemTools::IsOn(epnValue);
@@ -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";
+  }
+}

+ 2 - 0
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);
 

+ 2 - 2
Source/cmInstallTargetGenerator.cxx

@@ -167,7 +167,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
         to1 += ".";
         to1 += ext;
         to1 += "/";
-        if (!mf->PlatformIsAppleIos()) {
+        if (!mf->PlatformIsAppleEmbedded()) {
           to1 += "Contents/MacOS/";
         }
         to1 += targetName;
@@ -796,7 +796,7 @@ void cmInstallTargetGenerator::AddUniversalInstallRule(
 {
   cmMakefile const* mf = this->Target->Target->GetMakefile();
 
-  if (!mf->PlatformIsAppleIos() || !mf->IsOn("XCODE")) {
+  if (!mf->PlatformIsAppleEmbedded() || !mf->IsOn("XCODE")) {
     return;
   }
 

+ 22 - 9
Source/cmMakefile.cxx

@@ -2244,25 +2244,38 @@ bool cmMakefile::PlatformIsx32() const
   return false;
 }
 
-bool cmMakefile::PlatformIsAppleIos() 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

+ 16 - 1
Source/cmMakefile.h

@@ -439,8 +439,23 @@ 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 PlatformIsAppleIos() const;
+  bool PlatformIsAppleEmbedded() const;
 
   /** Retrieve soname flag for the specified language if supported */
   const char* GetSONameFlag(const std::string& language) const;

+ 2 - 2
Source/cmOSXBundleGenerator.cxx

@@ -82,7 +82,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
 
   // Configure the Info.plist file
   std::string plist = newoutpath;
-  if (!this->Makefile->PlatformIsAppleIos()) {
+  if (!this->Makefile->PlatformIsAppleEmbedded()) {
     // Put the Info.plist file into the Resources directory.
     this->MacContentFolders->insert("Resources");
     plist += "/Resources";
@@ -93,7 +93,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
                                                    plist.c_str());
 
   // Generate Versions directory only for MacOSX frameworks
-  if (this->Makefile->PlatformIsAppleIos()) {
+  if (this->Makefile->PlatformIsAppleEmbedded()) {
     return;
   }
 

+ 26 - 0
Tests/RunCMake/XcodeProject/DeploymentTarget.c

@@ -0,0 +1,26 @@
+#include <Availability.h>
+#include <TargetConditionals.h>
+
+#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()
+{
+}

+ 32 - 0
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)

+ 18 - 0
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()

+ 3 - 0
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")

+ 3 - 0
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")

+ 3 - 0
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")

+ 3 - 0
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")