summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2023-11-06 17:40:13 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2023-11-06 22:40:00 (GMT)
commit7d1924613858ec15d7d628306ea0e3156a1a6ddd (patch)
treea7a88f607d5275e973e3d9d31a306c61a0d7af4f
parent1e7489e3acac6aace240a62e4c38eefcf306a9e4 (diff)
downloadCMake-7d1924613858ec15d7d628306ea0e3156a1a6ddd.zip
CMake-7d1924613858ec15d7d628306ea0e3156a1a6ddd.tar.gz
CMake-7d1924613858ec15d7d628306ea0e3156a1a6ddd.tar.bz2
Xcode: Fix linking against .xcframework from static libraries
Issue: #21752
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx93
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target.cmake3
-rw-r--r--Tests/RunCMake/XcFramework/create-executable.cmake3
-rw-r--r--Tests/RunCMake/XcFramework/myconsuminglib/myconsuminglib.c6
4 files changed, 84 insertions, 21 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 5076e6c..cce45a3 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3854,18 +3854,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);
@@ -3972,13 +4038,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())));
@@ -3986,14 +4045,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;
diff --git a/Tests/RunCMake/XcFramework/create-executable-target.cmake b/Tests/RunCMake/XcFramework/create-executable-target.cmake
index 0cc356c..1bc091f 100644
--- a/Tests/RunCMake/XcFramework/create-executable-target.cmake
+++ b/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)
diff --git a/Tests/RunCMake/XcFramework/create-executable.cmake b/Tests/RunCMake/XcFramework/create-executable.cmake
index 6706b9f..eaad890 100644
--- a/Tests/RunCMake/XcFramework/create-executable.cmake
+++ b/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})
diff --git a/Tests/RunCMake/XcFramework/myconsuminglib/myconsuminglib.c b/Tests/RunCMake/XcFramework/myconsuminglib/myconsuminglib.c
new file mode 100644
index 0000000..83c0789
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/myconsuminglib/myconsuminglib.c
@@ -0,0 +1,6 @@
+#include <mylib/mylib.h>
+
+void myconsuminglib(void)
+{
+ mylib();
+}