ENH: put the 64 bit paths first
[cmake.git] / Source / cmComputeLinkDepends.cxx
blob20b032d26636ea75a496d865c033ce1b67584b18
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkDepends.cxx,v $
5 Language: C++
6 Date: $Date: 2009-04-06 15:10:34 $
7 Version: $Revision: 1.30 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmComputeLinkDepends.h"
19 #include "cmComputeComponentGraph.h"
20 #include "cmGlobalGenerator.h"
21 #include "cmLocalGenerator.h"
22 #include "cmMakefile.h"
23 #include "cmTarget.h"
24 #include "cmake.h"
26 #include <cmsys/stl/algorithm>
28 #include <assert.h>
32 This file computes an ordered list of link items to use when linking a
33 single target in one configuration. Each link item is identified by
34 the string naming it. A graph of dependencies is created in which
35 each node corresponds to one item and directed eges lead from nodes to
36 those which must *follow* them on the link line. For example, the
37 graph
39 A -> B -> C
41 will lead to the link line order
43 A B C
45 The set of items placed in the graph is formed with a breadth-first
46 search of the link dependencies starting from the main target.
48 There are two types of items: those with known direct dependencies and
49 those without known dependencies. We will call the two types "known
50 items" and "unknown items", respecitvely. Known items are those whose
51 names correspond to targets (built or imported) and those for which an
52 old-style <item>_LIB_DEPENDS variable is defined. All other items are
53 unknown and we must infer dependencies for them. For items that look
54 like flags (beginning with '-') we trivially infer no dependencies,
55 and do not include them in the dependencies of other items.
57 Known items have dependency lists ordered based on how the user
58 specified them. We can use this order to infer potential dependencies
59 of unknown items. For example, if link items A and B are unknown and
60 items X and Y are known, then we might have the following dependency
61 lists:
63 X: Y A B
64 Y: A B
66 The explicitly known dependencies form graph edges
68 X -> Y , X -> A , X -> B , Y -> A , Y -> B
70 We can also infer the edge
72 A -> B
74 because *every* time A appears B is seen on its right. We do not know
75 whether A really needs symbols from B to link, but it *might* so we
76 must preserve their order. This is the case also for the following
77 explict lists:
79 X: A B Y
80 Y: A B
82 Here, A is followed by the set {B,Y} in one list, and {B} in the other
83 list. The intersection of these sets is {B}, so we can infer that A
84 depends on at most B. Meanwhile B is followed by the set {Y} in one
85 list and {} in the other. The intersection is {} so we can infer that
86 B has no dependencies.
88 Let's make a more complex example by adding unknown item C and
89 considering these dependency lists:
91 X: A B Y C
92 Y: A C B
94 The explicit edges are
96 X -> Y , X -> A , X -> B , X -> C , Y -> A , Y -> B , Y -> C
98 For the unknown items, we infer dependencies by looking at the
99 "follow" sets:
101 A: intersect( {B,Y,C} , {C,B} ) = {B,C} ; infer edges A -> B , A -> C
102 B: intersect( {Y,C} , {} ) = {} ; infer no edges
103 C: intersect( {} , {B} ) = {} ; infer no edges
105 Note that targets are never inferred as dependees because outside
106 libraries should not depend on them.
108 ------------------------------------------------------------------------------
110 The initial exploration of dependencies using a BFS associates an
111 integer index with each link item. When the graph is built outgoing
112 edges are sorted by this index.
114 After the initial exploration of the link interface tree, any
115 transitive (dependent) shared libraries that were encountered and not
116 included in the interface are processed in their own BFS. This BFS
117 follows only the dependent library lists and not the link interfaces.
118 They are added to the link items with a mark indicating that the are
119 transitive dependencies. Then cmComputeLinkInformation deals with
120 them on a per-platform basis.
122 The complete graph formed from all known and inferred dependencies may
123 not be acyclic, so an acyclic version must be created.
124 The original graph is converted to a directed acyclic graph in which
125 each node corresponds to a strongly connected component of the
126 original graph. For example, the dependency graph
128 X -> A -> B -> C -> A -> Y
130 contains strongly connected components {X}, {A,B,C}, and {Y}. The
131 implied directed acyclic graph (DAG) is
133 {X} -> {A,B,C} -> {Y}
135 We then compute a topological order for the DAG nodes to serve as a
136 reference for satisfying dependencies efficiently. We perform the DFS
137 in reverse order and assign topological order indices counting down so
138 that the result is as close to the original BFS order as possible
139 without violating dependencies.
141 ------------------------------------------------------------------------------
143 The final link entry order is constructed as follows. We first walk
144 through and emit the *original* link line as specified by the user.
145 As each item is emitted, a set of pending nodes in the component DAG
146 is maintained. When a pending component has been completely seen, it
147 is removed from the pending set and its dependencies (following edges
148 of the DAG) are added. A trivial component (those with one item) is
149 complete as soon as its item is seen. A non-trivial component (one
150 with more than one item; assumed to be static libraries) is complete
151 when *all* its entries have been seen *twice* (all entries seen once,
152 then all entries seen again, not just each entry twice). A pending
153 component tracks which items have been seen and a count of how many
154 times the component needs to be seen (once for trivial components,
155 twice for non-trivial). If at any time another component finishes and
156 re-adds an already pending component, the pending component is reset
157 so that it needs to be seen in its entirety again. This ensures that
158 all dependencies of a component are satisified no matter where it
159 appears.
161 After the original link line has been completed, we append to it the
162 remaining pending components and their dependencies. This is done by
163 repeatedly emitting the first item from the first pending component
164 and following the same update rules as when traversing the original
165 link line. Since the pending components are kept in topological order
166 they are emitted with minimal repeats (we do not want to emit a
167 component just to have it added again when another component is
168 completed later). This process continues until no pending components
169 remain. We know it will terminate because the component graph is
170 guaranteed to be acyclic.
172 The final list of items produced by this procedure consists of the
173 original user link line followed by minimal additional items needed to
174 satisfy dependencies.
178 //----------------------------------------------------------------------------
179 cmComputeLinkDepends
180 ::cmComputeLinkDepends(cmTarget* target, const char* config)
182 // Store context information.
183 this->Target = target;
184 this->Makefile = this->Target->GetMakefile();
185 this->LocalGenerator = this->Makefile->GetLocalGenerator();
186 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
187 this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
189 // The configuration being linked.
190 this->Config = (config && *config)? config : 0;
191 this->LinkType = this->Target->ComputeLinkType(this->Config);
193 // Enable debug mode if requested.
194 this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
196 // Assume no compatibility until set.
197 this->OldLinkDirMode = false;
199 // No computation has been done.
200 this->CCG = 0;
203 //----------------------------------------------------------------------------
204 cmComputeLinkDepends::~cmComputeLinkDepends()
206 for(std::vector<DependSetList*>::iterator
207 i = this->InferredDependSets.begin();
208 i != this->InferredDependSets.end(); ++i)
210 delete *i;
212 delete this->CCG;
215 //----------------------------------------------------------------------------
216 void cmComputeLinkDepends::SetOldLinkDirMode(bool b)
218 this->OldLinkDirMode = b;
221 //----------------------------------------------------------------------------
222 std::vector<cmComputeLinkDepends::LinkEntry> const&
223 cmComputeLinkDepends::Compute()
225 // Follow the link dependencies of the target to be linked.
226 this->AddTargetLinkEntries(-1, this->Target->GetOriginalLinkLibraries());
228 // Complete the breadth-first search of dependencies.
229 while(!this->BFSQueue.empty())
231 // Get the next entry.
232 BFSEntry qe = this->BFSQueue.front();
233 this->BFSQueue.pop();
235 // Follow the entry's dependencies.
236 this->FollowLinkEntry(qe);
239 // Complete the search of shared library dependencies.
240 while(!this->SharedDepQueue.empty())
242 // Handle the next entry.
243 this->HandleSharedDependency(this->SharedDepQueue.front());
244 this->SharedDepQueue.pop();
247 // Infer dependencies of targets for which they were not known.
248 this->InferDependencies();
250 // Cleanup the constraint graph.
251 this->CleanConstraintGraph();
253 // Display the constraint graph.
254 if(this->DebugMode)
256 fprintf(stderr,
257 "---------------------------------------"
258 "---------------------------------------\n");
259 fprintf(stderr, "Link dependency analysis for target %s, config %s\n",
260 this->Target->GetName(), this->Config?this->Config:"noconfig");
261 this->DisplayConstraintGraph();
264 // Compute the final ordering.
265 this->OrderLinkEntires();
267 // Compute the final set of link entries.
268 for(std::vector<int>::const_iterator li = this->FinalLinkOrder.begin();
269 li != this->FinalLinkOrder.end(); ++li)
271 this->FinalLinkEntries.push_back(this->EntryList[*li]);
274 // Display the final set.
275 if(this->DebugMode)
277 this->DisplayFinalEntries();
280 return this->FinalLinkEntries;
283 //----------------------------------------------------------------------------
284 std::map<cmStdString, int>::iterator
285 cmComputeLinkDepends::AllocateLinkEntry(std::string const& item)
287 std::map<cmStdString, int>::value_type
288 index_entry(item, static_cast<int>(this->EntryList.size()));
289 std::map<cmStdString, int>::iterator
290 lei = this->LinkEntryIndex.insert(index_entry).first;
291 this->EntryList.push_back(LinkEntry());
292 this->InferredDependSets.push_back(0);
293 this->EntryConstraintGraph.push_back(NodeList());
294 return lei;
297 //----------------------------------------------------------------------------
298 int cmComputeLinkDepends::AddLinkEntry(int depender_index,
299 std::string const& item)
301 // Check if the item entry has already been added.
302 std::map<cmStdString, int>::iterator lei = this->LinkEntryIndex.find(item);
303 if(lei != this->LinkEntryIndex.end())
305 // Yes. We do not need to follow the item's dependencies again.
306 return lei->second;
309 // Allocate a spot for the item entry.
310 lei = this->AllocateLinkEntry(item);
312 // Initialize the item entry.
313 int index = lei->second;
314 LinkEntry& entry = this->EntryList[index];
315 entry.Item = item;
316 entry.Target = this->FindTargetToLink(depender_index, entry.Item.c_str());
317 entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
318 item.substr(0, 10) != "-framework");
320 // If the item has dependencies queue it to follow them.
321 if(entry.Target)
323 // Target dependencies are always known. Follow them.
324 BFSEntry qe = {index, 0};
325 this->BFSQueue.push(qe);
327 else
329 // Look for an old-style <item>_LIB_DEPENDS variable.
330 std::string var = entry.Item;
331 var += "_LIB_DEPENDS";
332 if(const char* val = this->Makefile->GetDefinition(var.c_str()))
334 // The item dependencies are known. Follow them.
335 BFSEntry qe = {index, val};
336 this->BFSQueue.push(qe);
338 else if(!entry.IsFlag)
340 // The item dependencies are not known. We need to infer them.
341 this->InferredDependSets[index] = new DependSetList;
345 return index;
348 //----------------------------------------------------------------------------
349 void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
351 // Get this entry representation.
352 int depender_index = qe.Index;
353 LinkEntry const& entry = this->EntryList[depender_index];
355 // Follow the item's dependencies.
356 if(entry.Target)
358 // Follow the target dependencies.
359 if(cmTargetLinkInterface const* iface =
360 entry.Target->GetLinkInterface(this->Config))
362 // This target provides its own link interface information.
363 this->AddLinkEntries(depender_index, iface->Libraries);
365 // Handle dependent shared libraries.
366 this->QueueSharedDependencies(depender_index, iface->SharedDeps);
368 else if(!entry.Target->IsImported() &&
369 entry.Target->GetType() != cmTarget::EXECUTABLE)
371 // Use the target's link implementation as the interface.
372 this->AddTargetLinkEntries(depender_index,
373 entry.Target->GetOriginalLinkLibraries());
376 else
378 // Follow the old-style dependency list.
379 this->AddVarLinkEntries(depender_index, qe.LibDepends);
383 //----------------------------------------------------------------------------
384 void
385 cmComputeLinkDepends
386 ::QueueSharedDependencies(int depender_index,
387 std::vector<std::string> const& deps)
389 for(std::vector<std::string>::const_iterator li = deps.begin();
390 li != deps.end(); ++li)
392 SharedDepEntry qe;
393 qe.Item = *li;
394 qe.DependerIndex = depender_index;
395 this->SharedDepQueue.push(qe);
399 //----------------------------------------------------------------------------
400 void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
402 // Check if the target already has an entry.
403 std::map<cmStdString, int>::iterator lei =
404 this->LinkEntryIndex.find(dep.Item);
405 if(lei == this->LinkEntryIndex.end())
407 // Allocate a spot for the item entry.
408 lei = this->AllocateLinkEntry(dep.Item);
410 // Initialize the item entry.
411 LinkEntry& entry = this->EntryList[lei->second];
412 entry.Item = dep.Item;
413 entry.Target = this->FindTargetToLink(dep.DependerIndex,
414 dep.Item.c_str());
416 // This item was added specifically because it is a dependent
417 // shared library. It may get special treatment
418 // in cmComputeLinkInformation.
419 entry.IsSharedDep = true;
422 // Get the link entry for this target.
423 int index = lei->second;
424 LinkEntry& entry = this->EntryList[index];
426 // This shared library dependency must follow the item that listed
427 // it.
428 this->EntryConstraintGraph[dep.DependerIndex].push_back(index);
430 // Target items may have their own dependencies.
431 if(entry.Target)
433 if(cmTargetLinkInterface const* iface =
434 entry.Target->GetLinkInterface(this->Config))
436 // We use just the shared dependencies, not the interface.
437 this->QueueSharedDependencies(index, iface->SharedDeps);
442 //----------------------------------------------------------------------------
443 void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
444 const char* value)
446 // This is called to add the dependencies named by
447 // <item>_LIB_DEPENDS. The variable contains a semicolon-separated
448 // list. The list contains link-type;item pairs and just items.
449 std::vector<std::string> deplist;
450 cmSystemTools::ExpandListArgument(value, deplist);
452 // Look for entries meant for this configuration.
453 std::vector<std::string> actual_libs;
454 cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
455 bool haveLLT = false;
456 for(std::vector<std::string>::const_iterator di = deplist.begin();
457 di != deplist.end(); ++di)
459 if(*di == "debug")
461 llt = cmTarget::DEBUG;
462 haveLLT = true;
464 else if(*di == "optimized")
466 llt = cmTarget::OPTIMIZED;
467 haveLLT = true;
469 else if(*di == "general")
471 llt = cmTarget::GENERAL;
472 haveLLT = true;
474 else if(!di->empty())
476 // If no explicit link type was given prior to this entry then
477 // check if the entry has its own link type variable. This is
478 // needed for compatibility with dependency files generated by
479 // the export_library_dependencies command from CMake 2.4 and
480 // lower.
481 if(!haveLLT)
483 std::string var = *di;
484 var += "_LINK_TYPE";
485 if(const char* val = this->Makefile->GetDefinition(var.c_str()))
487 if(strcmp(val, "debug") == 0)
489 llt = cmTarget::DEBUG;
491 else if(strcmp(val, "optimized") == 0)
493 llt = cmTarget::OPTIMIZED;
498 // If the library is meant for this link type then use it.
499 if(llt == cmTarget::GENERAL || llt == this->LinkType)
501 actual_libs.push_back(*di);
503 else if(this->OldLinkDirMode)
505 this->CheckWrongConfigItem(depender_index, *di);
508 // Reset the link type until another explicit type is given.
509 llt = cmTarget::GENERAL;
510 haveLLT = false;
514 // Add the entries from this list.
515 this->AddLinkEntries(depender_index, actual_libs);
518 //----------------------------------------------------------------------------
519 void
520 cmComputeLinkDepends::AddTargetLinkEntries(int depender_index,
521 LinkLibraryVectorType const& libs)
523 // Look for entries meant for this configuration.
524 std::vector<std::string> actual_libs;
525 for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
526 li != libs.end(); ++li)
528 if(li->second == cmTarget::GENERAL || li->second == this->LinkType)
530 actual_libs.push_back(li->first);
532 else if(this->OldLinkDirMode)
534 this->CheckWrongConfigItem(depender_index, li->first);
538 // Add these entries.
539 this->AddLinkEntries(depender_index, actual_libs);
542 //----------------------------------------------------------------------------
543 void
544 cmComputeLinkDepends::AddLinkEntries(int depender_index,
545 std::vector<std::string> const& libs)
547 // Track inferred dependency sets implied by this list.
548 std::map<int, DependSet> dependSets;
550 // Loop over the libraries linked directly by the depender.
551 for(std::vector<std::string>::const_iterator li = libs.begin();
552 li != libs.end(); ++li)
554 // Skip entries that will resolve to the target getting linked or
555 // are empty.
556 std::string item = this->CleanItemName(*li);
557 if(item == this->Target->GetName() || item.empty())
559 continue;
562 // Add a link entry for this item.
563 int dependee_index = this->AddLinkEntry(depender_index, item);
565 // The dependee must come after the depender.
566 if(depender_index >= 0)
568 this->EntryConstraintGraph[depender_index].push_back(dependee_index);
570 else
572 // This is a direct dependency of the target being linked.
573 this->OriginalEntries.push_back(dependee_index);
576 // Update the inferred dependencies for earlier items.
577 for(std::map<int, DependSet>::iterator dsi = dependSets.begin();
578 dsi != dependSets.end(); ++dsi)
580 // Add this item to the inferred dependencies of other items.
581 // Target items are never inferred dependees because unknown
582 // items are outside libraries that should not be depending on
583 // targets.
584 if(!this->EntryList[dependee_index].Target &&
585 !this->EntryList[dependee_index].IsFlag &&
586 dependee_index != dsi->first)
588 dsi->second.insert(dependee_index);
592 // If this item needs to have dependencies inferred, do so.
593 if(this->InferredDependSets[dependee_index])
595 // Make sure an entry exists to hold the set for the item.
596 dependSets[dependee_index];
600 // Store the inferred dependency sets discovered for this list.
601 for(std::map<int, DependSet>::iterator dsi = dependSets.begin();
602 dsi != dependSets.end(); ++dsi)
604 this->InferredDependSets[dsi->first]->push_back(dsi->second);
608 //----------------------------------------------------------------------------
609 std::string cmComputeLinkDepends::CleanItemName(std::string const& item)
611 // Strip whitespace off the library names because we used to do this
612 // in case variables were expanded at generate time. We no longer
613 // do the expansion but users link to libraries like " ${VAR} ".
614 std::string lib = item;
615 std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
616 if(pos != lib.npos)
618 lib = lib.substr(pos, lib.npos);
620 pos = lib.find_last_not_of(" \t\r\n");
621 if(pos != lib.npos)
623 lib = lib.substr(0, pos+1);
625 if(lib != item)
627 switch(this->Target->GetPolicyStatusCMP0004())
629 case cmPolicies::WARN:
631 cmOStringStream w;
632 w << (this->Makefile->GetPolicies()
633 ->GetPolicyWarning(cmPolicies::CMP0004)) << "\n"
634 << "Target \"" << this->Target->GetName() << "\" links to item \""
635 << item << "\" which has leading or trailing whitespace.";
636 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
637 this->Target->GetBacktrace());
639 case cmPolicies::OLD:
640 break;
641 case cmPolicies::NEW:
643 cmOStringStream e;
644 e << "Target \"" << this->Target->GetName() << "\" links to item \""
645 << item << "\" which has leading or trailing whitespace. "
646 << "This is now an error according to policy CMP0004.";
647 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
648 this->Target->GetBacktrace());
650 break;
651 case cmPolicies::REQUIRED_IF_USED:
652 case cmPolicies::REQUIRED_ALWAYS:
654 cmOStringStream e;
655 e << (this->Makefile->GetPolicies()
656 ->GetRequiredPolicyError(cmPolicies::CMP0004)) << "\n"
657 << "Target \"" << this->Target->GetName() << "\" links to item \""
658 << item << "\" which has leading or trailing whitespace.";
659 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
660 this->Target->GetBacktrace());
662 break;
665 return lib;
668 //----------------------------------------------------------------------------
669 cmTarget* cmComputeLinkDepends::FindTargetToLink(int depender_index,
670 const char* name)
672 // Look for a target in the scope of the depender.
673 cmMakefile* mf = this->Makefile;
674 if(depender_index >= 0)
676 if(cmTarget* depender = this->EntryList[depender_index].Target)
678 mf = depender->GetMakefile();
681 cmTarget* tgt = mf->FindTargetToUse(name);
683 // Skip targets that will not really be linked. This is probably a
684 // name conflict between an external library and an executable
685 // within the project.
686 if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
687 !tgt->IsExecutableWithExports())
689 tgt = 0;
692 // Return the target found, if any.
693 return tgt;
696 //----------------------------------------------------------------------------
697 void cmComputeLinkDepends::InferDependencies()
699 // The inferred dependency sets for each item list the possible
700 // dependencies. The intersection of the sets for one item form its
701 // inferred dependencies.
702 for(unsigned int depender_index=0;
703 depender_index < this->InferredDependSets.size(); ++depender_index)
705 // Skip items for which dependencies do not need to be inferred or
706 // for which the inferred dependency sets are empty.
707 DependSetList* sets = this->InferredDependSets[depender_index];
708 if(!sets || sets->empty())
710 continue;
713 // Intersect the sets for this item.
714 DependSetList::const_iterator i = sets->begin();
715 DependSet common = *i;
716 for(++i; i != sets->end(); ++i)
718 DependSet intersection;
719 cmsys_stl::set_intersection
720 (common.begin(), common.end(), i->begin(), i->end(),
721 std::inserter(intersection, intersection.begin()));
722 common = intersection;
725 // Add the inferred dependencies to the graph.
726 for(DependSet::const_iterator j = common.begin(); j != common.end(); ++j)
728 int dependee_index = *j;
729 this->EntryConstraintGraph[depender_index].push_back(dependee_index);
734 //----------------------------------------------------------------------------
735 void cmComputeLinkDepends::CleanConstraintGraph()
737 for(Graph::iterator i = this->EntryConstraintGraph.begin();
738 i != this->EntryConstraintGraph.end(); ++i)
740 // Sort the outgoing edges for each graph node so that the
741 // original order will be preserved as much as possible.
742 cmsys_stl::sort(i->begin(), i->end());
744 // Make the edge list unique.
745 NodeList::iterator last = cmsys_stl::unique(i->begin(), i->end());
746 i->erase(last, i->end());
750 //----------------------------------------------------------------------------
751 void cmComputeLinkDepends::DisplayConstraintGraph()
753 // Display the graph nodes and their edges.
754 cmOStringStream e;
755 for(unsigned int i=0; i < this->EntryConstraintGraph.size(); ++i)
757 NodeList const& nl = this->EntryConstraintGraph[i];
758 e << "item " << i << " is [" << this->EntryList[i].Item << "]\n";
759 for(NodeList::const_iterator j = nl.begin(); j != nl.end(); ++j)
761 e << " item " << *j << " must follow it\n";
764 fprintf(stderr, "%s\n", e.str().c_str());
767 //----------------------------------------------------------------------------
768 void cmComputeLinkDepends::OrderLinkEntires()
770 // Compute the DAG of strongly connected components. The algorithm
771 // used by cmComputeComponentGraph should identify the components in
772 // the same order in which the items were originally discovered in
773 // the BFS. This should preserve the original order when no
774 // constraints disallow it.
775 this->CCG = new cmComputeComponentGraph(this->EntryConstraintGraph);
777 // The component graph is guaranteed to be acyclic. Start a DFS
778 // from every entry to compute a topological order for the
779 // components.
780 Graph const& cgraph = this->CCG->GetComponentGraph();
781 int n = static_cast<int>(cgraph.size());
782 this->ComponentVisited.resize(cgraph.size(), 0);
783 this->ComponentOrder.resize(cgraph.size(), n);
784 this->ComponentOrderId = n;
785 // Run in reverse order so the topological order will preserve the
786 // original order where there are no constraints.
787 for(int c = n-1; c >= 0; --c)
789 this->VisitComponent(c);
792 // Display the component graph.
793 if(this->DebugMode)
795 this->DisplayComponents();
798 // Start with the original link line.
799 for(std::vector<int>::const_iterator i = this->OriginalEntries.begin();
800 i != this->OriginalEntries.end(); ++i)
802 this->VisitEntry(*i);
805 // Now explore anything left pending. Since the component graph is
806 // guaranteed to be acyclic we know this will terminate.
807 while(!this->PendingComponents.empty())
809 // Visit one entry from the first pending component. The visit
810 // logic will update the pending components accordingly. Since
811 // the pending components are kept in topological order this will
812 // not repeat one.
813 int e = *this->PendingComponents.begin()->second.Entries.begin();
814 this->VisitEntry(e);
818 //----------------------------------------------------------------------------
819 void
820 cmComputeLinkDepends::DisplayComponents()
822 fprintf(stderr, "The strongly connected components are:\n");
823 std::vector<NodeList> const& components = this->CCG->GetComponents();
824 for(unsigned int c=0; c < components.size(); ++c)
826 fprintf(stderr, "Component (%u):\n", c);
827 NodeList const& nl = components[c];
828 for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
830 int i = *ni;
831 fprintf(stderr, " item %d [%s]\n", i,
832 this->EntryList[i].Item.c_str());
834 NodeList const& ol = this->CCG->GetComponentGraphEdges(c);
835 for(NodeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
837 fprintf(stderr, " followed by Component (%d)\n", *oi);
839 fprintf(stderr, " topo order index %d\n",
840 this->ComponentOrder[c]);
842 fprintf(stderr, "\n");
845 //----------------------------------------------------------------------------
846 void cmComputeLinkDepends::VisitComponent(unsigned int c)
848 // Check if the node has already been visited.
849 if(this->ComponentVisited[c])
851 return;
854 // We are now visiting this component so mark it.
855 this->ComponentVisited[c] = 1;
857 // Visit the neighbors of the component first.
858 // Run in reverse order so the topological order will preserve the
859 // original order where there are no constraints.
860 NodeList const& nl = this->CCG->GetComponentGraphEdges(c);
861 for(NodeList::const_reverse_iterator ni = nl.rbegin();
862 ni != nl.rend(); ++ni)
864 this->VisitComponent(*ni);
867 // Assign an ordering id to this component.
868 this->ComponentOrder[c] = --this->ComponentOrderId;
871 //----------------------------------------------------------------------------
872 void cmComputeLinkDepends::VisitEntry(int index)
874 // Include this entry on the link line.
875 this->FinalLinkOrder.push_back(index);
877 // This entry has now been seen. Update its component.
878 bool completed = false;
879 int component = this->CCG->GetComponentMap()[index];
880 std::map<int, PendingComponent>::iterator mi =
881 this->PendingComponents.find(this->ComponentOrder[component]);
882 if(mi != this->PendingComponents.end())
884 // The entry is in an already pending component.
885 PendingComponent& pc = mi->second;
887 // Remove the entry from those pending in its component.
888 pc.Entries.erase(index);
889 if(pc.Entries.empty())
891 // The complete component has been seen since it was last needed.
892 --pc.Count;
894 if(pc.Count == 0)
896 // The component has been completed.
897 this->PendingComponents.erase(mi);
898 completed = true;
900 else
902 // The whole component needs to be seen again.
903 NodeList const& nl = this->CCG->GetComponent(component);
904 assert(nl.size() > 1);
905 pc.Entries.insert(nl.begin(), nl.end());
909 else
911 // The entry is not in an already pending component.
912 NodeList const& nl = this->CCG->GetComponent(component);
913 if(nl.size() > 1)
915 // This is a non-trivial component. It is now pending.
916 PendingComponent& pc = this->MakePendingComponent(component);
918 // The starting entry has already been seen.
919 pc.Entries.erase(index);
921 else
923 // This is a trivial component, so it is already complete.
924 completed = true;
928 // If the entry completed a component, the component's dependencies
929 // are now pending.
930 if(completed)
932 NodeList const& ol = this->CCG->GetComponentGraphEdges(component);
933 for(NodeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
935 // This entire component is now pending no matter whether it has
936 // been partially seen already.
937 this->MakePendingComponent(*oi);
942 //----------------------------------------------------------------------------
943 cmComputeLinkDepends::PendingComponent&
944 cmComputeLinkDepends::MakePendingComponent(unsigned int component)
946 // Create an entry (in topological order) for the component.
947 PendingComponent& pc =
948 this->PendingComponents[this->ComponentOrder[component]];
949 pc.Id = component;
950 NodeList const& nl = this->CCG->GetComponent(component);
952 if(nl.size() == 1)
954 // Trivial components need be seen only once.
955 pc.Count = 1;
957 else
959 // This is a non-trivial strongly connected component of the
960 // original graph. It consists of two or more libraries
961 // (archives) that mutually require objects from one another. In
962 // the worst case we may have to repeat the list of libraries as
963 // many times as there are object files in the biggest archive.
964 // For now we just list them twice.
966 // The list of items in the component has been sorted by the order
967 // of discovery in the original BFS of dependencies. This has the
968 // advantage that the item directly linked by a target requiring
969 // this component will come first which minimizes the number of
970 // repeats needed.
971 pc.Count = 2;
974 // Store the entries to be seen.
975 pc.Entries.insert(nl.begin(), nl.end());
977 return pc;
980 //----------------------------------------------------------------------------
981 void cmComputeLinkDepends::DisplayFinalEntries()
983 fprintf(stderr, "target [%s] links to:\n", this->Target->GetName());
984 for(std::vector<LinkEntry>::const_iterator lei =
985 this->FinalLinkEntries.begin();
986 lei != this->FinalLinkEntries.end(); ++lei)
988 if(lei->Target)
990 fprintf(stderr, " target [%s]\n", lei->Target->GetName());
992 else
994 fprintf(stderr, " item [%s]\n", lei->Item.c_str());
997 fprintf(stderr, "\n");
1000 //----------------------------------------------------------------------------
1001 void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
1002 std::string const& item)
1004 if(!this->OldLinkDirMode)
1006 return;
1009 // For CMake 2.4 bug-compatibility we need to consider the output
1010 // directories of targets linked in another configuration as link
1011 // directories.
1012 if(cmTarget* tgt = this->FindTargetToLink(depender_index, item.c_str()))
1014 if(!tgt->IsImported())
1016 this->OldWrongConfigItems.insert(tgt);