From a84a62e0a748c05f1779c4cd1e022df7d27e0db8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 15 Dec 2021 10:50:39 -0500 Subject: cmTarget: Record backtraces for INTERFACE_LINK_LIBRARIES --- Source/cmExportTryCompileFileGenerator.cxx | 10 ++++++++-- Source/cmTarget.cxx | 28 ++++++++++++++++++++++++++++ Source/cmTarget.h | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 4fe92c6..db9b05b 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -107,10 +107,16 @@ void cmExportTryCompileFileGenerator::PopulateProperties( const cmGeneratorTarget* target, ImportPropertyMap& properties, std::set& emitted) { + // Look through all non-special properties. std::vector props = target->GetPropertyKeys(); + // Include special properties that might be relevant here. + props.emplace_back("INTERFACE_LINK_LIBRARIES"); for (std::string const& p : props) { - - properties[p] = *target->GetProperty(p); + cmValue v = target->GetProperty(p); + if (!v) { + continue; + } + properties[p] = *v; if (cmHasLiteralPrefix(p, "IMPORTED_LINK_INTERFACE_LIBRARIES") || cmHasLiteralPrefix(p, "IMPORTED_LINK_DEPENDENT_LIBRARIES") || diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ebf5bd0..38361cc 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -200,6 +200,7 @@ public: std::vector> LinkOptionsEntries; std::vector> LinkDirectoriesEntries; std::vector> LinkImplementationPropertyEntries; + std::vector> LinkInterfacePropertyEntries; std::vector> HeaderSetsEntries; std::vector> InterfaceHeaderSetsEntries; std::vector> @@ -1114,6 +1115,11 @@ cmBTStringRange cmTarget::GetLinkImplementationEntries() const return cmMakeRange(this->impl->LinkImplementationPropertyEntries); } +cmBTStringRange cmTarget::GetLinkInterfaceEntries() const +{ + return cmMakeRange(this->impl->LinkInterfacePropertyEntries); +} + cmBTStringRange cmTarget::GetHeaderSetsEntries() const { return cmMakeRange(this->impl->HeaderSetsEntries); @@ -1157,6 +1163,7 @@ MAKE_PROP(HEADER_DIRS); MAKE_PROP(HEADER_SET); MAKE_PROP(HEADER_SETS); MAKE_PROP(INTERFACE_HEADER_SETS); +MAKE_PROP(INTERFACE_LINK_LIBRARIES); #undef MAKE_PROP } @@ -1282,6 +1289,12 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value) cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); } + } else if (prop == propINTERFACE_LINK_LIBRARIES) { + this->impl->LinkInterfacePropertyEntries.clear(); + if (value) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); + } } else if (prop == propSOURCES) { this->impl->SourceEntries.clear(); if (value) { @@ -1535,6 +1548,11 @@ void cmTarget::AppendProperty(const std::string& prop, cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); } + } else if (prop == propINTERFACE_LINK_LIBRARIES) { + if (!value.empty()) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); + } } else if (prop == "SOURCES") { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->SourceEntries.emplace_back(value, lfbt); @@ -1844,6 +1862,7 @@ cmValue cmTarget::GetProperty(const std::string& prop) const propHEADER_SET, propHEADER_SETS, propINTERFACE_HEADER_SETS, + propINTERFACE_LINK_LIBRARIES, }; if (specialProps.count(prop)) { if (prop == propC_STANDARD || prop == propCXX_STANDARD || @@ -1864,6 +1883,15 @@ cmValue cmTarget::GetProperty(const std::string& prop) const output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";"); return cmValue(output); } + if (prop == propINTERFACE_LINK_LIBRARIES) { + if (this->impl->LinkInterfacePropertyEntries.empty()) { + return nullptr; + } + + static std::string output; + output = cmJoin(this->impl->LinkInterfacePropertyEntries, ";"); + return cmValue(output); + } // the type property returns what type the target is if (prop == propTYPE) { return cmValue(cmState::GetTargetTypeName(this->GetType())); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index c4314a4..1173f49 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -265,6 +265,8 @@ public: cmBTStringRange GetLinkImplementationEntries() const; + cmBTStringRange GetLinkInterfaceEntries() const; + cmBTStringRange GetHeaderSetsEntries() const; cmBTStringRange GetInterfaceHeaderSetsEntries() const; -- cgit v0.12 From 1d709ea2f5de69970af24f21bb396292acca5a3d Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 15 Dec 2021 10:51:34 -0500 Subject: cmGeneratorTarget: Propagate backtraces from INTERFACE_LINK_LIBRARIES --- Source/cmGeneratorTarget.cxx | 111 ++++++++++++--------- Source/cmGeneratorTarget.h | 5 +- .../LinkImplementationCycle4-stderr.txt | 4 +- .../LinkImplementationCycle5-stderr.txt | 4 +- .../LinkImplementationCycle6-stderr.txt | 4 +- 5 files changed, 78 insertions(+), 50 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index e539e1d..1493f24 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -6553,14 +6553,13 @@ cm::optional 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 $ 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 libs; - std::unique_ptr 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 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 const& entry : entries) { + cmGeneratorExpression ge(entry.Backtrace); + std::unique_ptr cge = ge.Parse(entry.Value); + cge->SetEvaluateForBuildsystem(true); + std::vector libs = cmExpandedList( + cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, + this, headTarget->LinkerLanguage)); + for (std::string const& lib : libs) { + if (cm::optional 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> 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> 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 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 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) { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index eff5253..110af43 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -16,6 +16,7 @@ #include +#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> 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, diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt index 5cfeb0a..d56b199 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt @@ -1,4 +1,4 @@ -CMake Error: +^CMake Error at LinkImplementationCycle4.cmake:[0-9]+ \(target_link_libraries\): Error evaluating generator expression: \$ @@ -6,3 +6,5 @@ CMake Error: \$ 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\) diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt index 5cfeb0a..cf4e6d7 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt @@ -1,4 +1,4 @@ -CMake Error: +^CMake Error at LinkImplementationCycle5.cmake:[0-9]+ \(set_property\): Error evaluating generator expression: \$ @@ -6,3 +6,5 @@ CMake Error: \$ 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\) diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt index 5cfeb0a..93cb573 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt @@ -1,4 +1,4 @@ -CMake Error: +^CMake Error at LinkImplementationCycle6.cmake:[0-9]+ \(target_link_libraries\): Error evaluating generator expression: \$ @@ -6,3 +6,5 @@ CMake Error: \$ 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\) -- cgit v0.12