Browse Source

Merge topic '16253-xcode-effective-platform-name'

10c9c73d Xcode: Control emission of EFFECTIVE_PLATFORM_NAME
Brad King 9 years ago
parent
commit
6122fc54a9

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -44,6 +44,7 @@ Properties of Global Scope
    /prop_gbl/TARGET_MESSAGES
    /prop_gbl/TARGET_SUPPORTS_SHARED_LIBS
    /prop_gbl/USE_FOLDERS
+   /prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
 
 .. _`Directory Properties`:
 

+ 24 - 0
Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst

@@ -0,0 +1,24 @@
+XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
+----------------------------------
+
+Control emission of ``EFFECTIVE_PLATFORM_NAME`` by the Xcode generator.
+
+It is required for building the same target with multiple SDKs. A
+common use case is the parallel use of ``iphoneos`` and
+``iphonesimulator`` SDKs.
+
+Three different states possible that control when the Xcode generator
+emits the ``EFFECTIVE_PLATFORM_NAME`` variable:
+
+- If set to ``ON`` it will always be emitted
+- If set to ``OFF`` it will never be emitted
+- If unset (the default) it will only be emitted when the project was
+  configured for an embedded Xcode SDK like iOS, tvOS, watchOS or any
+  of the simulators.
+
+.. note::
+
+  When this behavior is enable for generated Xcode projects, the
+  ``EFFECTIVE_PLATFORM_NAME`` variable will leak into
+  :manual:`Generator expressions <cmake-generator-expressions(7)>`
+  like ``TARGET_FILE`` and will render those mostly unusable.

+ 8 - 0
Help/release/dev/xcode-effective-platform-name.rst

@@ -0,0 +1,8 @@
+xcode-effective-platform-name
+-----------------------------
+
+* The Xcode generator can now control emission of the
+  ``EFFECTIVE_PLATFORM_NAME`` variable through the
+  :prop_gbl:`XCODE_EMIT_EFFECTIVE_PLATFORM_NAME` global property.
+  This is useful when building with multiple SDKs like macosx and
+  iphoneos in parallel.

+ 3 - 2
Source/cmGeneratorTarget.cxx

@@ -4419,9 +4419,10 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
 
   // The generator may add the configuration's subdirectory.
   if (!conf.empty()) {
-    bool iosPlatform = this->Makefile->PlatformIsAppleIos();
+    bool useEPN =
+      this->GlobalGenerator->UseEffectivePlatformName(this->Makefile);
     std::string suffix =
-      usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
+      usesDefaultOutputDir && useEPN ? "${EFFECTIVE_PLATFORM_NAME}" : "";
     this->LocalGenerator->GetGlobalGenerator()->AppendDirectoryForConfig(
       "/", conf, suffix, out);
   }

+ 2 - 2
Source/cmGlobalGenerator.cxx

@@ -2342,8 +2342,8 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
     singleLine.push_back(cmd);
     if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
       std::string cfgArg = "-DBUILD_TYPE=";
-      bool iosPlatform = mf->PlatformIsAppleIos();
-      if (iosPlatform) {
+      bool useEPN = this->UseEffectivePlatformName(mf);
+      if (useEPN) {
         cfgArg += "$(CONFIGURATION)";
         singleLine.push_back(cfgArg);
         cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)";

+ 4 - 0
Source/cmGlobalGenerator.h

@@ -333,6 +333,10 @@ public:
 
   virtual bool UseFolderProperty() const;
 
+  /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is
+      relevant for mixed macOS and iOS builds. */
+  virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }
+
   std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
 
   /** Generate an <output>.rule file path for a given command output.  */

+ 14 - 0
Source/cmGlobalXCodeGenerator.cxx

@@ -22,6 +22,7 @@
 #include "cmOutputConverter.h"
 #include "cmSourceFile.h"
 #include "cmSourceGroup.h"
+#include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
@@ -3544,6 +3545,19 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const
   return true;
 }
 
+bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
+{
+  const char* epnValue =
+    this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+      "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
+
+  if (!epnValue) {
+    return mf->PlatformIsAppleIos();
+  }
+
+  return cmSystemTools::IsOn(epnValue);
+}
+
 void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory(
   cmGeneratorTarget* gt) const
 {

+ 2 - 0
Source/cmGlobalXCodeGenerator.h

@@ -86,6 +86,8 @@ public:
       i.e. "Can I build Debug and Release in the same tree?" */
   bool IsMultiConfig() const CM_OVERRIDE;
 
+  bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE;
+
   bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) CM_OVERRIDE;
   void AppendFlag(std::string& flags, std::string const& flag);
 

+ 21 - 0
Tests/RunCMake/XcodeProject/RunCMakeTest.cmake

@@ -166,3 +166,24 @@ if(NOT XCODE_VERSION VERSION_LESS 6)
   unset(RunCMake_TEST_NO_CLEAN)
   unset(RunCMake_TEST_OPTIONS)
 endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 5)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeMultiplatform-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(XcodeMultiplatform)
+
+  # build ios before macos
+  run_cmake_command(XcodeMultiplatform-iphonesimulator-build ${CMAKE_COMMAND} --build . -- -sdk iphonesimulator)
+  run_cmake_command(XcodeMultiplatform-iphonesimulator-install ${CMAKE_COMMAND} --build . --target install -- -sdk iphonesimulator DESTDIR=${RunCMake_TEST_BINARY_DIR}/_install_iphonesimulator)
+
+  run_cmake_command(XcodeMultiplatform-macosx-build ${CMAKE_COMMAND} --build . -- -sdk macosx)
+  run_cmake_command(XcodeMultiplatform-macosx-install ${CMAKE_COMMAND} --build . --target install -- -sdk macosx DESTDIR=${RunCMake_TEST_BINARY_DIR}/_install_macosx)
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_OPTIONS)
+endif()

+ 14 - 0
Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.3)
+enable_language(CXX)
+
+set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME ON)
+
+set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx iphonesimulator")
+set(CMAKE_MACOSX_BUNDLE true)
+
+add_library(library STATIC foo.cpp)
+
+add_executable(main main.cpp)
+target_link_libraries(main library)
+
+install(TARGETS library ARCHIVE DESTINATION lib)