cmGeneratorTarget: Propagate backtraces from INTERFACE_LINK_LIBRARIES

This commit is contained in:
Brad King
2021-12-15 10:51:34 -05:00
parent a84a62e0a7
commit 1d709ea2f5
5 changed files with 77 additions and 49 deletions

View File

@@ -6553,14 +6553,13 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
} }
void cmGeneratorTarget::ExpandLinkItems(std::string const& prop, void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
std::string const& value, cmBTStringRange entries,
std::string const& config, std::string const& config,
cmGeneratorTarget const* headTarget, cmGeneratorTarget const* headTarget,
LinkInterfaceFor interfaceFor, LinkInterfaceFor interfaceFor,
cmLinkInterface& iface) const cmLinkInterface& iface) const
{ {
// Keep this logic in sync with ComputeLinkImplementationLibraries. // Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr); cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
// The $<LINK_ONLY> expression may be in a link interface to specify // The $<LINK_ONLY> expression may be in a link interface to specify
// private link dependencies that are otherwise excluded from usage // private link dependencies that are otherwise excluded from usage
@@ -6568,39 +6567,46 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
if (interfaceFor == LinkInterfaceFor::Usage) { if (interfaceFor == LinkInterfaceFor::Usage) {
dagChecker.SetTransitivePropertiesOnly(); dagChecker.SetTransitivePropertiesOnly();
} }
std::vector<std::string> libs;
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
cge->SetEvaluateForBuildsystem(true);
cmExpandList(cge->Evaluate(this->LocalGenerator, config, headTarget,
&dagChecker, this, headTarget->LinkerLanguage),
libs);
cmMakefile const* mf = this->LocalGenerator->GetMakefile(); cmMakefile const* mf = this->LocalGenerator->GetMakefile();
LookupLinkItemScope scope{ this->LocalGenerator }; LookupLinkItemScope scope{ this->LocalGenerator };
for (std::string const& lib : libs) { for (BT<std::string> const& entry : entries) {
if (cm::optional<cmLinkItem> maybeItem = cmGeneratorExpression ge(entry.Backtrace);
this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) { std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
cmLinkItem item = std::move(*maybeItem); cge->SetEvaluateForBuildsystem(true);
std::vector<std::string> libs = cmExpandedList(
cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker,
this, headTarget->LinkerLanguage));
for (std::string const& lib : libs) {
if (cm::optional<cmLinkItem> maybeItem =
this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) {
cmLinkItem item = std::move(*maybeItem);
if (!item.Target) { if (!item.Target) {
// Report explicitly linked object files separately. // Report explicitly linked object files separately.
std::string const& maybeObj = item.AsStr(); std::string const& maybeObj = item.AsStr();
if (cmSystemTools::FileIsFullPath(maybeObj)) { if (cmSystemTools::FileIsFullPath(maybeObj)) {
cmSourceFile const* sf = cmSourceFile const* sf =
mf->GetSource(maybeObj, cmSourceFileLocationKind::Known); mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
iface.Objects.emplace_back(std::move(item)); iface.Objects.emplace_back(std::move(item));
continue; continue;
}
} }
} }
}
iface.Libraries.emplace_back(std::move(item)); iface.Libraries.emplace_back(std::move(item));
}
}
if (cge->GetHadHeadSensitiveCondition()) {
iface.HadHeadSensitiveCondition = true;
}
if (cge->GetHadContextSensitiveCondition()) {
iface.HadContextSensitiveCondition = true;
}
if (cge->GetHadLinkLanguageSensitiveCondition()) {
iface.HadLinkLanguageSensitiveCondition = true;
} }
} }
iface.HadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
iface.HadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
iface.HadLinkLanguageSensitiveCondition =
cge->GetHadLinkLanguageSensitiveCondition();
} }
cmLinkInterface const* cmGeneratorTarget::GetLinkInterface( cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
@@ -7105,8 +7111,18 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
if (explicitLibraries) { if (explicitLibraries) {
// The interface libraries have been explicitly set. // The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config, if (cmp0022NEW) {
headTarget, interfaceFor, iface); // The explicitLibraries came from INTERFACE_LINK_LIBRARIES.
// Use its special representation directly to get backtraces.
this->ExpandLinkItems(linkIfaceProp,
this->Target->GetLinkInterfaceEntries(), config,
headTarget, interfaceFor, iface);
} else {
std::vector<BT<std::string>> entries;
entries.emplace_back(*explicitLibraries);
this->ExpandLinkItems(linkIfaceProp, cmMakeRange(entries), config,
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.
@@ -7126,7 +7142,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
cmLinkInterface ifaceNew; cmLinkInterface ifaceNew;
static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
if (cmValue newExplicitLibraries = this->GetProperty(newProp)) { if (cmValue newExplicitLibraries = this->GetProperty(newProp)) {
this->ExpandLinkItems(newProp, *newExplicitLibraries, config, std::vector<BT<std::string>> entries;
entries.emplace_back(*newExplicitLibraries);
this->ExpandLinkItems(linkIfaceProp, cmMakeRange(entries), config,
headTarget, interfaceFor, ifaceNew); headTarget, interfaceFor, ifaceNew);
} }
if (ifaceNew.Libraries != iface.Libraries) { if (ifaceNew.Libraries != iface.Libraries) {
@@ -7268,8 +7286,8 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
iface.AllDone = true; iface.AllDone = true;
iface.Multiplicity = info->Multiplicity; iface.Multiplicity = info->Multiplicity;
cmExpandList(info->Languages, iface.Languages); cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, this->ExpandLinkItems(info->LibrariesProp, cmMakeRange(info->Libraries),
headTarget, interfaceFor, iface); config, headTarget, interfaceFor, iface);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps); std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
LookupLinkItemScope scope{ this->LocalGenerator }; LookupLinkItemScope scope{ this->LocalGenerator };
for (std::string const& dep : deps) { for (std::string const& dep : deps) {
@@ -7340,23 +7358,26 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the link interface. // Get the link interface.
{ {
std::string linkProp = "INTERFACE_LINK_LIBRARIES"; // Use the INTERFACE_LINK_LIBRARIES special representation directly
cmValue propertyLibs = this->GetProperty(linkProp); // to get backtraces.
cmBTStringRange entries = this->Target->GetLinkInterfaceEntries();
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) { if (!entries.empty()) {
if (!propertyLibs) { info.LibrariesProp = "INTERFACE_LINK_LIBRARIES";
linkProp = cmStrCat("IMPORTED_LINK_INTERFACE_LIBRARIES", suffix); for (BT<std::string> const& entry : entries) {
propertyLibs = this->GetProperty(linkProp); info.Libraries.emplace_back(entry);
} }
} else if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
std::string linkProp =
cmStrCat("IMPORTED_LINK_INTERFACE_LIBRARIES", suffix);
cmValue propertyLibs = this->GetProperty(linkProp);
if (!propertyLibs) { if (!propertyLibs) {
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
propertyLibs = this->GetProperty(linkProp); propertyLibs = this->GetProperty(linkProp);
} }
} if (propertyLibs) {
if (propertyLibs) { info.LibrariesProp = linkProp;
info.LibrariesProp = linkProp; info.Libraries.emplace_back(*propertyLibs);
info.Libraries = *propertyLibs; }
} }
} }
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) { if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {

View File

@@ -16,6 +16,7 @@
#include <cm/optional> #include <cm/optional>
#include "cmAlgorithms.h"
#include "cmLinkItem.h" #include "cmLinkItem.h"
#include "cmListFileCache.h" #include "cmListFileCache.h"
#include "cmPolicies.h" #include "cmPolicies.h"
@@ -983,7 +984,7 @@ private:
std::string ImportLibrary; std::string ImportLibrary;
std::string LibName; std::string LibName;
std::string Languages; std::string Languages;
std::string Libraries; std::vector<BT<std::string>> Libraries;
std::string LibrariesProp; std::string LibrariesProp;
std::string SharedDeps; std::string SharedDeps;
}; };
@@ -1045,7 +1046,7 @@ private:
bool IsLinkLookupScope(std::string const& n, bool IsLinkLookupScope(std::string const& n,
cmLocalGenerator const*& lg) const; cmLocalGenerator const*& lg) const;
void ExpandLinkItems(std::string const& prop, std::string const& value, void ExpandLinkItems(std::string const& prop, cmBTStringRange entries,
std::string const& config, std::string const& config,
const cmGeneratorTarget* headTarget, const cmGeneratorTarget* headTarget,
LinkInterfaceFor interfaceFor, LinkInterfaceFor interfaceFor,

View File

@@ -1,4 +1,4 @@
CMake Error: ^CMake Error at LinkImplementationCycle4.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES> \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
@@ -6,3 +6,5 @@ CMake Error:
\$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
target property which is transitive over the link libraries, creating a target property which is transitive over the link libraries, creating a
recursion. recursion.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -1,4 +1,4 @@
CMake Error: ^CMake Error at LinkImplementationCycle5.cmake:[0-9]+ \(set_property\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES> \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
@@ -6,3 +6,5 @@ CMake Error:
\$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
target property which is transitive over the link libraries, creating a target property which is transitive over the link libraries, creating a
recursion. recursion.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -1,4 +1,4 @@
CMake Error: ^CMake Error at LinkImplementationCycle6.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES> \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
@@ -6,3 +6,5 @@ CMake Error:
\$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
target property which is transitive over the link libraries, creating a target property which is transitive over the link libraries, creating a
recursion. recursion.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)