/src/CMake/Source/cmGlobalCommonGenerator.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include "cmGlobalCommonGenerator.h" |
4 | | |
5 | | #include <algorithm> |
6 | | #include <memory> |
7 | | #include <utility> |
8 | | |
9 | | #include <cmext/algorithm> |
10 | | |
11 | | #include <cmsys/Glob.hxx> |
12 | | |
13 | | #include "cmGeneratorExpression.h" |
14 | | #include "cmGeneratorTarget.h" |
15 | | #include "cmLocalCommonGenerator.h" |
16 | | #include "cmLocalGenerator.h" |
17 | | #include "cmStateDirectory.h" |
18 | | #include "cmStateSnapshot.h" |
19 | | #include "cmStateTypes.h" |
20 | | #include "cmStringAlgorithms.h" |
21 | | #include "cmSystemTools.h" |
22 | | #include "cmValue.h" |
23 | | #include "cmake.h" |
24 | | |
25 | | cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm) |
26 | 0 | : cmGlobalGenerator(cm) |
27 | 0 | { |
28 | 0 | } |
29 | | |
30 | 0 | cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default; |
31 | | |
32 | | std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget> |
33 | | cmGlobalCommonGenerator::ComputeDirectoryTargets() const |
34 | 0 | { |
35 | 0 | std::map<std::string, DirectoryTarget> dirTargets; |
36 | 0 | for (auto const& lg : this->LocalGenerators) { |
37 | 0 | std::string currentBinaryDir = |
38 | 0 | lg->GetStateSnapshot().GetDirectory().GetCurrentBinary(); |
39 | 0 | DirectoryTarget& dirTarget = dirTargets[currentBinaryDir]; |
40 | 0 | dirTarget.LG = lg.get(); |
41 | 0 | std::vector<std::string> const& configs = |
42 | 0 | static_cast<cmLocalCommonGenerator const*>(lg.get())->GetConfigNames(); |
43 | | |
44 | | // The directory-level rule should depend on the target-level rules |
45 | | // for all targets in the directory. |
46 | 0 | for (auto const& gt : lg->GetGeneratorTargets()) { |
47 | 0 | cmStateEnums::TargetType const type = gt->GetType(); |
48 | 0 | if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) { |
49 | 0 | continue; |
50 | 0 | } |
51 | 0 | DirectoryTarget::Target t; |
52 | 0 | t.GT = gt.get(); |
53 | 0 | std::string const EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL"); |
54 | 0 | if (cmValue exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) { |
55 | 0 | for (std::string const& config : configs) { |
56 | 0 | cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config, |
57 | 0 | gt.get()); |
58 | 0 | if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) { |
59 | | // This target has been explicitly excluded. |
60 | 0 | t.ExcludedFromAllInConfigs.push_back(config); |
61 | 0 | } |
62 | 0 | } |
63 | |
|
64 | 0 | if (t.ExcludedFromAllInConfigs.empty()) { |
65 | | // This target has been explicitly un-excluded. The directory-level |
66 | | // rule for every directory between this and the root should depend |
67 | | // on the target-level rule for this target. |
68 | 0 | for (cmStateSnapshot dir = |
69 | 0 | lg->GetStateSnapshot().GetBuildsystemDirectoryParent(); |
70 | 0 | dir.IsValid(); dir = dir.GetBuildsystemDirectoryParent()) { |
71 | 0 | std::string d = dir.GetDirectory().GetCurrentBinary(); |
72 | 0 | dirTargets[d].Targets.emplace_back(t); |
73 | 0 | } |
74 | 0 | } |
75 | 0 | } |
76 | 0 | dirTarget.Targets.emplace_back(t); |
77 | 0 | } |
78 | | |
79 | | // The directory-level rule should depend on the directory-level |
80 | | // rules of the subdirectories. |
81 | 0 | for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) { |
82 | 0 | DirectoryTarget::Dir d; |
83 | 0 | d.Path = state.GetDirectory().GetCurrentBinary(); |
84 | 0 | d.ExcludeFromAll = |
85 | 0 | state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"); |
86 | 0 | dirTarget.Children.emplace_back(std::move(d)); |
87 | 0 | } |
88 | 0 | } |
89 | |
|
90 | 0 | return dirTargets; |
91 | 0 | } |
92 | | |
93 | | bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig( |
94 | | DirectoryTarget::Target const& t, std::string const& config) |
95 | 0 | { |
96 | 0 | if (this->IsMultiConfig()) { |
97 | 0 | return cm::contains(t.ExcludedFromAllInConfigs, config); |
98 | 0 | } |
99 | 0 | return !t.ExcludedFromAllInConfigs.empty(); |
100 | 0 | } |
101 | | |
102 | | std::string cmGlobalCommonGenerator::GetEditCacheCommand() const |
103 | 0 | { |
104 | | // If generating for an extra IDE, the edit_cache target cannot |
105 | | // launch a terminal-interactive tool, so always use cmake-gui. |
106 | 0 | if (!this->GetExtraGeneratorName().empty()) { |
107 | 0 | return cmSystemTools::GetCMakeGUICommand(); |
108 | 0 | } |
109 | | |
110 | | // Use an internal cache entry to track the latest dialog used |
111 | | // to edit the cache, and use that for the edit_cache target. |
112 | 0 | cmake* cm = this->GetCMakeInstance(); |
113 | 0 | std::string editCacheCommand = cm->GetCMakeEditCommand(); |
114 | 0 | if (!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") || |
115 | 0 | !editCacheCommand.empty()) { |
116 | 0 | if (this->SupportsDirectConsole() && editCacheCommand.empty()) { |
117 | 0 | editCacheCommand = cmSystemTools::GetCMakeCursesCommand(); |
118 | 0 | } |
119 | 0 | if (editCacheCommand.empty()) { |
120 | 0 | editCacheCommand = cmSystemTools::GetCMakeGUICommand(); |
121 | 0 | } |
122 | 0 | if (!editCacheCommand.empty()) { |
123 | 0 | cm->AddCacheEntry("CMAKE_EDIT_COMMAND", editCacheCommand, |
124 | 0 | "Path to cache edit program executable.", |
125 | 0 | cmStateEnums::INTERNAL); |
126 | 0 | } |
127 | 0 | } |
128 | 0 | cmValue edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND"); |
129 | 0 | return edit_cmd ? *edit_cmd : std::string(); |
130 | 0 | } |
131 | | |
132 | | void cmGlobalCommonGenerator::RemoveUnknownClangTidyExportFixesFiles() const |
133 | 0 | { |
134 | 0 | for (auto const& dir : this->ClangTidyExportFixesDirs) { |
135 | 0 | cmsys::Glob g; |
136 | 0 | g.SetRecurse(true); |
137 | 0 | g.SetListDirs(false); |
138 | 0 | g.FindFiles(cmStrCat(dir, "/*.yaml")); |
139 | 0 | for (auto const& file : g.GetFiles()) { |
140 | 0 | if (!this->ClangTidyExportFixesFiles.count(file) && |
141 | 0 | !std::any_of(this->ClangTidyExportFixesFiles.begin(), |
142 | 0 | this->ClangTidyExportFixesFiles.end(), |
143 | 0 | [&file](std::string const& knownFile) -> bool { |
144 | 0 | return cmSystemTools::SameFile(file, knownFile); |
145 | 0 | })) { |
146 | 0 | cmSystemTools::RemoveFile(file); |
147 | 0 | } |
148 | 0 | } |
149 | 0 | } |
150 | 0 | } |