1
0
Эх сурвалжийг харах

Merge topic 'static-library-link-xcframework'

7d19246138 Xcode: Fix linking against .xcframework from static libraries

Acked-by: Kitware Robot <[email protected]>
Merge-request: !8949
Brad King 1 жил өмнө
parent
commit
49df33c342

+ 72 - 21
Source/cmGlobalXCodeGenerator.cxx

@@ -3857,18 +3857,84 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
         configName);
     }
 
-    // Skip link information for object libraries.
-    if (gt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
-        gt->GetType() == cmStateEnums::STATIC_LIBRARY) {
-      continue;
-    }
-
     // Compute the link library and directory information.
     cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
     if (!cli) {
       continue;
     }
 
+    // add .xcframework include paths
+    {
+      // Keep track of framework search paths we've already added or that are
+      // part of the set of implicit search paths. We don't want to repeat
+      // them and we also need to avoid hard-coding any SDK-specific paths.
+      // This is essential for getting device-and-simulator builds to work,
+      // otherwise we end up hard-coding a path to the wrong SDK for
+      // SDK-provided frameworks that are added by their full path.
+      std::set<std::string> emitted(cli->GetFrameworkPathsEmitted());
+      BuildObjectListOrString includePaths(this, true);
+      BuildObjectListOrString fwSearchPaths(this, true);
+      for (auto const& libItem : configItemMap[configName]) {
+        auto const& libName = *libItem;
+        if (libName.IsPath == cmComputeLinkInformation::ItemIsPath::Yes) {
+          auto cleanPath = libName.Value.Value;
+          if (cmSystemTools::FileIsFullPath(cleanPath)) {
+            cleanPath = cmSystemTools::CollapseFullPath(cleanPath);
+          }
+          bool isXcFramework =
+            cmHasSuffix(libName.GetFeatureName(), "XCFRAMEWORK"_s);
+          if (isXcFramework) {
+            auto plist = cmParseXcFrameworkPlist(
+              cleanPath, *this->Makefiles.front(), libName.Value.Backtrace);
+            if (!plist) {
+              return;
+            }
+            if (auto const* library = plist->SelectSuitableLibrary(
+                  *this->Makefiles.front(), libName.Value.Backtrace)) {
+              auto libraryPath =
+                cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
+                         library->LibraryPath);
+              if (auto const fwDescriptor = this->SplitFrameworkPath(
+                    libraryPath,
+                    cmGlobalGenerator::FrameworkFormat::Relaxed)) {
+                if (!fwDescriptor->Directory.empty() &&
+                    emitted.insert(fwDescriptor->Directory).second) {
+                  // This is a search path we had not added before and it
+                  // isn't an implicit search path, so we need it
+                  fwSearchPaths.Add(
+                    this->XCodeEscapePath(fwDescriptor->Directory));
+                }
+              } else {
+                if (!library->HeadersPath.empty()) {
+                  includePaths.Add(this->XCodeEscapePath(
+                    cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
+                             library->HeadersPath)));
+                }
+              }
+            } else {
+              return;
+            }
+          }
+        }
+      }
+      if (!includePaths.IsEmpty()) {
+        this->AppendBuildSettingAttribute(target, "HEADER_SEARCH_PATHS",
+                                          includePaths.CreateList(),
+                                          configName);
+      }
+      if (!fwSearchPaths.IsEmpty()) {
+        this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
+                                          fwSearchPaths.CreateList(),
+                                          configName);
+      }
+    }
+
+    // Skip link information for object libraries.
+    if (gt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
+        gt->GetType() == cmStateEnums::STATIC_LIBRARY) {
+      continue;
+    }
+
     // Add dependencies directly on library files.
     for (auto const& libDep : cli->GetDepends()) {
       target->AddDependLibrary(configName, libDep);
@@ -3975,13 +4041,6 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
               if (auto const fwDescriptor = this->SplitFrameworkPath(
                     libraryPath,
                     cmGlobalGenerator::FrameworkFormat::Relaxed)) {
-                if (!fwDescriptor->Directory.empty() &&
-                    emitted.insert(fwDescriptor->Directory).second) {
-                  // This is a search path we had not added before and it
-                  // isn't an implicit search path, so we need it
-                  fwSearchPaths.Add(
-                    this->XCodeEscapePath(fwDescriptor->Directory));
-                }
                 libPaths.Add(cmStrCat(
                   "-framework ",
                   this->XCodeEscapePath(fwDescriptor->GetLinkName())));
@@ -3989,14 +4048,6 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
                 libPaths.Add(
                   libName.GetFormattedItem(this->XCodeEscapePath(libraryPath))
                     .Value);
-                if (!library->HeadersPath.empty()) {
-                  this->AppendBuildSettingAttribute(
-                    target, "HEADER_SEARCH_PATHS",
-                    this->CreateString(this->XCodeEscapePath(
-                      cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
-                               library->HeadersPath))),
-                    configName);
-                }
               }
             } else {
               return;

+ 3 - 0
Tests/RunCMake/XcFramework/create-executable-target.cmake

@@ -19,3 +19,6 @@ set_property(TARGET mylib PROPERTY IMPORTED_LOCATION ${MYLIB_LIBRARY})
 
 add_executable(myexe myexe/myexe.c)
 target_link_libraries(myexe PRIVATE mylib)
+
+add_library(myconsuminglib STATIC myconsuminglib/myconsuminglib.c)
+target_link_libraries(myconsuminglib PRIVATE mylib)

+ 3 - 0
Tests/RunCMake/XcFramework/create-executable.cmake

@@ -16,3 +16,6 @@ endif()
 
 add_executable(myexe myexe/myexe.c)
 target_link_libraries(myexe PRIVATE ${MYLIB_LIBRARY})
+
+add_library(myconsuminglib STATIC myconsuminglib/myconsuminglib.c)
+target_link_libraries(myconsuminglib PRIVATE ${MYLIB_LIBRARY})

+ 6 - 0
Tests/RunCMake/XcFramework/myconsuminglib/myconsuminglib.c

@@ -0,0 +1,6 @@
+#include <mylib/mylib.h>
+
+void myconsuminglib(void)
+{
+  mylib();
+}