Xcode: Fix linking against .xcframework from static libraries

Issue: #21752
This commit is contained in:
Kyle Edwards
2023-11-06 12:40:13 -05:00
parent 1e7489e3ac
commit 7d19246138
4 changed files with 84 additions and 21 deletions

View File

@@ -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;

View File

@@ -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)

View File

@@ -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})

View File

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