Commit 1d709ea2 authored by Brad King's avatar Brad King
Browse files

cmGeneratorTarget: Propagate backtraces from INTERFACE_LINK_LIBRARIES

parent a84a62e0
......@@ -6553,14 +6553,13 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
}
void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
std::string const& value,
cmBTStringRange entries,
std::string const& config,
cmGeneratorTarget const* headTarget,
LinkInterfaceFor interfaceFor,
cmLinkInterface& iface) const
{
// Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
// The $<LINK_ONLY> expression may be in a link interface to specify
// private link dependencies that are otherwise excluded from usage
......@@ -6568,39 +6567,46 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
if (interfaceFor == LinkInterfaceFor::Usage) {
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();
LookupLinkItemScope scope{ this->LocalGenerator };
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) {
// Report explicitly linked object files separately.
std::string const& maybeObj = item.AsStr();
if (cmSystemTools::FileIsFullPath(maybeObj)) {
cmSourceFile const* sf =
mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
iface.Objects.emplace_back(std::move(item));
continue;
for (BT<std::string> const& entry : entries) {
cmGeneratorExpression ge(entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
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) {
// Report explicitly linked object files separately.
std::string const& maybeObj = item.AsStr();
if (cmSystemTools::FileIsFullPath(maybeObj)) {
cmSourceFile const* sf =
mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
iface.Objects.emplace_back(std::move(item));
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(
......@@ -7105,8 +7111,18 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
if (explicitLibraries) {
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
headTarget, interfaceFor, iface);
if (cmp0022NEW) {
// 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.
......@@ -7126,7 +7142,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
cmLinkInterface ifaceNew;
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
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);
}
if (ifaceNew.Libraries != iface.Libraries) {
......@@ -7268,8 +7286,8 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
iface.AllDone = true;
iface.Multiplicity = info->Multiplicity;
cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, interfaceFor, iface);
this->ExpandLinkItems(info->LibrariesProp, cmMakeRange(info->Libraries),
config, headTarget, interfaceFor, iface);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
LookupLinkItemScope scope{ this->LocalGenerator };
for (std::string const& dep : deps) {
......@@ -7340,23 +7358,26 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the link interface.
{
std::string linkProp = "INTERFACE_LINK_LIBRARIES";
cmValue propertyLibs = this->GetProperty(linkProp);
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
if (!propertyLibs) {
linkProp = cmStrCat("IMPORTED_LINK_INTERFACE_LIBRARIES", suffix);
propertyLibs = this->GetProperty(linkProp);
// Use the INTERFACE_LINK_LIBRARIES special representation directly
// to get backtraces.
cmBTStringRange entries = this->Target->GetLinkInterfaceEntries();
if (!entries.empty()) {
info.LibrariesProp = "INTERFACE_LINK_LIBRARIES";
for (BT<std::string> const& entry : entries) {
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) {
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
propertyLibs = this->GetProperty(linkProp);
}
}
if (propertyLibs) {
info.LibrariesProp = linkProp;
info.Libraries = *propertyLibs;
if (propertyLibs) {
info.LibrariesProp = linkProp;
info.Libraries.emplace_back(*propertyLibs);
}
}
}
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
......
......@@ -16,6 +16,7 @@
#include <cm/optional>
#include "cmAlgorithms.h"
#include "cmLinkItem.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
......@@ -983,7 +984,7 @@ private:
std::string ImportLibrary;
std::string LibName;
std::string Languages;
std::string Libraries;
std::vector<BT<std::string>> Libraries;
std::string LibrariesProp;
std::string SharedDeps;
};
......@@ -1045,7 +1046,7 @@ private:
bool IsLinkLookupScope(std::string const& n,
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,
const cmGeneratorTarget* headTarget,
LinkInterfaceFor interfaceFor,
......
CMake Error:
^CMake Error at LinkImplementationCycle4.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
......@@ -6,3 +6,5 @@ CMake Error:
\$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
target property which is transitive over the link libraries, creating a
recursion.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
CMake Error:
^CMake Error at LinkImplementationCycle5.cmake:[0-9]+ \(set_property\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
......@@ -6,3 +6,5 @@ CMake Error:
\$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
target property which is transitive over the link libraries, creating a
recursion.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
CMake Error:
^CMake Error at LinkImplementationCycle6.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
......@@ -6,3 +6,5 @@ CMake Error:
\$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
target property which is transitive over the link libraries, creating a
recursion.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment