cmGeneratorTarget: Clarify CMP0022 logic in ComputeLinkInterfaceLibraries

Follow up commit 1d709ea2f5 (cmGeneratorTarget: Propagate backtraces
from INTERFACE_LINK_LIBRARIES, 2021-12-15), which made the logic a bit
more complicated due to having backtraces for CMP0022 NEW behavior.
This commit is contained in:
Brad King 2022-01-05 15:22:23 -05:00
parent f3e9e03fe0
commit d75ab9d066

View File

@ -7156,59 +7156,64 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// An explicit list of interface libraries may be set for shared // An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols. // libraries and executables that export symbols.
cmValue explicitLibraries = nullptr; bool haveExplicitLibraries = false;
std::string linkIfaceProp; cmValue explicitLibrariesCMP0022OLD;
std::string linkIfacePropCMP0022OLD;
bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD && bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
this->GetPolicyStatusCMP0022() != cmPolicies::WARN); this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
if (cmp0022NEW) { if (cmp0022NEW) {
// CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; haveExplicitLibraries = !this->Target->GetLinkInterfaceEntries().empty();
explicitLibraries = this->GetProperty(linkIfaceProp); } else {
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
// CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
// shared lib or executable. // shared lib or executable.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
// Lookup the per-configuration property.
linkIfacePropCMP0022OLD = cmStrCat("LINK_INTERFACE_LIBRARIES", suffix);
explicitLibrariesCMP0022OLD = this->GetProperty(linkIfacePropCMP0022OLD);
// Lookup the per-configuration property. // If not set, try the generic property.
linkIfaceProp = cmStrCat("LINK_INTERFACE_LIBRARIES", suffix); if (!explicitLibrariesCMP0022OLD) {
explicitLibraries = this->GetProperty(linkIfaceProp); linkIfacePropCMP0022OLD = "LINK_INTERFACE_LIBRARIES";
explicitLibrariesCMP0022OLD =
// If not set, try the generic property. this->GetProperty(linkIfacePropCMP0022OLD);
if (!explicitLibraries) { }
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
explicitLibraries = this->GetProperty(linkIfaceProp);
} }
}
if (explicitLibraries && if (explicitLibrariesCMP0022OLD &&
this->GetPolicyStatusCMP0022() == cmPolicies::WARN && this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
!this->PolicyWarnedCMP0022) { !this->PolicyWarnedCMP0022) {
// Compare the explicitly set old link interface properties to the // Compare the explicitly set old link interface properties to the
// preferred new link interface property one and warn if different. // preferred new link interface property one and warn if different.
cmValue newExplicitLibraries = cmValue newExplicitLibraries =
this->GetProperty("INTERFACE_LINK_LIBRARIES"); this->GetProperty("INTERFACE_LINK_LIBRARIES");
if (newExplicitLibraries && if (newExplicitLibraries &&
(*newExplicitLibraries != *explicitLibraries)) { (*newExplicitLibraries != *explicitLibrariesCMP0022OLD)) {
std::ostringstream w; std::ostringstream w;
/* clang-format off */ /* clang-format off */
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
"Target \"" << this->GetName() << "\" has an " "Target \"" << this->GetName() << "\" has an "
"INTERFACE_LINK_LIBRARIES property which differs from its " << "INTERFACE_LINK_LIBRARIES property which differs from its " <<
linkIfaceProp << " properties." linkIfacePropCMP0022OLD << " properties."
"\n" "\n"
"INTERFACE_LINK_LIBRARIES:\n" "INTERFACE_LINK_LIBRARIES:\n"
" " << *newExplicitLibraries << "\n" << " " << *newExplicitLibraries << "\n" <<
linkIfaceProp << ":\n" linkIfacePropCMP0022OLD << ":\n"
" " << *explicitLibraries << "\n"; " " << *explicitLibrariesCMP0022OLD << "\n";
/* clang-format on */ /* clang-format on */
this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING,
this->PolicyWarnedCMP0022 = true; w.str());
this->PolicyWarnedCMP0022 = true;
}
} }
haveExplicitLibraries = static_cast<bool>(explicitLibrariesCMP0022OLD);
} }
// There is no implicit link interface for executables or modules // There is no implicit link interface for executables or modules
// so if none was explicitly set then there is no link interface. // so if none was explicitly set then there is no link interface.
if (!explicitLibraries && if (!haveExplicitLibraries &&
(this->GetType() == cmStateEnums::EXECUTABLE || (this->GetType() == cmStateEnums::EXECUTABLE ||
(this->GetType() == cmStateEnums::MODULE_LIBRARY))) { (this->GetType() == cmStateEnums::MODULE_LIBRARY))) {
return; return;
@ -7218,22 +7223,20 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// If CMP0022 is NEW then the plain tll signature sets the // If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES property. Even if the project // INTERFACE_LINK_LIBRARIES property. Even if the project
// clears it, the link interface is still explicit. // clears it, the link interface is still explicit.
iface.Explicit = cmp0022NEW || explicitLibraries; iface.Explicit = cmp0022NEW || explicitLibrariesCMP0022OLD;
if (explicitLibraries) { if (cmp0022NEW) {
// The interface libraries have been explicitly set. // The interface libraries are specified by INTERFACE_LINK_LIBRARIES.
if (cmp0022NEW) { // Use its special representation directly to get backtraces.
// The explicitLibraries came from INTERFACE_LINK_LIBRARIES. this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES,
// Use its special representation directly to get backtraces. this->Target->GetLinkInterfaceEntries(), config,
this->ExpandLinkItems(linkIfaceProp, headTarget, interfaceFor, iface);
this->Target->GetLinkInterfaceEntries(), config, } else if (explicitLibrariesCMP0022OLD) {
headTarget, interfaceFor, iface); // The interface libraries have been explicitly set in pre-CMP0022 style.
} else { std::vector<BT<std::string>> entries;
std::vector<BT<std::string>> entries; entries.emplace_back(*explicitLibrariesCMP0022OLD);
entries.emplace_back(*explicitLibraries); this->ExpandLinkItems(linkIfacePropCMP0022OLD, cmMakeRange(entries),
this->ExpandLinkItems(linkIfaceProp, cmMakeRange(entries), config, config, headTarget, interfaceFor, iface);
headTarget, interfaceFor, iface);
}
} }
// If the link interface is explicit, do not fall back to the link impl. // If the link interface is explicit, do not fall back to the link impl.