Ver Fonte

Xcode: add support for embedding dynamic libraries

Lucas SOLTIC há 4 anos atrás
pai
commit
6ef7bfbb64

+ 5 - 2
Source/cmGlobalXCodeGenerator.cxx

@@ -3809,7 +3809,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
   copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
                                     this->CreateString("0"));
   cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-  // Collect all embedded frameworks and add them to build phase
+  // Collect all embedded frameworks and dylibs and add them to build phase
   std::vector<std::string> relFiles = cmExpandedList(*files);
   for (std::string const& relFile : relFiles) {
     cmXCodeObject* buildFile{ nullptr };
@@ -3839,7 +3839,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
       } else {
         buildFile = it->second;
       }
-    } else if (cmSystemTools::IsPathToFramework(relFile)) {
+    } else if (cmSystemTools::IsPathToFramework(relFile) ||
+               cmSystemTools::IsPathToMacOSSharedLibrary(relFile)) {
       // This is a regular string path - create file reference
       auto it = this->EmbeddedLibRefs.find(relFile);
       if (it == this->EmbeddedLibRefs.end()) {
@@ -3905,6 +3906,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target)
 {
   static const auto dstSubfolderSpec = "10";
 
+  // Despite the name, by default Xcode uses "Embed Frameworks" build phase for
+  // both frameworks and dynamic libraries
   this->AddEmbeddedObjects(target, "Embed Frameworks",
                            "XCODE_EMBED_FRAMEWORKS", dstSubfolderSpec,
                            NoActionOnCopyByDefault);

+ 6 - 0
Source/cmSystemTools.cxx

@@ -1592,6 +1592,12 @@ bool cmSystemTools::IsPathToFramework(const std::string& path)
           cmHasLiteralSuffix(path, ".framework"));
 }
 
+bool cmSystemTools::IsPathToMacOSSharedLibrary(const std::string& path)
+{
+  return (cmSystemTools::FileIsFullPath(path) &&
+          cmHasLiteralSuffix(path, ".dylib"));
+}
+
 bool cmSystemTools::CreateTar(const std::string& outFileName,
                               const std::vector<std::string>& files,
                               cmTarCompression compressType, bool verbose,

+ 5 - 1
Source/cmSystemTools.h

@@ -102,7 +102,11 @@ public:
   }
 
   //! Return true if the path is a framework
-  static bool IsPathToFramework(const std::string& value);
+  static bool IsPathToFramework(const std::string& path);
+
+  //! Return true if the path is a macOS non-framework shared library (aka
+  //! .dylib)
+  static bool IsPathToMacOSSharedLibrary(const std::string& path);
 
   static bool DoesFileExistWithExtensions(
     const std::string& name, const std::vector<std::string>& sourceExts);

+ 1 - 1
Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOff.cmake

@@ -1,7 +1,7 @@
 add_executable(app MACOSX_BUNDLE main.m)
 
 set_target_properties(app PROPERTIES
-  XCODE_EMBED_FRAMEWORKS "${EXTERNAL_FWK}"
+  XCODE_EMBED_FRAMEWORKS "${EXTERNAL_DEPENDENCY}"
   XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY OFF
   XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY OFF
 )

+ 2 - 2
Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnNoSubdir-build-check.cmake

@@ -1,3 +1,3 @@
-if(NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/Debug/app.app/Contents/Frameworks/sharedFrameworkExt.framework)
-  set(RunCMake_TEST_FAILED "Framework was not embedded at the expected location")
+if(NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/Debug/app.app/Contents/Frameworks/${EXTERNAL_DEPENDENCY_NAME})
+  set(RunCMake_TEST_FAILED "${EXTERNAL_DEPENDENCY_NAME} was not embedded at the expected location")
 endif()

+ 1 - 1
Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnNoSubdir.cmake

@@ -1,7 +1,7 @@
 add_executable(app MACOSX_BUNDLE main.m)
 
 set_target_properties(app PROPERTIES
-  XCODE_EMBED_FRAMEWORKS "${EXTERNAL_FWK}"
+  XCODE_EMBED_FRAMEWORKS "${EXTERNAL_DEPENDENCY}"
   XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY ON
   XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
 )

+ 2 - 2
Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnWithSubdir-build-check.cmake

@@ -1,3 +1,3 @@
-if(NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/Debug/app.app/Contents/Frameworks/subdir/sharedFrameworkExt.framework)
-  set(RunCMake_TEST_FAILED "Framework was not embedded at the expected location")
+if(NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/Debug/app.app/Contents/Frameworks/subdir/${EXTERNAL_DEPENDENCY_NAME})
+  set(RunCMake_TEST_FAILED "${EXTERNAL_DEPENDENCY_NAME} was not embedded at the expected location")
 endif()

+ 1 - 1
Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnWithSubdir.cmake

@@ -1,7 +1,7 @@
 add_executable(app MACOSX_BUNDLE main.m)
 
 set_target_properties(app PROPERTIES
-  XCODE_EMBED_FRAMEWORKS "${EXTERNAL_FWK}"
+  XCODE_EMBED_FRAMEWORKS "${EXTERNAL_DEPENDENCY}"
   XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY ON
   XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
   XCODE_EMBED_FRAMEWORKS_PATH "subdir"

+ 2 - 0
Tests/RunCMake/XcodeProject-Embed/ExternalFramework.cmake → Tests/RunCMake/XcodeProject-Embed/ExternalDependencies.cmake

@@ -1,2 +1,4 @@
 add_library(sharedFrameworkExt SHARED func.m)
 set_target_properties(sharedFrameworkExt PROPERTIES FRAMEWORK TRUE)
+
+add_library(sharedDylibExt SHARED func.m)

+ 19 - 17
Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake

@@ -1,47 +1,49 @@
 include(RunCMake)
 
-# Build a framework that the other tests will use and treat as external.
+# Build dependencies that the other tests will use and treat as external.
 # Always build in the Debug configuration so that the path to the framework
 # is predictable.
-function(ExternalFramework)
+function(ExternalDependencies)
   set(RunCMake_TEST_NO_CLEAN 1)
-  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExternalFramework-build)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExternalDependencies-build)
   set(externalFramework ${RunCMake_TEST_BINARY_DIR}/Debug/sharedFrameworkExt.framework PARENT_SCOPE)
+  set(externalDylib ${RunCMake_TEST_BINARY_DIR}/Debug/libsharedDylibExt.dylib PARENT_SCOPE)
 
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
 
-  run_cmake(ExternalFramework)
-  run_cmake_command(ExternalFramework-build
+  run_cmake(ExternalDependencies)
+  run_cmake_command(ExternalDependencies-build
     ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR}
                      --config Debug
-                     --target sharedFrameworkExt
+                     --target sharedFrameworkExt sharedDylibExt
   )
 endfunction()
-ExternalFramework()
+ExternalDependencies()
 
-set(RunCMake_TEST_OPTIONS -DEXTERNAL_FWK=${externalFramework})
-
-run_cmake(EmbedFrameworksFlagsOff)
-
-function(TestFlagsOn testName)
+function(TestFlagsOn testName dependencyName)
   set(RunCMake_TEST_NO_CLEAN 1)
-  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-build)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-${dependencyName}-build)
 
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
 
   run_cmake(${testName})
-  run_cmake_command(${testName}-build
+  run_cmake_command(${testName}-${dependencyName}-build
     ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR}
                      --config Debug
                      --target app
   )
 endfunction()
 
-TestFlagsOn(EmbedFrameworksFlagsOnNoSubdir)
-TestFlagsOn(EmbedFrameworksFlagsOnWithSubdir)
-
+foreach(dependency ${externalFramework} ${externalDylib})
+  cmake_path(GET dependency FILENAME dependencyName)
+  set(RunCMake_TEST_OPTIONS -DEXTERNAL_DEPENDENCY=${dependency} -DEXTERNAL_DEPENDENCY_NAME=${dependencyName})
+  run_cmake(EmbedFrameworksFlagsOff)
+  TestFlagsOn(EmbedFrameworksFlagsOnNoSubdir ${dependencyName})
+  TestFlagsOn(EmbedFrameworksFlagsOnWithSubdir ${dependencyName})
+endforeach()
+unset(RunCMake_TEST_OPTIONS)
 
 function(TestAppExtension platform)
   set(testName EmbedAppExtensions-${platform})