summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2022-11-22 16:32:59 +0100
committerMarc Chevrier <marc.chevrier@gmail.com>2022-11-22 16:44:45 +0100
commit61075d2d7b0a77f53bc9a0d4c6644ab338f27886 (patch)
tree6d0130aaa0ee0f92877d4bd7895cfd67eeb92daa /Source
parent3d1f91a245fec409b93c4f059ca50efcff9af578 (diff)
downloadcmake-61075d2d7b0a77f53bc9a0d4c6644ab338f27886.tar.gz
XCode: ensure LINK_LIBRARY genex is usable with XCODE_LINK_BUILD_PHASE_MODE
Fixes: #24176
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx74
1 files changed, 53 insertions, 21 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 065802166b..116e510c6f 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3581,28 +3581,37 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
libItem.IsPath == cmComputeLinkInformation::ItemIsPath::Yes &&
forceLinkPhase))) {
std::string libName;
- bool canUseLinkPhase = true;
- if (libItem.Target) {
- if (libItem.Target->GetType() == cmStateEnums::UNKNOWN_LIBRARY) {
- canUseLinkPhase = canUseLinkPhase && forceLinkPhase;
+ bool canUseLinkPhase = !libItem.HasFeature() ||
+ libItem.GetFeatureName() == "__CMAKE_LINK_FRAMEWORK"_s ||
+ libItem.GetFeatureName() == "FRAMEWORK"_s ||
+ libItem.GetFeatureName() == "WEAK_FRAMEWORK"_s ||
+ libItem.GetFeatureName() == "WEAK_LIBRARY"_s;
+ if (canUseLinkPhase) {
+ if (libItem.Target) {
+ if (libItem.Target->GetType() == cmStateEnums::UNKNOWN_LIBRARY) {
+ canUseLinkPhase = canUseLinkPhase && forceLinkPhase;
+ } else {
+ // If a library target uses custom build output directory Xcode
+ // won't pick it up so we have to resort back to linker flags,
+ // but that's OK as long as the custom output dir is absolute
+ // path.
+ for (auto const& libConfigName :
+ this->CurrentConfigurationTypes) {
+ canUseLinkPhase = canUseLinkPhase &&
+ libItem.Target->UsesDefaultOutputDir(
+ libConfigName, cmStateEnums::RuntimeBinaryArtifact);
+ }
+ }
+ libName = libItem.Target->GetName();
} else {
- // If a library target uses custom build output directory Xcode
- // won't pick it up so we have to resort back to linker flags, but
- // that's OK as long as the custom output dir is absolute path.
- for (auto const& libConfigName : this->CurrentConfigurationTypes) {
- canUseLinkPhase = canUseLinkPhase &&
- libItem.Target->UsesDefaultOutputDir(
- libConfigName, cmStateEnums::RuntimeBinaryArtifact);
+ libName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+ // We don't want all the possible files here, just standard
+ // libraries
+ const auto libExt = cmSystemTools::GetFilenameExtension(libName);
+ if (!IsLinkPhaseLibraryExtension(libExt)) {
+ canUseLinkPhase = false;
}
}
- libName = libItem.Target->GetName();
- } else {
- libName = cmSystemTools::GetFilenameName(libItem.Value.Value);
- // We don't want all the possible files here, just standard libraries
- const auto libExt = cmSystemTools::GetFilenameExtension(libName);
- if (!IsLinkPhaseLibraryExtension(libExt)) {
- canUseLinkPhase = false;
- }
}
if (canUseLinkPhase) {
// Add unique configuration name to target-config map for later
@@ -3658,6 +3667,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
// separately.
std::vector<std::string> linkSearchPaths;
std::vector<std::string> frameworkSearchPaths;
+ std::set<std::pair<cmXCodeObject*, std::string>> linkBuildFileSet;
for (auto const& libItem : linkPhaseTargetVector) {
// Add target output directory as a library search path
std::string linkDir;
@@ -3760,8 +3770,30 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
cmSystemTools::Error("Missing files of PBXFrameworksBuildPhase");
continue;
}
- if (buildFile && !buildFiles->HasObject(buildFile)) {
- buildFiles->AddObject(buildFile);
+ if (buildFile) {
+ if (cmHasPrefix(libItem->GetFeatureName(), "WEAK_"_s)) {
+ auto key = std::make_pair(buildFile->GetAttribute("fileRef"),
+ libItem->GetFeatureName());
+ if (linkBuildFileSet.find(key) != linkBuildFileSet.end()) {
+ continue;
+ }
+ linkBuildFileSet.insert(key);
+
+ cmXCodeObject* buildObject =
+ this->CreateObject(cmXCodeObject::PBXBuildFile);
+ buildObject->AddAttribute("fileRef", key.first);
+ // Add settings, ATTRIBUTES, Weak flag
+ cmXCodeObject* settings =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ attrs->AddObject(this->CreateString("Weak"));
+ settings->AddAttribute("ATTRIBUTES", attrs);
+ buildObject->AddAttribute("settings", settings);
+ buildFile = buildObject;
+ }
+ if (!buildFiles->HasObject(buildFile)) {
+ buildFiles->AddObject(buildFile);
+ }
}
}