cmComputeLinkDepends.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. void AddTargetObjectEntries();
  89. template <typename T>
  90. void AddLinkEntries(size_t depender_index, std::vector<T> const& libs);
  91. void AddLinkObjects(std::vector<cmLinkItem> const& objs);
  92. cmLinkItem ResolveLinkItem(size_t depender_index, const std::string& name);
  93. // One entry for each unique item.
  94. std::vector<LinkEntry> EntryList;
  95. std::map<cmLinkItem, size_t> LinkEntryIndex;
  96. // map storing, for each group, the list of items
  97. std::map<size_t, std::vector<size_t>> GroupItems;
  98. // BFS of initial dependencies.
  99. struct BFSEntry
  100. {
  101. size_t Index;
  102. size_t GroupIndex;
  103. const char* LibDepends;
  104. };
  105. std::queue<BFSEntry> BFSQueue;
  106. void FollowLinkEntry(BFSEntry qe);
  107. // Shared libraries that are included only because they are
  108. // dependencies of other shared libraries, not because they are part
  109. // of the interface.
  110. struct SharedDepEntry
  111. {
  112. cmLinkItem Item;
  113. size_t DependerIndex;
  114. };
  115. std::queue<SharedDepEntry> SharedDepQueue;
  116. std::set<size_t> SharedDepFollowed;
  117. void FollowSharedDeps(size_t depender_index, cmLinkInterface const* iface,
  118. bool follow_interface = false);
  119. void QueueSharedDependencies(size_t depender_index,
  120. std::vector<cmLinkItem> const& deps);
  121. void HandleSharedDependency(SharedDepEntry const& dep);
  122. // Dependency inferral for each link item.
  123. struct DependSet : public std::set<size_t>
  124. {
  125. };
  126. struct DependSetList : public std::vector<DependSet>
  127. {
  128. bool Initialized = false;
  129. };
  130. std::vector<DependSetList> InferredDependSets;
  131. void InferDependencies();
  132. // To finalize dependencies over groups in place of raw items
  133. void UpdateGroupDependencies();
  134. // Ordering constraint graph adjacency list.
  135. using NodeList = cmGraphNodeList;
  136. using EdgeList = cmGraphEdgeList;
  137. using Graph = cmGraphAdjacencyList;
  138. Graph EntryConstraintGraph;
  139. void CleanConstraintGraph();
  140. bool CheckCircularDependencies() const;
  141. void DisplayConstraintGraph();
  142. // Ordering algorithm.
  143. void OrderLinkEntries();
  144. std::vector<char> ComponentVisited;
  145. std::vector<size_t> ComponentOrder;
  146. struct PendingComponent
  147. {
  148. // The real component id. Needed because the map is indexed by
  149. // component topological index.
  150. size_t Id;
  151. // The number of times the component needs to be seen. This is
  152. // always 1 for trivial components and is initially 2 for
  153. // non-trivial components.
  154. size_t Count;
  155. // The entries yet to be seen to complete the component.
  156. std::set<size_t> Entries;
  157. };
  158. std::map<size_t, PendingComponent> PendingComponents;
  159. std::unique_ptr<cmComputeComponentGraph> CCG;
  160. std::vector<size_t> FinalLinkOrder;
  161. void DisplayComponents();
  162. void VisitComponent(size_t c);
  163. void VisitEntry(size_t index);
  164. PendingComponent& MakePendingComponent(size_t component);
  165. size_t ComputeComponentCount(NodeList const& nl);
  166. void DisplayFinalEntries();
  167. // Record of the original link line.
  168. std::vector<size_t> OriginalEntries;
  169. std::set<cmGeneratorTarget const*> OldWrongConfigItems;
  170. void CheckWrongConfigItem(cmLinkItem const& item);
  171. // Record of explicitly linked object files.
  172. std::vector<size_t> ObjectEntries;
  173. size_t ComponentOrderId;
  174. cmTargetLinkLibraryType LinkType;
  175. bool HasConfig;
  176. bool DebugMode;
  177. bool OldLinkDirMode;
  178. };