cmComputeLinkDepends.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #pragma once
  4. #include "cmConfigure.h" // IWYU pragma: keep
  5. #include <cstddef>
  6. #include <map>
  7. #include <memory>
  8. #include <queue>
  9. #include <set>
  10. #include <string>
  11. #include <utility>
  12. #include <vector>
  13. #include "cmComputeComponentGraph.h"
  14. #include "cmGraphAdjacencyList.h"
  15. #include "cmLinkItem.h"
  16. #include "cmListFileCache.h"
  17. #include "cmTargetLinkLibraryType.h"
  18. class cmGeneratorTarget;
  19. class cmGlobalGenerator;
  20. class cmMakefile;
  21. class cmake;
  22. /** \class cmComputeLinkDepends
  23. * \brief Compute link dependencies for targets.
  24. */
  25. class cmComputeLinkDepends
  26. {
  27. public:
  28. cmComputeLinkDepends(cmGeneratorTarget const* target,
  29. const std::string& config,
  30. const std::string& linkLanguage);
  31. ~cmComputeLinkDepends();
  32. cmComputeLinkDepends(const cmComputeLinkDepends&) = delete;
  33. cmComputeLinkDepends& operator=(const cmComputeLinkDepends&) = delete;
  34. // Basic information about each link item.
  35. struct LinkEntry
  36. {
  37. LinkEntry() = default;
  38. LinkEntry(BT<std::string> item, cmGeneratorTarget const* target = nullptr)
  39. : Item(std::move(item))
  40. , Target(target)
  41. {
  42. }
  43. static const std::string DEFAULT;
  44. enum EntryKind
  45. {
  46. Library,
  47. Object,
  48. SharedDep,
  49. Flag,
  50. // The following member is for the management of items specified
  51. // through genex $<LINK_GROUP:...>
  52. Group
  53. };
  54. BT<std::string> Item;
  55. cmGeneratorTarget const* Target = nullptr;
  56. EntryKind Kind = Library;
  57. // The following member is for the management of items specified
  58. // through genex $<LINK_LIBRARY:...>
  59. std::string Feature = std::string(DEFAULT);
  60. };
  61. using EntryVector = std::vector<LinkEntry>;
  62. EntryVector const& Compute();
  63. void SetOldLinkDirMode(bool b);
  64. std::set<cmGeneratorTarget const*> const& GetOldWrongConfigItems() const
  65. {
  66. return this->OldWrongConfigItems;
  67. }
  68. private:
  69. // Context information.
  70. cmGeneratorTarget const* Target;
  71. cmMakefile* Makefile;
  72. cmGlobalGenerator const* GlobalGenerator;
  73. cmake* CMakeInstance;
  74. std::string LinkLanguage;
  75. std::string Config;
  76. EntryVector FinalLinkEntries;
  77. std::map<std::string, std::string> LinkLibraryOverride;
  78. std::string const& GetCurrentFeature(
  79. std::string const& item, std::string const& defaultFeature) const;
  80. std::pair<std::map<cmLinkItem, size_t>::iterator, bool> AllocateLinkEntry(
  81. cmLinkItem const& item);
  82. std::pair<size_t, bool> AddLinkEntry(
  83. cmLinkItem const& item,
  84. size_t groupIndex = cmComputeComponentGraph::INVALID_COMPONENT);
  85. void AddLinkObject(cmLinkItem const& item);
  86. void AddVarLinkEntries(size_t depender_index, const char* value);
  87. void AddDirectLinkEntries();
  88. template <typename T>
  89. void AddLinkEntries(size_t depender_index, std::vector<T> const& libs);
  90. void AddLinkObjects(std::vector<cmLinkItem> const& objs);
  91. cmLinkItem ResolveLinkItem(size_t depender_index, const std::string& name);
  92. // One entry for each unique item.
  93. std::vector<LinkEntry> EntryList;
  94. std::map<cmLinkItem, size_t> LinkEntryIndex;
  95. // map storing, for each group, the list of items
  96. std::map<size_t, std::vector<size_t>> GroupItems;
  97. // BFS of initial dependencies.
  98. struct BFSEntry
  99. {
  100. size_t Index;
  101. size_t GroupIndex;
  102. const char* LibDepends;
  103. };
  104. std::queue<BFSEntry> BFSQueue;
  105. void FollowLinkEntry(BFSEntry qe);
  106. // Shared libraries that are included only because they are
  107. // dependencies of other shared libraries, not because they are part
  108. // of the interface.
  109. struct SharedDepEntry
  110. {
  111. cmLinkItem Item;
  112. size_t DependerIndex;
  113. };
  114. std::queue<SharedDepEntry> SharedDepQueue;
  115. std::set<size_t> SharedDepFollowed;
  116. void FollowSharedDeps(size_t depender_index, cmLinkInterface const* iface,
  117. bool follow_interface = false);
  118. void QueueSharedDependencies(size_t depender_index,
  119. std::vector<cmLinkItem> const& deps);
  120. void HandleSharedDependency(SharedDepEntry const& dep);
  121. // Dependency inferral for each link item.
  122. struct DependSet : public std::set<size_t>
  123. {
  124. };
  125. struct DependSetList : public std::vector<DependSet>
  126. {
  127. bool Initialized = false;
  128. };
  129. std::vector<DependSetList> InferredDependSets;
  130. void InferDependencies();
  131. // To finalize dependencies over groups in place of raw items
  132. void UpdateGroupDependencies();
  133. // Ordering constraint graph adjacency list.
  134. using NodeList = cmGraphNodeList;
  135. using EdgeList = cmGraphEdgeList;
  136. using Graph = cmGraphAdjacencyList;
  137. Graph EntryConstraintGraph;
  138. void CleanConstraintGraph();
  139. bool CheckCircularDependencies() const;
  140. void DisplayConstraintGraph();
  141. // Ordering algorithm.
  142. void OrderLinkEntries();
  143. std::vector<char> ComponentVisited;
  144. std::vector<size_t> ComponentOrder;
  145. struct PendingComponent
  146. {
  147. // The real component id. Needed because the map is indexed by
  148. // component topological index.
  149. size_t Id;
  150. // The number of times the component needs to be seen. This is
  151. // always 1 for trivial components and is initially 2 for
  152. // non-trivial components.
  153. size_t Count;
  154. // The entries yet to be seen to complete the component.
  155. std::set<size_t> Entries;
  156. };
  157. std::map<size_t, PendingComponent> PendingComponents;
  158. std::unique_ptr<cmComputeComponentGraph> CCG;
  159. std::vector<size_t> FinalLinkOrder;
  160. void DisplayComponents();
  161. void VisitComponent(size_t c);
  162. void VisitEntry(size_t index);
  163. PendingComponent& MakePendingComponent(size_t component);
  164. size_t ComputeComponentCount(NodeList const& nl);
  165. void DisplayFinalEntries();
  166. // Record of the original link line.
  167. std::vector<size_t> OriginalEntries;
  168. std::set<cmGeneratorTarget const*> OldWrongConfigItems;
  169. void CheckWrongConfigItem(cmLinkItem const& item);
  170. // Record of explicitly linked object files.
  171. std::vector<size_t> ObjectEntries;
  172. size_t ComponentOrderId;
  173. cmTargetLinkLibraryType LinkType;
  174. bool HasConfig;
  175. bool DebugMode;
  176. bool OldLinkDirMode;
  177. };