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