summaryrefslogtreecommitdiff
path: root/Source/cmComputeLinkDepends.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmComputeLinkDepends.cxx')
-rw-r--r--Source/cmComputeLinkDepends.cxx217
1 files changed, 99 insertions, 118 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 9c516ee8d..7a9e2b7f6 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -2,25 +2,28 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmComputeLinkDepends.h"
-#include "cmAlgorithms.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <iterator>
+#include <sstream>
+#include <utility>
+
+#include <cm/memory>
+
#include "cmComputeComponentGraph.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmRange.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
#include "cmake.h"
-#include <algorithm>
-#include <assert.h>
-#include <iterator>
-#include <sstream>
-#include <stdio.h>
-#include <string.h>
-#include <utility>
-
/*
This file computes an ordered list of link items to use when linking a
@@ -194,14 +197,10 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
this->OldLinkDirMode = false;
// No computation has been done.
- this->CCG = CM_NULLPTR;
+ this->CCG = nullptr;
}
-cmComputeLinkDepends::~cmComputeLinkDepends()
-{
- cmDeleteAll(this->InferredDependSets);
- delete this->CCG;
-}
+cmComputeLinkDepends::~cmComputeLinkDepends() = default;
void cmComputeLinkDepends::SetOldLinkDirMode(bool b)
{
@@ -239,8 +238,9 @@ cmComputeLinkDepends::Compute()
// Display the constraint graph.
if (this->DebugMode) {
- fprintf(stderr, "---------------------------------------"
- "---------------------------------------\n");
+ fprintf(stderr,
+ "---------------------------------------"
+ "---------------------------------------\n");
fprintf(stderr, "Link dependency analysis for target %s, config %s\n",
this->Target->GetName().c_str(),
this->HasConfig ? this->Config.c_str() : "noconfig");
@@ -254,11 +254,7 @@ cmComputeLinkDepends::Compute()
// Iterate in reverse order so we can keep only the last occurrence
// of a shared library.
std::set<int> emmitted;
- for (std::vector<int>::const_reverse_iterator
- li = this->FinalLinkOrder.rbegin(),
- le = this->FinalLinkOrder.rend();
- li != le; ++li) {
- int i = *li;
+ for (int i : cmReverseRange(this->FinalLinkOrder)) {
LinkEntry const& e = this->EntryList[i];
cmGeneratorTarget const* t = e.Target;
// Entries that we know the linker will re-use do not need to be repeated.
@@ -278,23 +274,22 @@ cmComputeLinkDepends::Compute()
return this->FinalLinkEntries;
}
-std::map<std::string, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
- std::string const& item)
+std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
+ cmLinkItem const& item)
{
- std::map<std::string, int>::value_type index_entry(
+ std::map<cmLinkItem, int>::value_type index_entry(
item, static_cast<int>(this->EntryList.size()));
- std::map<std::string, int>::iterator lei =
- this->LinkEntryIndex.insert(index_entry).first;
- this->EntryList.push_back(LinkEntry());
- this->InferredDependSets.push_back(CM_NULLPTR);
- this->EntryConstraintGraph.push_back(EdgeList());
+ auto lei = this->LinkEntryIndex.insert(index_entry).first;
+ this->EntryList.emplace_back();
+ this->InferredDependSets.emplace_back();
+ this->EntryConstraintGraph.emplace_back();
return lei;
}
int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
{
// Check if the item entry has already been added.
- std::map<std::string, int>::iterator lei = this->LinkEntryIndex.find(item);
+ auto lei = this->LinkEntryIndex.find(item);
if (lei != this->LinkEntryIndex.end()) {
// Yes. We do not need to follow the item's dependencies again.
return lei->second;
@@ -306,27 +301,27 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
// Initialize the item entry.
int index = lei->second;
LinkEntry& entry = this->EntryList[index];
- entry.Item = item;
+ entry.Item = item.AsStr();
entry.Target = item.Target;
- entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
- item.substr(0, 10) != "-framework");
+ entry.IsFlag =
+ (!entry.Target && entry.Item[0] == '-' && entry.Item[1] != 'l' &&
+ entry.Item.substr(0, 10) != "-framework");
// If the item has dependencies queue it to follow them.
if (entry.Target) {
// Target dependencies are always known. Follow them.
- BFSEntry qe = { index, CM_NULLPTR };
+ BFSEntry qe = { index, nullptr };
this->BFSQueue.push(qe);
} else {
// Look for an old-style <item>_LIB_DEPENDS variable.
- std::string var = entry.Item;
- var += "_LIB_DEPENDS";
+ std::string var = cmStrCat(entry.Item, "_LIB_DEPENDS");
if (const char* val = this->Makefile->GetDefinition(var)) {
// The item dependencies are known. Follow them.
BFSEntry qe = { index, val };
this->BFSQueue.push(qe);
} else if (!entry.IsFlag) {
// The item dependencies are not known. We need to infer them.
- this->InferredDependSets[index] = new DependSetList;
+ this->InferredDependSets[index].Initialized = true;
}
}
@@ -357,10 +352,8 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry qe)
this->FollowSharedDeps(depender_index, iface);
// Support for CMP0003.
- for (std::vector<cmLinkItem>::const_iterator oi =
- iface->WrongConfigLibraries.begin();
- oi != iface->WrongConfigLibraries.end(); ++oi) {
- this->CheckWrongConfigItem(*oi);
+ for (cmLinkItem const& oi : iface->WrongConfigLibraries) {
+ this->CheckWrongConfigItem(oi);
}
}
} else {
@@ -385,10 +378,9 @@ void cmComputeLinkDepends::FollowSharedDeps(int depender_index,
void cmComputeLinkDepends::QueueSharedDependencies(
int depender_index, std::vector<cmLinkItem> const& deps)
{
- for (std::vector<cmLinkItem>::const_iterator li = deps.begin();
- li != deps.end(); ++li) {
+ for (cmLinkItem const& li : deps) {
SharedDepEntry qe;
- qe.Item = *li;
+ qe.Item = li;
qe.DependerIndex = depender_index;
this->SharedDepQueue.push(qe);
}
@@ -397,15 +389,14 @@ void cmComputeLinkDepends::QueueSharedDependencies(
void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
{
// Check if the target already has an entry.
- std::map<std::string, int>::iterator lei =
- this->LinkEntryIndex.find(dep.Item);
+ auto lei = this->LinkEntryIndex.find(dep.Item);
if (lei == this->LinkEntryIndex.end()) {
// Allocate a spot for the item entry.
lei = this->AllocateLinkEntry(dep.Item);
// Initialize the item entry.
LinkEntry& entry = this->EntryList[lei->second];
- entry.Item = dep.Item;
+ entry.Item = dep.Item.AsStr();
entry.Target = dep.Item.Target;
// This item was added specifically because it is a dependent
@@ -420,7 +411,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) {
@@ -438,33 +430,30 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
// This is called to add the dependencies named by
// <item>_LIB_DEPENDS. The variable contains a semicolon-separated
// list. The list contains link-type;item pairs and just items.
- std::vector<std::string> deplist;
- cmSystemTools::ExpandListArgument(value, deplist);
+ std::vector<std::string> deplist = cmExpandedList(value);
// Look for entries meant for this configuration.
std::vector<cmLinkItem> actual_libs;
cmTargetLinkLibraryType llt = GENERAL_LibraryType;
bool haveLLT = false;
- for (std::vector<std::string>::const_iterator di = deplist.begin();
- di != deplist.end(); ++di) {
- if (*di == "debug") {
+ for (std::string const& d : deplist) {
+ if (d == "debug") {
llt = DEBUG_LibraryType;
haveLLT = true;
- } else if (*di == "optimized") {
+ } else if (d == "optimized") {
llt = OPTIMIZED_LibraryType;
haveLLT = true;
- } else if (*di == "general") {
+ } else if (d == "general") {
llt = GENERAL_LibraryType;
haveLLT = true;
- } else if (!di->empty()) {
+ } else if (!d.empty()) {
// If no explicit link type was given prior to this entry then
// check if the entry has its own link type variable. This is
// needed for compatibility with dependency files generated by
// the export_library_dependencies command from CMake 2.4 and
// lower.
if (!haveLLT) {
- std::string var = *di;
- var += "_LINK_TYPE";
+ std::string var = cmStrCat(d, "_LINK_TYPE");
if (const char* val = this->Makefile->GetDefinition(var)) {
if (strcmp(val, "debug") == 0) {
llt = DEBUG_LibraryType;
@@ -476,10 +465,9 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
// If the library is meant for this link type then use it.
if (llt == GENERAL_LibraryType || llt == this->LinkType) {
- cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
- actual_libs.push_back(item);
+ actual_libs.emplace_back(this->ResolveLinkItem(depender_index, d));
} else if (this->OldLinkDirMode) {
- cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+ cmLinkItem item = this->ResolveLinkItem(depender_index, d);
this->CheckWrongConfigItem(item);
}
@@ -499,10 +487,8 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
cmLinkImplementation const* impl =
this->Target->GetLinkImplementation(this->Config);
this->AddLinkEntries(-1, impl->Libraries);
- for (std::vector<cmLinkItem>::const_iterator wi =
- impl->WrongConfigLibraries.begin();
- wi != impl->WrongConfigLibraries.end(); ++wi) {
- this->CheckWrongConfigItem(*wi);
+ for (cmLinkItem const& wi : impl->WrongConfigLibraries) {
+ this->CheckWrongConfigItem(wi);
}
}
@@ -514,56 +500,54 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
std::map<int, DependSet> dependSets;
// Loop over the libraries linked directly by the depender.
- for (typename std::vector<T>::const_iterator li = libs.begin();
- li != libs.end(); ++li) {
+ for (T const& l : libs) {
// Skip entries that will resolve to the target getting linked or
// are empty.
- cmLinkItem const& item = *li;
- if (item == this->Target->GetName() || item.empty()) {
+ cmLinkItem const& item = l;
+ if (item.AsStr() == this->Target->GetName() || item.AsStr().empty()) {
continue;
}
// Add a link entry for this item.
- int dependee_index = this->AddLinkEntry(*li);
+ int dependee_index = this->AddLinkEntry(l);
// 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);
}
// Update the inferred dependencies for earlier items.
- for (std::map<int, DependSet>::iterator dsi = dependSets.begin();
- dsi != dependSets.end(); ++dsi) {
+ for (auto& dependSet : dependSets) {
// Add this item to the inferred dependencies of other items.
// Target items are never inferred dependees because unknown
// items are outside libraries that should not be depending on
// targets.
if (!this->EntryList[dependee_index].Target &&
!this->EntryList[dependee_index].IsFlag &&
- dependee_index != dsi->first) {
- dsi->second.insert(dependee_index);
+ dependee_index != dependSet.first) {
+ dependSet.second.insert(dependee_index);
}
}
// If this item needs to have dependencies inferred, do so.
- if (this->InferredDependSets[dependee_index]) {
+ if (this->InferredDependSets[dependee_index].Initialized) {
// Make sure an entry exists to hold the set for the item.
dependSets[dependee_index];
}
}
// Store the inferred dependency sets discovered for this list.
- for (std::map<int, DependSet>::iterator dsi = dependSets.begin();
- dsi != dependSets.end(); ++dsi) {
- this->InferredDependSets[dsi->first]->push_back(dsi->second);
+ for (auto const& dependSet : dependSets) {
+ this->InferredDependSets[dependSet.first].push_back(dependSet.second);
}
}
-cmGeneratorTarget const* cmComputeLinkDepends::FindTargetToLink(
- int depender_index, const std::string& name)
+cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index,
+ const std::string& name)
{
// Look for a target in the scope of the depender.
cmGeneratorTarget const* from = this->Target;
@@ -573,7 +557,7 @@ cmGeneratorTarget const* cmComputeLinkDepends::FindTargetToLink(
from = depender;
}
}
- return from->FindTargetToLink(name);
+ return from->ResolveLinkItem(name, cmListFileBacktrace());
}
void cmComputeLinkDepends::InferDependencies()
@@ -585,37 +569,39 @@ void cmComputeLinkDepends::InferDependencies()
depender_index < this->InferredDependSets.size(); ++depender_index) {
// Skip items for which dependencies do not need to be inferred or
// for which the inferred dependency sets are empty.
- DependSetList* sets = this->InferredDependSets[depender_index];
- if (!sets || sets->empty()) {
+ DependSetList& sets = this->InferredDependSets[depender_index];
+ if (!sets.Initialized || sets.empty()) {
continue;
}
// Intersect the sets for this item.
- DependSetList::const_iterator i = sets->begin();
- DependSet common = *i;
- for (++i; i != sets->end(); ++i) {
+ DependSet common = sets.front();
+ for (DependSet const& i : cmMakeRange(sets).advance(1)) {
DependSet intersection;
- std::set_intersection(common.begin(), common.end(), i->begin(), i->end(),
+ std::set_intersection(common.begin(), common.end(), i.begin(), i.end(),
std::inserter(intersection, intersection.begin()));
common = intersection;
}
// 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());
+ }
}
}
void cmComputeLinkDepends::CleanConstraintGraph()
{
- for (Graph::iterator i = this->EntryConstraintGraph.begin();
- i != this->EntryConstraintGraph.end(); ++i) {
+ for (cmGraphEdgeList& edgeList : this->EntryConstraintGraph) {
// Sort the outgoing edges for each graph node so that the
// original order will be preserved as much as possible.
- std::sort(i->begin(), i->end());
+ std::sort(edgeList.begin(), edgeList.end());
// Make the edge list unique.
- i->erase(std::unique(i->begin(), i->end()), i->end());
+ edgeList.erase(std::unique(edgeList.begin(), edgeList.end()),
+ edgeList.end());
}
}
@@ -638,7 +624,8 @@ void cmComputeLinkDepends::OrderLinkEntires()
// the same order in which the items were originally discovered in
// the BFS. This should preserve the original order when no
// constraints disallow it.
- this->CCG = new cmComputeComponentGraph(this->EntryConstraintGraph);
+ this->CCG =
+ cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph);
// The component graph is guaranteed to be acyclic. Start a DFS
// from every entry to compute a topological order for the
@@ -660,9 +647,8 @@ void cmComputeLinkDepends::OrderLinkEntires()
}
// Start with the original link line.
- for (std::vector<int>::const_iterator i = this->OriginalEntries.begin();
- i != this->OriginalEntries.end(); ++i) {
- this->VisitEntry(*i);
+ for (int originalEntry : this->OriginalEntries) {
+ this->VisitEntry(originalEntry);
}
// Now explore anything left pending. Since the component graph is
@@ -684,13 +670,12 @@ void cmComputeLinkDepends::DisplayComponents()
for (unsigned int c = 0; c < components.size(); ++c) {
fprintf(stderr, "Component (%u):\n", c);
NodeList const& nl = components[c];
- for (NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) {
- int i = *ni;
+ for (int i : nl) {
fprintf(stderr, " item %d [%s]\n", i, this->EntryList[i].Item.c_str());
}
EdgeList const& ol = this->CCG->GetComponentGraphEdges(c);
- for (EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) {
- int i = *oi;
+ for (cmGraphEdge const& oi : ol) {
+ int i = oi;
fprintf(stderr, " followed by Component (%d)\n", i);
}
fprintf(stderr, " topo order index %d\n", this->ComponentOrder[c]);
@@ -712,9 +697,8 @@ void cmComputeLinkDepends::VisitComponent(unsigned int c)
// Run in reverse order so the topological order will preserve the
// original order where there are no constraints.
EdgeList const& nl = this->CCG->GetComponentGraphEdges(c);
- for (EdgeList::const_reverse_iterator ni = nl.rbegin(); ni != nl.rend();
- ++ni) {
- this->VisitComponent(*ni);
+ for (cmGraphEdge const& edge : cmReverseRange(nl)) {
+ this->VisitComponent(edge);
}
// Assign an ordering id to this component.
@@ -729,8 +713,7 @@ void cmComputeLinkDepends::VisitEntry(int index)
// This entry has now been seen. Update its component.
bool completed = false;
int component = this->CCG->GetComponentMap()[index];
- std::map<int, PendingComponent>::iterator mi =
- this->PendingComponents.find(this->ComponentOrder[component]);
+ auto mi = this->PendingComponents.find(this->ComponentOrder[component]);
if (mi != this->PendingComponents.end()) {
// The entry is in an already pending component.
PendingComponent& pc = mi->second;
@@ -771,10 +754,10 @@ void cmComputeLinkDepends::VisitEntry(int index)
// are now pending.
if (completed) {
EdgeList const& ol = this->CCG->GetComponentGraphEdges(component);
- for (EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) {
+ for (cmGraphEdge const& oi : ol) {
// This entire component is now pending no matter whether it has
// been partially seen already.
- this->MakePendingComponent(*oi);
+ this->MakePendingComponent(oi);
}
}
}
@@ -816,8 +799,8 @@ cmComputeLinkDepends::MakePendingComponent(unsigned int component)
int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
{
unsigned int count = 2;
- for (NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) {
- if (cmGeneratorTarget const* target = this->EntryList[*ni].Target) {
+ for (int ni : nl) {
+ if (cmGeneratorTarget const* target = this->EntryList[ni].Target) {
if (cmLinkInterface const* iface =
target->GetLinkInterface(this->Config, this->Target)) {
if (iface->Multiplicity > count) {
@@ -832,13 +815,11 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
void cmComputeLinkDepends::DisplayFinalEntries()
{
fprintf(stderr, "target [%s] links to:\n", this->Target->GetName().c_str());
- for (std::vector<LinkEntry>::const_iterator lei =
- this->FinalLinkEntries.begin();
- lei != this->FinalLinkEntries.end(); ++lei) {
- if (lei->Target) {
- fprintf(stderr, " target [%s]\n", lei->Target->GetName().c_str());
+ for (LinkEntry const& lei : this->FinalLinkEntries) {
+ if (lei.Target) {
+ fprintf(stderr, " target [%s]\n", lei.Target->GetName().c_str());
} else {
- fprintf(stderr, " item [%s]\n", lei->Item.c_str());
+ fprintf(stderr, " item [%s]\n", lei.Item.c_str());
}
}
fprintf(stderr, "\n");