1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkDepends.cxx,v $
6 Date: $Date: 2008/02/13 20:29:55 $
7 Version: $Revision: 1.11 $
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"
25 #include <cmsys/stl/algorithm>
31 This file computes an ordered list of link items to use when linking a
32 single target in one configuration. Each link item is identified by
33 the string naming it. A graph of dependencies is created in which
34 each node corresponds to one item and directed eges lead from nodes to
35 those which must *precede* them on the link line. For example, the
40 will lead to the link line order
44 The set of items placed in the graph is formed with a breadth-first
45 search of the link dependencies starting from the main target.
47 There are two types of items: those with known direct dependencies and
48 those without known dependencies. We will call the two types "known
49 items" and "unknown items", respecitvely. Known items are those whose
50 names correspond to targets (built or imported) and those for which an
51 old-style <item>_LIB_DEPENDS variable is defined. All other items are
52 unknown and we must infer dependencies for them.
54 Known items have dependency lists ordered based on how the user
55 specified them. We can use this order to infer potential dependencies
56 of unknown items. For example, if link items A and B are unknown and
57 items X and Y are known, then we might have the following dependency
63 The explicitly known dependencies form graph edges
65 X <- Y , X <- A , X <- B , Y <- A , Y <- B
67 We can also infer the edge
71 because *every* time A appears B is seen on its right. We do not know
72 whether A really needs symbols from B to link, but it *might* so we
73 must preserve their order. This is the case also for the following
79 Here, A is followed by the set {B,Y} in one list, and {B} in the other
80 list. The intersection of these sets is {B}, so we can infer that A
81 depends on at most B. Meanwhile B is followed by the set {Y} in one
82 list and {} in the other. The intersection is {} so we can infer that
83 B has no dependencies.
85 Let's make a more complex example by adding unknown item C and
86 considering these dependency lists:
91 The explicit edges are
93 X <- Y , X <- A , X <- B , X <- C , Y <- A , Y <- B , Y <- C
95 For the unknown items, we infer dependencies by looking at the
98 A: intersect( {B,Y,C} , {C,B} ) = {B,C} ; infer edges A <- B , A <- C
99 B: intersect( {Y,C} , {} ) = {} ; infer no edges
100 C: intersect( {} , {B} ) = {} ; infer no edges
102 ------------------------------------------------------------------------------
104 Once the complete graph is formed from all known and inferred
105 dependencies we must use it to produce a valid link line. If the
106 dependency graph were known to be acyclic a simple depth-first-search
107 would produce a correct link line. Unfortunately we cannot make this
108 assumption so the following technique is used.
110 The original graph is converted to a directed acyclic graph in which
111 each node corresponds to a strongly connected component of the
112 original graph. For example, the dependency graph
114 X <- A <- B <- C <- A <- Y
116 contains strongly connected components {X}, {A,B,C}, and {Y}. The
117 implied directed acyclic graph (DAG) is
119 {X} <- {A,B,C} <- {Y}
121 The final list of link items is constructed by a series of
122 depth-first-searches through this DAG of components. When visiting a
123 component all outgoing edges are followed first because the neighbors
124 must precede it. Once neighbors across all edges have been emitted it
125 is safe to emit the current component.
127 Trivial components (those with one item) are handled simply by
128 emitting the item. Non-trivial components (those with more than one
129 item) are assumed to consist only of static libraries that may be
130 safely repeated on the link line. We emit members of the component
131 multiple times (see code below for details). The final link line for
132 the example graph might be
136 ------------------------------------------------------------------------------
138 The initial exploration of dependencies using a BFS associates an
139 integer index with each link item. When the graph is built outgoing
140 edges are sorted by this index.
142 This preserves the original link
143 order as much as possible subject to the dependencies.
145 After the initial exploration of the link interface tree, any
146 transitive (dependent) shared libraries that were encountered and not
147 included in the interface are processed in their own BFS. This BFS
148 follows only the dependent library lists and not the link interfaces.
149 They are added to the link items with a mark indicating that the are
150 transitive dependencies. Then cmComputeLinkInformation deals with
151 them on a per-platform basis.
155 //----------------------------------------------------------------------------
157 ::cmComputeLinkDepends(cmTarget
* target
, const char* config
)
159 // Store context information.
160 this->Target
= target
;
161 this->Makefile
= this->Target
->GetMakefile();
162 this->LocalGenerator
= this->Makefile
->GetLocalGenerator();
163 this->GlobalGenerator
= this->LocalGenerator
->GetGlobalGenerator();
165 // The configuration being linked.
166 this->Config
= config
;
168 // Enable debug mode if requested.
169 this->DebugMode
= this->Makefile
->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
172 //----------------------------------------------------------------------------
173 cmComputeLinkDepends::~cmComputeLinkDepends()
175 for(std::vector
<DependSetList
*>::iterator
176 i
= this->InferredDependSets
.begin();
177 i
!= this->InferredDependSets
.end(); ++i
)
183 //----------------------------------------------------------------------------
184 std::vector
<cmComputeLinkDepends::LinkEntry
> const&
185 cmComputeLinkDepends::Compute()
187 // Follow the link dependencies of the target to be linked.
188 this->AddTargetLinkEntries(-1, this->Target
->GetOriginalLinkLibraries());
190 // Complete the breadth-first search of dependencies.
191 while(!this->BFSQueue
.empty())
193 // Get the next entry.
194 BFSEntry qe
= this->BFSQueue
.front();
195 this->BFSQueue
.pop();
197 // Follow the entry's dependencies.
198 this->FollowLinkEntry(qe
);
201 // Complete the search of shared library dependencies.
202 while(!this->SharedDepQueue
.empty())
204 // Handle the next entry.
205 this->HandleSharedDependency(this->SharedDepQueue
.front());
206 this->SharedDepQueue
.pop();
209 // Infer dependencies of targets for which they were not known.
210 this->InferDependencies();
212 // Cleanup the constraint graph.
213 this->CleanConstraintGraph();
215 // Display the constraint graph.
219 "---------------------------------------"
220 "---------------------------------------\n");
221 fprintf(stderr
, "Link dependency analysis for target %s, config %s\n",
222 this->Target
->GetName(), this->Config
?this->Config
:"noconfig");
223 this->DisplayConstraintGraph();
226 // Compute the final set of link entries.
227 this->OrderLinkEntires();
229 // Display the final set.
232 this->DisplayFinalEntries();
235 return this->FinalLinkEntries
;
238 //----------------------------------------------------------------------------
239 std::map
<cmStdString
, int>::iterator
240 cmComputeLinkDepends::AllocateLinkEntry(std::string
const& item
)
242 std::map
<cmStdString
, int>::value_type
243 index_entry(item
, static_cast<int>(this->EntryList
.size()));
244 std::map
<cmStdString
, int>::iterator
245 lei
= this->LinkEntryIndex
.insert(index_entry
).first
;
246 this->EntryList
.push_back(LinkEntry());
247 this->InferredDependSets
.push_back(0);
248 this->EntryConstraintGraph
.push_back(NodeList());
252 //----------------------------------------------------------------------------
253 int cmComputeLinkDepends::AddLinkEntry(std::string
const& item
)
255 // Check if the item entry has already been added.
256 std::map
<cmStdString
, int>::iterator lei
= this->LinkEntryIndex
.find(item
);
257 if(lei
!= this->LinkEntryIndex
.end())
259 // Yes. We do not need to follow the item's dependencies again.
263 // Allocate a spot for the item entry.
264 lei
= this->AllocateLinkEntry(item
);
266 // Initialize the item entry.
267 int index
= lei
->second
;
268 LinkEntry
& entry
= this->EntryList
[index
];
270 entry
.Target
= this->Makefile
->FindTargetToUse(entry
.Item
.c_str());
272 // If the item has dependencies queue it to follow them.
275 // Target dependencies are always known. Follow them.
276 BFSEntry qe
= {index
, 0};
277 this->BFSQueue
.push(qe
);
281 // Look for an old-style <item>_LIB_DEPENDS variable.
282 std::string var
= entry
.Item
;
283 var
+= "_LIB_DEPENDS";
284 if(const char* val
= this->Makefile
->GetDefinition(var
.c_str()))
286 // The item dependencies are known. Follow them.
287 BFSEntry qe
= {index
, val
};
288 this->BFSQueue
.push(qe
);
292 // The item dependencies are not known. We need to infer them.
293 this->InferredDependSets
[index
] = new DependSetList
;
300 //----------------------------------------------------------------------------
301 void cmComputeLinkDepends::FollowLinkEntry(BFSEntry
const& qe
)
303 // Get this entry representation.
304 int depender_index
= qe
.Index
;
305 LinkEntry
const& entry
= this->EntryList
[depender_index
];
307 // Follow the item's dependencies.
310 // Follow the target dependencies.
311 if(cmTargetLinkInterface
const* interface
=
312 entry
.Target
->GetLinkInterface(this->Config
))
314 // This target provides its own link interface information.
315 this->AddLinkEntries(depender_index
, interface
->Libraries
);
317 // Handle dependent shared libraries.
318 this->QueueSharedDependencies(depender_index
, interface
->SharedDeps
);
320 else if(!entry
.Target
->IsImported() &&
321 entry
.Target
->GetType() != cmTarget::EXECUTABLE
)
323 // Use the target's link implementation as the interface.
324 this->AddTargetLinkEntries(depender_index
,
325 entry
.Target
->GetOriginalLinkLibraries());
330 // Follow the old-style dependency list.
331 this->AddVarLinkEntries(depender_index
, qe
.LibDepends
);
335 //----------------------------------------------------------------------------
338 ::QueueSharedDependencies(int depender_index
,
339 std::vector
<std::string
> const& deps
)
341 for(std::vector
<std::string
>::const_iterator li
= deps
.begin();
342 li
!= deps
.end(); ++li
)
346 qe
.DependerIndex
= depender_index
;
347 this->SharedDepQueue
.push(qe
);
351 //----------------------------------------------------------------------------
352 void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry
const& dep
)
354 // Check if the target already has an entry.
355 std::map
<cmStdString
, int>::iterator lei
=
356 this->LinkEntryIndex
.find(dep
.Item
);
357 if(lei
== this->LinkEntryIndex
.end())
359 // Allocate a spot for the item entry.
360 lei
= this->AllocateLinkEntry(dep
.Item
);
362 // Initialize the item entry.
363 LinkEntry
& entry
= this->EntryList
[lei
->second
];
364 entry
.Item
= dep
.Item
;
365 entry
.Target
= this->Makefile
->FindTargetToUse(dep
.Item
.c_str());
367 // This item was added specifically because it is a dependent
368 // shared library. It may get special treatment
369 // in cmComputeLinkInformation.
370 entry
.IsSharedDep
= true;
373 // Get the link entry for this target.
374 int index
= lei
->second
;
375 LinkEntry
& entry
= this->EntryList
[index
];
377 // This shared library dependency must be preceded by the item that
379 this->EntryConstraintGraph
[index
].push_back(dep
.DependerIndex
);
381 // Target items may have their own dependencies.
384 if(cmTargetLinkInterface
const* interface
=
385 entry
.Target
->GetLinkInterface(this->Config
))
387 // We use just the shared dependencies, not the interface.
388 this->QueueSharedDependencies(index
, interface
->SharedDeps
);
393 //----------------------------------------------------------------------------
394 void cmComputeLinkDepends::AddVarLinkEntries(int depender_index
,
397 // This is called to add the dependencies named by
398 // <item>_LIB_DEPENDS. The variable contains a semicolon-separated
399 // list. The list contains link-type;item pairs and just items.
400 std::vector
<std::string
> deplist
;
401 cmSystemTools::ExpandListArgument(value
, deplist
);
403 // Compute which library configuration to link.
404 cmTarget::LinkLibraryType linkType
= cmTarget::OPTIMIZED
;
405 if(this->Config
&& cmSystemTools::UpperCase(this->Config
) == "DEBUG")
407 linkType
= cmTarget::DEBUG
;
410 // Look for entries meant for this configuration.
411 std::vector
<std::string
> actual_libs
;
412 cmTarget::LinkLibraryType llt
= cmTarget::GENERAL
;
413 bool haveLLT
= false;
414 for(std::vector
<std::string
>::const_iterator di
= deplist
.begin();
415 di
!= deplist
.end(); ++di
)
419 llt
= cmTarget::DEBUG
;
422 else if(*di
== "optimized")
424 llt
= cmTarget::OPTIMIZED
;
427 else if(*di
== "general")
429 llt
= cmTarget::GENERAL
;
432 else if(!di
->empty())
434 // If no explicit link type was given prior to this entry then
435 // check if the entry has its own link type variable. This is
436 // needed for compatibility with dependency files generated by
437 // the export_library_dependencies command from CMake 2.4 and
441 std::string var
= *di
;
443 if(const char* val
= this->Makefile
->GetDefinition(var
.c_str()))
445 if(strcmp(val
, "debug") == 0)
447 llt
= cmTarget::DEBUG
;
449 else if(strcmp(val
, "optimized") == 0)
451 llt
= cmTarget::OPTIMIZED
;
456 // If the library is meant for this link type then use it.
457 if(llt
== cmTarget::GENERAL
|| llt
== linkType
)
459 actual_libs
.push_back(*di
);
462 // Reset the link type until another explicit type is given.
463 llt
= cmTarget::GENERAL
;
468 // Add the entries from this list.
469 this->AddLinkEntries(depender_index
, actual_libs
);
472 //----------------------------------------------------------------------------
474 cmComputeLinkDepends::AddTargetLinkEntries(int depender_index
,
475 LinkLibraryVectorType
const& libs
)
477 // Compute which library configuration to link.
478 cmTarget::LinkLibraryType linkType
= cmTarget::OPTIMIZED
;
479 if(this->Config
&& cmSystemTools::UpperCase(this->Config
) == "DEBUG")
481 linkType
= cmTarget::DEBUG
;
484 // Look for entries meant for this configuration.
485 std::vector
<std::string
> actual_libs
;
486 for(cmTarget::LinkLibraryVectorType::const_iterator li
= libs
.begin();
487 li
!= libs
.end(); ++li
)
489 if(li
->second
== cmTarget::GENERAL
|| li
->second
== linkType
)
491 actual_libs
.push_back(li
->first
);
495 // Add these entries.
496 this->AddLinkEntries(depender_index
, actual_libs
);
499 //----------------------------------------------------------------------------
501 cmComputeLinkDepends::AddLinkEntries(int depender_index
,
502 std::vector
<std::string
> const& libs
)
504 // Track inferred dependency sets implied by this list.
505 std::map
<int, DependSet
> dependSets
;
507 // Loop over the libraries linked directly by the depender.
508 for(std::vector
<std::string
>::const_iterator li
= libs
.begin();
509 li
!= libs
.end(); ++li
)
511 // Skip entries that will resolve to the target getting linked or
513 std::string item
= this->CleanItemName(*li
);
514 if(item
== this->Target
->GetName() || item
.empty())
519 // Add a link entry for this item.
520 int dependee_index
= this->AddLinkEntry(item
);
522 // The depender must come before the dependee.
523 if(depender_index
>= 0)
525 this->EntryConstraintGraph
[dependee_index
].push_back(depender_index
);
528 // Update the inferred dependencies for earlier items.
529 for(std::map
<int, DependSet
>::iterator dsi
= dependSets
.begin();
530 dsi
!= dependSets
.end(); ++dsi
)
532 if(dependee_index
!= dsi
->first
)
534 dsi
->second
.insert(dependee_index
);
538 // If this item needs to have dependencies inferred, do so.
539 if(this->InferredDependSets
[dependee_index
])
541 // Make sure an entry exists to hold the set for the item.
542 dependSets
[dependee_index
];
546 // Store the inferred dependency sets discovered for this list.
547 for(std::map
<int, DependSet
>::iterator dsi
= dependSets
.begin();
548 dsi
!= dependSets
.end(); ++dsi
)
550 this->InferredDependSets
[dsi
->first
]->push_back(dsi
->second
);
554 //----------------------------------------------------------------------------
555 std::string
cmComputeLinkDepends::CleanItemName(std::string
const& item
)
557 // Strip whitespace off the library names because we used to do this
558 // in case variables were expanded at generate time. We no longer
559 // do the expansion but users link to libraries like " ${VAR} ".
560 std::string lib
= item
;
561 std::string::size_type pos
= lib
.find_first_not_of(" \t\r\n");
564 lib
= lib
.substr(pos
, lib
.npos
);
566 pos
= lib
.find_last_not_of(" \t\r\n");
569 lib
= lib
.substr(0, pos
+1);
571 if(lib
!= item
&& !this->Makefile
->NeedBackwardsCompatibility(2,4))
574 e
<< "Target \"" << this->Target
->GetName() << "\" links to item \""
575 << item
<< "\" which has leading or trailing whitespace. "
576 << "CMake is stripping off the whitespace but this may not be "
577 << "supported in the future. "
578 << "Update the CMakeLists.txt files to avoid adding the whitespace. "
579 << "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.4 or lower to disable this "
581 cmSystemTools::Message(e
.str().c_str());
586 //----------------------------------------------------------------------------
587 void cmComputeLinkDepends::InferDependencies()
589 // The inferred dependency sets for each item list the possible
590 // dependencies. The intersection of the sets for one item form its
591 // inferred dependencies.
592 for(unsigned int depender_index
=0;
593 depender_index
< this->InferredDependSets
.size(); ++depender_index
)
595 // Skip items for which dependencies do not need to be inferred or
596 // for which the inferred dependency sets are empty.
597 DependSetList
* sets
= this->InferredDependSets
[depender_index
];
598 if(!sets
|| sets
->empty())
603 // Intersect the sets for this item.
604 DependSetList::const_iterator i
= sets
->begin();
605 DependSet common
= *i
;
606 for(++i
; i
!= sets
->end(); ++i
)
608 DependSet intersection
;
609 cmsys_stl::set_intersection
610 (common
.begin(), common
.end(), i
->begin(), i
->end(),
611 std::inserter(intersection
, intersection
.begin()));
612 common
= intersection
;
615 // Add the inferred dependencies to the graph.
616 for(DependSet::const_iterator j
= common
.begin(); j
!= common
.end(); ++j
)
618 int dependee_index
= *j
;
619 this->EntryConstraintGraph
[dependee_index
].push_back(depender_index
);
624 //----------------------------------------------------------------------------
625 void cmComputeLinkDepends::CleanConstraintGraph()
627 for(Graph::iterator i
= this->EntryConstraintGraph
.begin();
628 i
!= this->EntryConstraintGraph
.end(); ++i
)
630 // Sort the outgoing edges for each graph node so that the
631 // original order will be preserved as much as possible.
632 cmsys_stl::sort(i
->begin(), i
->end());
634 // Make the edge list unique.
635 NodeList::iterator last
= cmsys_stl::unique(i
->begin(), i
->end());
636 i
->erase(last
, i
->end());
640 //----------------------------------------------------------------------------
641 void cmComputeLinkDepends::DisplayConstraintGraph()
643 // Display the graph nodes and their edges.
645 for(unsigned int i
=0; i
< this->EntryConstraintGraph
.size(); ++i
)
647 NodeList
const& nl
= this->EntryConstraintGraph
[i
];
648 e
<< "item " << i
<< " is [" << this->EntryList
[i
].Item
<< "]\n";
649 for(NodeList::const_iterator j
= nl
.begin(); j
!= nl
.end(); ++j
)
651 e
<< " item " << *j
<< " must precede it\n";
654 fprintf(stderr
, "%s\n", e
.str().c_str());
657 //----------------------------------------------------------------------------
658 void cmComputeLinkDepends::OrderLinkEntires()
660 // Compute the DAG of strongly connected components. The algorithm
661 // used by cmComputeComponentGraph should identify the components in
662 // the same order in which the items were originally discovered in
663 // the BFS. This should preserve the original order when no
664 // constraints disallow it.
665 cmComputeComponentGraph
ccg(this->EntryConstraintGraph
);
666 Graph
const& cgraph
= ccg
.GetComponentGraph();
669 this->DisplayComponents(ccg
);
672 // Setup visit tracking.
673 this->ComponentVisited
.resize(cgraph
.size(), 0);
675 // The component graph is guaranteed to be acyclic. Start a DFS
677 for(unsigned int c
=0; c
< cgraph
.size(); ++c
)
679 this->VisitComponent(ccg
, c
);
683 //----------------------------------------------------------------------------
685 cmComputeLinkDepends::DisplayComponents(cmComputeComponentGraph
const& ccg
)
687 fprintf(stderr
, "The strongly connected components are:\n");
688 std::vector
<NodeList
> const& components
= ccg
.GetComponents();
689 for(unsigned int c
=0; c
< components
.size(); ++c
)
691 fprintf(stderr
, "Component (%u):\n", c
);
692 NodeList
const& nl
= components
[c
];
693 for(NodeList::const_iterator ni
= nl
.begin(); ni
!= nl
.end(); ++ni
)
696 fprintf(stderr
, " item %d [%s]\n", i
,
697 this->EntryList
[i
].Item
.c_str());
700 fprintf(stderr
, "\n");
703 //----------------------------------------------------------------------------
705 cmComputeLinkDepends::VisitComponent(cmComputeComponentGraph
const& ccg
,
708 // Check if the node has already been visited.
709 if(this->ComponentVisited
[c
])
714 // We are now visiting this component so mark it.
715 this->ComponentVisited
[c
] = 1;
717 // Visit the neighbors of the component first.
718 NodeList
const& nl
= ccg
.GetComponentGraphEdges(c
);
719 for(NodeList::const_iterator ni
= nl
.begin(); ni
!= nl
.end(); ++ni
)
721 this->VisitComponent(ccg
, *ni
);
724 // Now that all items required to come before this one have been
725 // emmitted, emit this component's items.
726 this->EmitComponent(ccg
.GetComponent(c
));
729 //----------------------------------------------------------------------------
730 void cmComputeLinkDepends::EmitComponent(NodeList
const& nl
)
734 // Handle trivial components.
737 this->FinalLinkEntries
.push_back(this->EntryList
[nl
[0]]);
741 // This is a non-trivial strongly connected component of the
742 // original graph. It consists of two or more libraries (archives)
743 // that mutually require objects from one another. In the worst
744 // case we may have to repeat the list of libraries as many times as
745 // there are object files in the biggest archive. For now we just
748 // The list of items in the component has been sorted by the order
749 // of discovery in the original BFS of dependencies. This has the
750 // advantage that the item directly linked by a target requiring
751 // this component will come first which minimizes the number of
753 for(NodeList::const_iterator ni
= nl
.begin(); ni
!= nl
.end(); ++ni
)
755 this->FinalLinkEntries
.push_back(this->EntryList
[*ni
]);
757 for(NodeList::const_iterator ni
= nl
.begin(); ni
!= nl
.end(); ++ni
)
759 this->FinalLinkEntries
.push_back(this->EntryList
[*ni
]);
763 //----------------------------------------------------------------------------
764 void cmComputeLinkDepends::DisplayFinalEntries()
766 fprintf(stderr
, "target [%s] links to:\n", this->Target
->GetName());
767 for(std::vector
<LinkEntry
>::const_iterator lei
=
768 this->FinalLinkEntries
.begin();
769 lei
!= this->FinalLinkEntries
.end(); ++lei
)
773 fprintf(stderr
, " target [%s]\n", lei
->Target
->GetName());
777 fprintf(stderr
, " item [%s]\n", lei
->Item
.c_str());
780 fprintf(stderr
, "\n");