From f1dd0eeaaf264ebb35b048f423c66296e6967d16 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 24 Sep 2018 10:54:18 -0400 Subject: cmListFileCache: Add wrapper template for values with a backtrace --- Source/cmListFileCache.cxx | 7 ++++++- Source/cmListFileCache.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 4d7e1e2..d79afc6 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -9,10 +9,10 @@ #include "cmSystemTools.h" #include "cmake.h" -#include #include #include #include +#include cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=( std::string const& name) @@ -474,3 +474,8 @@ bool operator!=(const cmListFileContext& lhs, const cmListFileContext& rhs) { return !(lhs == rhs); } + +std::ostream& operator<<(std::ostream& os, BT const& s) +{ + return os << s.Value; +} diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 3d3afdf..9f16b16 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -9,6 +9,7 @@ #include // IWYU pragma: keep #include #include +#include #include #include "cmStateSnapshot.h" @@ -169,6 +170,34 @@ private: cmListFileBacktrace(std::shared_ptr top); }; +// Wrap type T as a value with a backtrace. For purposes of +// ordering and equality comparison, only the original value is +// used. The backtrace is considered incidental. +template +class BT +{ +public: + BT(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace()) + : Value(std::move(v)) + , Backtrace(std::move(bt)) + { + } + T Value; + cmListFileBacktrace Backtrace; + friend bool operator==(BT const& l, BT const& r) + { + return l.Value == r.Value; + } + friend bool operator<(BT const& l, BT const& r) + { + return l.Value < r.Value; + } + friend bool operator==(BT const& l, T const& r) { return l.Value == r; } + friend bool operator==(T const& l, BT const& r) { return l == r.Value; } +}; + +std::ostream& operator<<(std::ostream& os, BT const& s); + struct cmListFile { bool ParseFile(const char* path, cmMessenger* messenger, -- cgit v0.12 From e022e2d8734ffbc0378b75d85b32a2524302dd50 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 10 Oct 2018 08:56:36 -0400 Subject: cmListFileCache: Add ExpandListWithBacktrace helper --- Source/cmListFileCache.cxx | 13 +++++++++++++ Source/cmListFileCache.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index d79afc6..d0495f7 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -479,3 +479,16 @@ std::ostream& operator<<(std::ostream& os, BT const& s) { return os << s.Value; } + +std::vector> ExpandListWithBacktrace( + const char* list, cmListFileBacktrace const& bt) +{ + std::vector> result; + std::vector tmp; + cmSystemTools::ExpandListArgument(list, tmp); + result.reserve(tmp.size()); + for (std::string& i : tmp) { + result.emplace_back(std::move(i), bt); + } + return result; +} diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 9f16b16..7c2802e 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -198,6 +198,9 @@ public: std::ostream& operator<<(std::ostream& os, BT const& s); +std::vector> ExpandListWithBacktrace( + const char* list, cmListFileBacktrace const& bt = cmListFileBacktrace()); + struct cmListFile { bool ParseFile(const char* path, cmMessenger* messenger, -- cgit v0.12 From a093b1a4f3c8c40c55c50ad8e701ceb599961140 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 17 Oct 2018 10:44:09 -0400 Subject: cmLinkItem: Add backtrace Carry a backtrace on every link item, not just link implementation items. For now the non-impl items will still have empty backtraces at runtime, but this will allow us to introduce values over time. --- Source/cmComputeLinkDepends.cxx | 3 ++- Source/cmComputeTargetDepends.cxx | 20 +++++++------------- Source/cmGeneratorTarget.cxx | 28 +++++++++++++++++----------- Source/cmGeneratorTarget.h | 4 +++- Source/cmLinkItem.cxx | 12 ++++++------ Source/cmLinkItem.h | 9 ++++----- 6 files changed, 39 insertions(+), 37 deletions(-) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index aa17de6..e3d53e4 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -6,6 +6,7 @@ #include "cmComputeComponentGraph.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" @@ -565,7 +566,7 @@ cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index, from = depender; } } - return from->ResolveLinkItem(name); + return from->ResolveLinkItem(name, cmListFileBacktrace()); } void cmComputeLinkDepends::InferDependencies() diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 268e749..28e1251 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -6,6 +6,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmPolicies.h" @@ -22,8 +23,6 @@ #include #include -class cmListFileBacktrace; - /* This class is meant to analyze inter-target dependencies globally @@ -208,7 +207,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) for (cmSourceFile const* o : objectFiles) { std::string const& objLib = o->GetObjectLibrary(); if (!objLib.empty()) { - cmLinkItem const& objItem = depender->ResolveLinkItem(objLib); + cmLinkItem const& objItem = + depender->ResolveLinkItem(objLib, cmListFileBacktrace()); if (emitted.insert(objItem).second) { if (depender->GetType() != cmStateEnums::EXECUTABLE && depender->GetType() != cmStateEnums::STATIC_LIBRARY && @@ -230,7 +230,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) cmLinkImplementation const* impl = depender->GetLinkImplementation(it); // A target should not depend on itself. - emitted.insert(cmLinkItem(depender)); + emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); for (cmLinkImplItem const& lib : impl->Libraries) { // Don't emit the same library twice for this target. if (emitted.insert(lib).second) { @@ -246,7 +246,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) std::set const& tutils = depender->GetUtilityItems(); std::set emitted; // A target should not depend on itself. - emitted.insert(cmLinkItem(depender)); + emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); for (cmLinkItem const& litem : tutils) { // Don't emit the same utility twice for this target. if (emitted.insert(litem).second) { @@ -289,7 +289,7 @@ void cmComputeTargetDepends::AddInterfaceDepends( if (dependee) { // A target should not depend on itself. - emitted.insert(cmLinkItem(depender)); + emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); this->AddInterfaceDepends(depender_index, dependee, config, emitted); } } @@ -327,13 +327,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, e << "The dependency target \"" << dependee_name << "\" of target \"" << depender->GetName() << "\" does not exist."; - cmListFileBacktrace const* backtrace = - depender->GetUtilityBacktrace(dependee_name.AsStr()); - if (backtrace) { - cm->IssueMessage(messageType, e.str(), *backtrace); - } else { - cm->IssueMessage(messageType, e.str()); - } + cm->IssueMessage(messageType, e.str(), dependee_name.Backtrace); } } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index ea283c6..6ce6512 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -676,11 +676,14 @@ std::set const& cmGeneratorTarget::GetUtilityItems() const this->UtilityItemsDone = true; std::set const& utilities = this->GetUtilities(); for (std::string const& i : utilities) { + cmListFileBacktrace const* bt = this->GetUtilityBacktrace(i); if (cmGeneratorTarget* gt = this->LocalGenerator->FindGeneratorTargetToUse(i)) { - this->UtilityItems.insert(cmLinkItem(gt)); + this->UtilityItems.insert( + cmLinkItem(gt, bt ? *bt : cmListFileBacktrace())); } else { - this->UtilityItems.insert(cmLinkItem(i)); + this->UtilityItems.insert( + cmLinkItem(i, bt ? *bt : cmListFileBacktrace())); } } } @@ -4618,6 +4621,7 @@ void cmGeneratorTarget::ReportPropertyOrigin( } void cmGeneratorTarget::LookupLinkItems(std::vector const& names, + cmListFileBacktrace const& bt, std::vector& items) const { for (std::string const& n : names) { @@ -4625,7 +4629,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector const& names, if (name == this->GetName() || name.empty()) { continue; } - items.push_back(this->ResolveLinkItem(name)); + items.push_back(this->ResolveLinkItem(name, bt)); } } @@ -4647,7 +4651,7 @@ void cmGeneratorTarget::ExpandLinkItems( false, headTarget, this, &dagChecker), libs); - this->LookupLinkItems(libs, items); + this->LookupLinkItems(libs, cge->GetBacktrace(), items); hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); } @@ -5200,7 +5204,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( iface.HadHeadSensitiveCondition); std::vector deps; cmSystemTools::ExpandListArgument(info->SharedDeps, deps); - this->LookupLinkItems(deps, iface.SharedDeps); + this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps); } return &iface; @@ -5736,7 +5740,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } // The entry is meant for this configuration. - impl.Libraries.emplace_back(this->ResolveLinkItem(name), *btIt, + impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt), evaluated != *le); } @@ -5764,7 +5768,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( continue; } // Support OLD behavior for CMP0003. - impl.WrongConfigLibraries.push_back(this->ResolveLinkItem(name)); + impl.WrongConfigLibraries.push_back( + this->ResolveLinkItem(name, cmListFileBacktrace())); } } } @@ -5811,12 +5816,13 @@ cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference( return resolved; } -cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const +cmLinkItem cmGeneratorTarget::ResolveLinkItem( + std::string const& name, cmListFileBacktrace const& bt) const { TargetOrString resolved = this->ResolveTargetReference(name); if (!resolved.Target) { - return cmLinkItem(resolved.String); + return cmLinkItem(resolved.String, bt); } // Skip targets that will not really be linked. This is probably a @@ -5824,10 +5830,10 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const // within the project. if (resolved.Target->GetType() == cmStateEnums::EXECUTABLE && !resolved.Target->IsExecutableWithExports()) { - return cmLinkItem(resolved.Target->GetName()); + return cmLinkItem(resolved.Target->GetName(), bt); } - return cmLinkItem(resolved.Target); + return cmLinkItem(resolved.Target, bt); } std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 98669c3..07274ce 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -362,7 +362,8 @@ public: }; TargetOrString ResolveTargetReference(std::string const& name) const; - cmLinkItem ResolveLinkItem(std::string const& name) const; + cmLinkItem ResolveLinkItem(std::string const& name, + cmListFileBacktrace const& bt) const; // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change @@ -838,6 +839,7 @@ private: std::vector& items, bool& hadHeadSensitiveCondition) const; void LookupLinkItems(std::vector const& names, + cmListFileBacktrace const& bt, std::vector& items) const; void GetSourceFiles(std::vector& files, diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx index 69b6821..121731d 100644 --- a/Source/cmLinkItem.cxx +++ b/Source/cmLinkItem.cxx @@ -12,15 +12,18 @@ cmLinkItem::cmLinkItem() { } -cmLinkItem::cmLinkItem(std::string const& n) +cmLinkItem::cmLinkItem(std::string const& n, cmListFileBacktrace const& bt) : String(n) , Target(nullptr) + , Backtrace(bt) { } -cmLinkItem::cmLinkItem(cmGeneratorTarget const* t) +cmLinkItem::cmLinkItem(cmGeneratorTarget const* t, + cmListFileBacktrace const& bt) : String() , Target(t) + , Backtrace(bt) { } @@ -58,15 +61,12 @@ std::ostream& operator<<(std::ostream& os, cmLinkItem const& item) cmLinkImplItem::cmLinkImplItem() : cmLinkItem() - , Backtrace() , FromGenex(false) { } -cmLinkImplItem::cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt, - bool fromGenex) +cmLinkImplItem::cmLinkImplItem(cmLinkItem item, bool fromGenex) : cmLinkItem(std::move(item)) - , Backtrace(bt) , FromGenex(fromGenex) { } diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index 74fd298..e1ddd22 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -24,10 +24,11 @@ class cmLinkItem public: cmLinkItem(); - explicit cmLinkItem(std::string const& s); - explicit cmLinkItem(cmGeneratorTarget const* t); + cmLinkItem(std::string const& s, cmListFileBacktrace const& bt); + cmLinkItem(cmGeneratorTarget const* t, cmListFileBacktrace const& bt); std::string const& AsStr() const; cmGeneratorTarget const* Target; + cmListFileBacktrace Backtrace; friend bool operator<(cmLinkItem const& l, cmLinkItem const& r); friend bool operator==(cmLinkItem const& l, cmLinkItem const& r); friend std::ostream& operator<<(std::ostream& os, cmLinkItem const& item); @@ -37,9 +38,7 @@ class cmLinkImplItem : public cmLinkItem { public: cmLinkImplItem(); - cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt, - bool fromGenex); - cmListFileBacktrace Backtrace; + cmLinkImplItem(cmLinkItem item, bool fromGenex); bool FromGenex; }; -- cgit v0.12 From a6e02f881dc5e74d79201f761fb28c99a9e7d2af Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 17 Oct 2018 10:25:20 -0400 Subject: add_dependencies: Track backtraces internally Record backtraces for "utility" dependencies created by `add_dependencies` calls. --- Source/cmGeneratorTarget.cxx | 21 ++++++--------------- Source/cmGeneratorTarget.h | 3 +-- Source/cmGlobalNinjaGenerator.cxx | 8 +++++--- Source/cmGlobalVisualStudio71Generator.cxx | 9 +++++---- Source/cmGlobalVisualStudio71Generator.h | 2 +- Source/cmGlobalVisualStudio7Generator.h | 2 +- Source/cmGlobalVisualStudio8Generator.cxx | 4 ++-- Source/cmLocalUnixMakefileGenerator3.cxx | 7 +++++-- Source/cmQtAutoGenInitializer.cxx | 5 +++-- Source/cmTarget.cxx | 20 +++----------------- Source/cmTarget.h | 11 ++++++----- 11 files changed, 38 insertions(+), 54 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6ce6512..fa489e2 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -674,16 +674,13 @@ std::set const& cmGeneratorTarget::GetUtilityItems() const { if (!this->UtilityItemsDone) { this->UtilityItemsDone = true; - std::set const& utilities = this->GetUtilities(); - for (std::string const& i : utilities) { - cmListFileBacktrace const* bt = this->GetUtilityBacktrace(i); + std::set> const& utilities = this->GetUtilities(); + for (BT const& i : utilities) { if (cmGeneratorTarget* gt = - this->LocalGenerator->FindGeneratorTargetToUse(i)) { - this->UtilityItems.insert( - cmLinkItem(gt, bt ? *bt : cmListFileBacktrace())); + this->LocalGenerator->FindGeneratorTargetToUse(i.Value)) { + this->UtilityItems.insert(cmLinkItem(gt, i.Backtrace)); } else { - this->UtilityItems.insert( - cmLinkItem(i, bt ? *bt : cmListFileBacktrace())); + this->UtilityItems.insert(cmLinkItem(i.Value, i.Backtrace)); } } } @@ -1713,17 +1710,11 @@ cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const return this->Target->GetBacktrace(); } -const std::set& cmGeneratorTarget::GetUtilities() const +const std::set>& cmGeneratorTarget::GetUtilities() const { return this->Target->GetUtilities(); } -const cmListFileBacktrace* cmGeneratorTarget::GetUtilityBacktrace( - const std::string& u) const -{ - return this->Target->GetUtilityBacktrace(u); -} - bool cmGeneratorTarget::HaveWellDefinedOutputFiles() const { return this->GetType() == cmStateEnums::STATIC_LIBRARY || diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 07274ce..7de306e 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -273,8 +273,7 @@ public: cmListFileBacktrace GetBacktrace() const; - std::set const& GetUtilities() const; - cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const; + std::set> const& GetUtilities() const; bool LinkLanguagePropagatesToDependents() const { diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index f513403..8c69f42 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -19,6 +19,7 @@ #include "cmGeneratedFileStream.h" #include "cmGeneratorExpressionEvaluationFile.h" #include "cmGeneratorTarget.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" @@ -1008,10 +1009,11 @@ void cmGlobalNinjaGenerator::AppendTargetDepends( { if (target->GetType() == cmStateEnums::GLOBAL_TARGET) { // These depend only on other CMake-provided targets, e.g. "all". - std::set const& utils = target->GetUtilities(); - for (std::string const& util : utils) { + std::set> const& utils = target->GetUtilities(); + for (BT const& util : utils) { std::string d = - target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" + util; + target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" + + util.Value; outputs.push_back(this->ConvertToNinjaPath(d)); } } else { diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 0b086b0..a216346 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -159,7 +159,7 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends( // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteExternalProject( std::ostream& fout, const std::string& name, const char* location, - const char* typeGuid, const std::set& depends) + const char* typeGuid, const std::set>& depends) { fout << "Project(\"{" << (typeGuid ? typeGuid : this->ExternalProjectType(location)) @@ -171,9 +171,10 @@ void cmGlobalVisualStudio71Generator::WriteExternalProject( // project instead of in the global section if (!depends.empty()) { fout << "\tProjectSection(ProjectDependencies) = postProject\n"; - for (std::string const& it : depends) { - if (!it.empty()) { - fout << "\t\t{" << this->GetGUID(it) << "} = {" << this->GetGUID(it) + for (BT const& it : depends) { + std::string const& dep = it.Value; + if (!dep.empty()) { + fout << "\t\t{" << this->GetGUID(dep) << "} = {" << this->GetGUID(dep) << "}\n"; } } diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index 054c342..b6e3131 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -33,7 +33,7 @@ protected: const std::string& platformMapping = "") override; void WriteExternalProject(std::ostream& fout, const std::string& name, const char* path, const char* typeGuid, - const std::set& depends) override; + const std::set>& depends) override; void WriteSLNHeader(std::ostream& fout) override; // Folders are not supported by VS 7.1. diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 0c9dd88..251478d 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -145,7 +145,7 @@ protected: virtual void WriteExternalProject( std::ostream& fout, const std::string& name, const char* path, - const char* typeGuid, const std::set& dependencies) = 0; + const char* typeGuid, const std::set>& dependencies) = 0; std::string ConvertToSolutionPath(const char* path); diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index ba138c2..b155d9c 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -315,9 +315,9 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies( cmGeneratorTarget* target) { // Look for utility dependencies that magically link. - for (std::string const& ui : target->GetUtilities()) { + for (BT const& ui : target->GetUtilities()) { if (cmGeneratorTarget* depTarget = - target->GetLocalGenerator()->FindGeneratorTargetToUse(ui)) { + target->GetLocalGenerator()->FindGeneratorTargetToUse(ui.Value)) { if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY && depTarget->GetProperty("EXTERNAL_MSPROJECT")) { // This utility dependency names an external .vcproj target. diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 68cdef0..6a535c1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -17,6 +17,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMakefileTargetGenerator.h" @@ -1546,8 +1547,10 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( if (!text) { text = "Running external command ..."; } - depends.insert(depends.end(), gt->GetUtilities().begin(), - gt->GetUtilities().end()); + depends.reserve(gt->GetUtilities().size()); + for (BT const& u : gt->GetUtilities()) { + depends.push_back(u.Value); + } this->AppendEcho(commands, text, cmLocalUnixMakefileGenerator3::EchoGlobal); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 6bc3b61..7700767 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -12,6 +12,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -940,8 +941,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() new cmGeneratorTarget(autogenTarget, localGen)); // Forward origin utilities to autogen target - for (std::string const& depName : this->Target->Target->GetUtilities()) { - autogenTarget->AddUtility(depName, makefile); + for (BT const& depName : this->Target->GetUtilities()) { + autogenTarget->AddUtility(depName.Value, makefile); } // Add additional autogen target dependencies to autogen target for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index f0d6519..1458f01 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -486,24 +486,10 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const return this->GetMakefile()->GetGlobalGenerator(); } -void cmTarget::AddUtility(const std::string& u, cmMakefile* makefile) +void cmTarget::AddUtility(std::string const& u, cmMakefile* mf) { - if (this->Utilities.insert(u).second && makefile) { - this->UtilityBacktraces.insert( - std::make_pair(u, makefile->GetBacktrace())); - } -} - -cmListFileBacktrace const* cmTarget::GetUtilityBacktrace( - const std::string& u) const -{ - std::map::const_iterator i = - this->UtilityBacktraces.find(u); - if (i == this->UtilityBacktraces.end()) { - return nullptr; - } - - return &i->second; + BT util(u, mf ? mf->GetBacktrace() : cmListFileBacktrace()); + this->Utilities.insert(util); } cmListFileBacktrace const& cmTarget::GetBacktrace() const diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 694de1c..aa2859d 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -190,10 +190,12 @@ public: * name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE * commands. It is not a full path nor does it have an extension. */ - void AddUtility(const std::string& u, cmMakefile* makefile = nullptr); + void AddUtility(std::string const& u, cmMakefile* mf = nullptr); ///! Get the utilities used by this target - std::set const& GetUtilities() const { return this->Utilities; } - cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const; + std::set> const& GetUtilities() const + { + return this->Utilities; + } ///! Set/Get a property of this target file void SetProperty(const std::string& prop, const char* value); @@ -307,8 +309,7 @@ private: bool IsGeneratorProvided; cmPropertyMap Properties; std::set SystemIncludeDirectories; - std::set Utilities; - std::map UtilityBacktraces; + std::set> Utilities; cmPolicies::PolicyMap PolicyMap; std::string Name; std::string InstallPath; -- cgit v0.12 From dacbb414550db63ff40225f3f6057c3c74bcf5c9 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 17 Oct 2018 10:46:00 -0400 Subject: Track backtraces in target dependencies internally Carry backtraces on target dependency edges to refer to the line in project code that caused the edge to appear. --- Source/cmComputeComponentGraph.cxx | 4 ++-- Source/cmComputeLinkDepends.cxx | 11 ++++++++--- Source/cmComputeTargetDepends.cxx | 37 ++++++++++++++++++++++++------------- Source/cmComputeTargetDepends.h | 3 +++ Source/cmGraphAdjacencyList.h | 8 +++++++- Source/cmTargetDepend.h | 6 ++++++ 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx index a7dc1ca..5820df6 100644 --- a/Source/cmComputeComponentGraph.cxx +++ b/Source/cmComputeComponentGraph.cxx @@ -125,8 +125,8 @@ void cmComputeComponentGraph::TransferEdges() if (i_component != j_component) { // We do not attempt to combine duplicate edges, but instead // store the inter-component edges with suitable multiplicity. - this->ComponentGraph[i_component].emplace_back(j_component, - ni.IsStrong()); + this->ComponentGraph[i_component].emplace_back( + j_component, ni.IsStrong(), ni.GetBacktrace()); } } } diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index e3d53e4..4717cf6 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -420,7 +420,8 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) // This shared library dependency must follow the item that listed // it. - this->EntryConstraintGraph[dep.DependerIndex].push_back(index); + this->EntryConstraintGraph[dep.DependerIndex].emplace_back( + index, true, cmListFileBacktrace()); // Target items may have their own dependencies. if (entry.Target) { @@ -523,7 +524,8 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, // The dependee must come after the depender. if (depender_index >= 0) { - this->EntryConstraintGraph[depender_index].push_back(dependee_index); + this->EntryConstraintGraph[depender_index].emplace_back( + dependee_index, false, cmListFileBacktrace()); } else { // This is a direct dependency of the target being linked. this->OriginalEntries.push_back(dependee_index); @@ -595,7 +597,10 @@ void cmComputeLinkDepends::InferDependencies() // Add the inferred dependencies to the graph. cmGraphEdgeList& edges = this->EntryConstraintGraph[depender_index]; - edges.insert(edges.end(), common.begin(), common.end()); + edges.reserve(edges.size() + common.size()); + for (auto const& c : common) { + edges.emplace_back(c, true, cmListFileBacktrace()); + } } } diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 28e1251..f8ac333 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -151,6 +151,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t, cmGeneratorTarget const* dep = this->Targets[ni]; cmTargetDependSet::iterator di = deps.insert(dep).first; di->SetType(ni.IsStrong()); + di->SetBacktrace(ni.GetBacktrace()); } } @@ -258,7 +259,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) void cmComputeTargetDepends::AddInterfaceDepends( int depender_index, const cmGeneratorTarget* dependee, - const std::string& config, std::set& emitted) + cmListFileBacktrace const& dependee_backtrace, const std::string& config, + std::set& emitted) { cmGeneratorTarget const* depender = this->Targets[depender_index]; if (cmLinkInterface const* iface = @@ -266,8 +268,13 @@ void cmComputeTargetDepends::AddInterfaceDepends( for (cmLinkItem const& lib : iface->Libraries) { // Don't emit the same library twice for this target. if (emitted.insert(lib).second) { - this->AddTargetDepend(depender_index, lib, true); - this->AddInterfaceDepends(depender_index, lib, config, emitted); + // Inject the backtrace of the original link dependency whose + // link interface we are adding. This indicates the line of + // code in the project that caused this dependency to be added. + cmLinkItem libBT = lib; + libBT.Backtrace = dependee_backtrace; + this->AddTargetDepend(depender_index, libBT, true); + this->AddInterfaceDepends(depender_index, libBT, config, emitted); } } } @@ -290,7 +297,8 @@ void cmComputeTargetDepends::AddInterfaceDepends( if (dependee) { // A target should not depend on itself. emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); - this->AddInterfaceDepends(depender_index, dependee, config, emitted); + this->AddInterfaceDepends(depender_index, dependee, + dependee_name.Backtrace, config, emitted); } } @@ -340,13 +348,14 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, } if (dependee) { - this->AddTargetDepend(depender_index, dependee, linking); + this->AddTargetDepend(depender_index, dependee, dependee_name.Backtrace, + linking); } } -void cmComputeTargetDepends::AddTargetDepend(int depender_index, - const cmGeneratorTarget* dependee, - bool linking) +void cmComputeTargetDepends::AddTargetDepend( + int depender_index, cmGeneratorTarget const* dependee, + cmListFileBacktrace const& dependee_backtrace, bool linking) { if (dependee->IsImported() || dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) { @@ -355,7 +364,8 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, std::set const& utils = dependee->GetUtilityItems(); for (cmLinkItem const& i : utils) { if (cmGeneratorTarget const* transitive_dependee = i.Target) { - this->AddTargetDepend(depender_index, transitive_dependee, false); + this->AddTargetDepend(depender_index, transitive_dependee, i.Backtrace, + false); } } } else { @@ -367,7 +377,8 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, int dependee_index = tii->second; // Add this entry to the dependency graph. - this->InitialGraph[depender_index].emplace_back(dependee_index, !linking); + this->InitialGraph[depender_index].emplace_back(dependee_index, !linking, + dependee_backtrace); } } @@ -501,7 +512,7 @@ bool cmComputeTargetDepends::IntraComponent(std::vector const& cmap, for (cmGraphEdge const& edge : el) { int j = edge; if (cmap[j] == c && edge.IsStrong()) { - this->FinalGraph[i].emplace_back(j, true); + this->FinalGraph[i].emplace_back(j, true, edge.GetBacktrace()); if (!this->IntraComponent(cmap, c, j, head, emitted, visited)) { return false; } @@ -510,7 +521,7 @@ bool cmComputeTargetDepends::IntraComponent(std::vector const& cmap, // Prepend to a linear linked-list of intra-component edges. if (*head >= 0) { - this->FinalGraph[i].emplace_back(*head, false); + this->FinalGraph[i].emplace_back(*head, false, cmListFileBacktrace()); } else { this->ComponentTail[c] = i; } @@ -561,7 +572,7 @@ bool cmComputeTargetDepends::ComputeFinalDepends( int dependee_component = ni; int dependee_component_head = this->ComponentHead[dependee_component]; this->FinalGraph[depender_component_tail].emplace_back( - dependee_component_head, ni.IsStrong()); + dependee_component_head, ni.IsStrong(), ni.GetBacktrace()); } } return true; diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 3046e8a..3840bd7 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmGraphAdjacencyList.h" +#include "cmListFileCache.h" #include #include @@ -47,6 +48,7 @@ private: void AddTargetDepend(int depender_index, cmLinkItem const& dependee_name, bool linking); void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee, + cmListFileBacktrace const& dependee_backtrace, bool linking); bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name, @@ -54,6 +56,7 @@ private: std::set& emitted); void AddInterfaceDepends(int depender_index, cmGeneratorTarget const* dependee, + cmListFileBacktrace const& dependee_backtrace, const std::string& config, std::set& emitted); cmGlobalGenerator* GlobalGenerator; diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h index 6a0a799..fb2eee2 100644 --- a/Source/cmGraphAdjacencyList.h +++ b/Source/cmGraphAdjacencyList.h @@ -5,6 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmListFileCache.h" + #include /** @@ -15,18 +17,22 @@ class cmGraphEdge { public: - cmGraphEdge(int n = 0, bool s = true) + cmGraphEdge(int n, bool s, cmListFileBacktrace const& bt) : Dest(n) , Strong(s) + , Backtrace(bt) { } operator int() const { return this->Dest; } bool IsStrong() const { return this->Strong; } + cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } + private: int Dest; bool Strong; + cmListFileBacktrace Backtrace; }; struct cmGraphEdgeList : public std::vector { diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h index b698db6..5ea0085 100644 --- a/Source/cmTargetDepend.h +++ b/Source/cmTargetDepend.h @@ -19,6 +19,7 @@ class cmTargetDepend // mutable members to achieve a map with set syntax. mutable bool Link; mutable bool Util; + mutable cmListFileBacktrace Backtrace; public: cmTargetDepend(cmGeneratorTarget const* t) @@ -42,8 +43,13 @@ public: this->Link = true; } } + void SetBacktrace(cmListFileBacktrace const& bt) const + { + this->Backtrace = bt; + } bool IsLink() const { return this->Link; } bool IsUtil() const { return this->Util; } + cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } }; /** Unordered set of (direct) dependencies of a target. */ -- cgit v0.12