/src/CMake/Source/cmGlobalGenerator.h
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 | | #pragma once |
4 | | |
5 | | #include "cmConfigure.h" // IWYU pragma: keep |
6 | | |
7 | | #include <cstddef> |
8 | | #include <functional> |
9 | | #include <iosfwd> |
10 | | #include <map> |
11 | | #include <memory> |
12 | | #include <set> |
13 | | #include <string> |
14 | | #include <unordered_map> |
15 | | #include <unordered_set> |
16 | | #include <utility> |
17 | | #include <vector> |
18 | | |
19 | | #include <cm/optional> |
20 | | #include <cm/string_view> |
21 | | #include <cmext/algorithm> |
22 | | #include <cmext/string_view> |
23 | | |
24 | | #include "cmBuildOptions.h" |
25 | | #include "cmCustomCommandLines.h" |
26 | | #include "cmDuration.h" |
27 | | #include "cmExportFileGenerator.h" |
28 | | #include "cmExportSet.h" |
29 | | #include "cmInstallGenerator.h" |
30 | | #include "cmLocalGenerator.h" |
31 | | #include "cmSbomBuilder.h" |
32 | | #include "cmStateSnapshot.h" |
33 | | #include "cmStateTypes.h" |
34 | | #include "cmStringAlgorithms.h" |
35 | | #include "cmSystemTools.h" |
36 | | #include "cmTarget.h" |
37 | | #include "cmTargetDepend.h" |
38 | | #include "cmTargetTypes.h" |
39 | | #include "cmTestGenerator.h" |
40 | | #include "cmValue.h" |
41 | | #include "cmXcFramework.h" |
42 | | |
43 | | #if !defined(CMAKE_BOOTSTRAP) |
44 | | # include <cm3p/json/value.h> |
45 | | |
46 | | # include "cmFileLockPool.h" |
47 | | #endif |
48 | | |
49 | 154k | #define CMAKE_DIRECTORY_ID_SEP "::@" |
50 | | |
51 | | enum class cmDepfileFormat; |
52 | | enum class codecvt_Encoding; |
53 | | |
54 | | class cmBuildArgs; |
55 | | class cmDirectoryId; |
56 | | class cmExportBuildFileGenerator; |
57 | | class cmExternalMakefileProjectGenerator; |
58 | | class cmBuildSbomGenerator; |
59 | | class cmInstallSbomGenerator; |
60 | | class cmGeneratorTarget; |
61 | | class cmRule; |
62 | | class cmGeneratorRule; |
63 | | class cmInstallRuntimeDependencySet; |
64 | | class cmLinkLineComputer; |
65 | | class cmMakefile; |
66 | | class cmOutputConverter; |
67 | | class cmQtAutoGenGlobalInitializer; |
68 | | class cmSourceFile; |
69 | | class cmState; |
70 | | class cmStateDirectory; |
71 | | class cmake; |
72 | | |
73 | | namespace detail { |
74 | | inline void AppendStrs(std::vector<std::string>&) |
75 | 0 | { |
76 | 0 | } |
77 | | template <typename T, typename... Ts> |
78 | | inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts) |
79 | 0 | { |
80 | 0 | command.emplace_back(std::forward<T>(s)); |
81 | 0 | AppendStrs(command, std::forward<Ts>(ts)...); |
82 | 0 | } Unexecuted instantiation: void detail::AppendStrs<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) Unexecuted instantiation: void detail::AppendStrs<char const (&) [3]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [3]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) Unexecuted instantiation: void detail::AppendStrs<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: void detail::AppendStrs<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: void detail::AppendStrs<char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: void detail::AppendStrs<char const (&) [21]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [21]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [15]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [15]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [9]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [9]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [10]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [10]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: void detail::AppendStrs<char const (&) [7]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [7]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [56]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [56]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [4]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [4]) Unexecuted instantiation: void detail::AppendStrs<char const (&) [29]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [29]) |
83 | | |
84 | | struct GeneratedMakeCommand |
85 | | { |
86 | | // Add each argument as a separate element to the vector |
87 | | template <typename... T> |
88 | | void Add(T&&... args) |
89 | 0 | { |
90 | | // iterate the args and append each one |
91 | 0 | AppendStrs(this->PrimaryCommand, std::forward<T>(args)...); |
92 | 0 | } Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [3]>(char const (&) [3]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [21]>(char const (&) [21]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [15]>(char const (&) [15]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [9]>(char const (&) [9]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [10]>(char const (&) [10]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [7]>(char const (&) [7]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [56]>(char const (&) [56]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [4]>(char const (&) [4]) Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [29]>(char const (&) [29]) |
93 | | |
94 | | // Add each value in the iterators as a separate element to the vector |
95 | | void Add(std::vector<std::string>::const_iterator start, |
96 | | std::vector<std::string>::const_iterator end) |
97 | 0 | { |
98 | 0 | cm::append(this->PrimaryCommand, start, end); |
99 | 0 | } |
100 | | |
101 | 0 | std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); } |
102 | | std::string QuotedPrintable() const; |
103 | | |
104 | | std::vector<std::string> PrimaryCommand; |
105 | | }; |
106 | | } |
107 | | namespace Json { |
108 | | class StreamWriter; |
109 | | } |
110 | | |
111 | | /** \class cmGlobalGenerator |
112 | | * \brief Responsible for overseeing the generation process for the entire tree |
113 | | * |
114 | | * Subclasses of this class generate makefiles for various |
115 | | * platforms. |
116 | | */ |
117 | | class cmGlobalGenerator |
118 | | { |
119 | | public: |
120 | | using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>; |
121 | | enum class BuildTryCompile |
122 | | { |
123 | | No, |
124 | | Yes, |
125 | | }; |
126 | | |
127 | | //! Free any memory allocated with the GlobalGenerator |
128 | | cmGlobalGenerator(cmake* cm); |
129 | | virtual ~cmGlobalGenerator(); |
130 | | |
131 | | virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator( |
132 | | cmMakefile* mf); |
133 | | |
134 | | //! Get the name for this generator |
135 | 661 | virtual std::string GetName() const { return "Generic"; } |
136 | | |
137 | | virtual std::vector<std::string> GetTestBuildDependencyPaths( |
138 | | std::string const& config, |
139 | | cmTestGenerator::BuildDependencies const& deps) const; |
140 | | |
141 | | struct InstallPrepTargets |
142 | | { |
143 | | struct TargetRequirements |
144 | | { |
145 | | bool Normal = false; |
146 | | bool InstallArtifact = false; |
147 | | std::set<std::string> GeneratedFiles; |
148 | | }; |
149 | | |
150 | | using TargetMap = std::map<cmGeneratorTarget const*, TargetRequirements>; |
151 | | |
152 | | TargetMap All; |
153 | | std::map<std::string, TargetMap> Components; |
154 | | |
155 | | // Generated files that no target prepares, such as byproducts installed |
156 | | // by install(FILES). Only generators that support depending on them |
157 | | // prepare these files. |
158 | | std::set<std::string> AllFiles; |
159 | | std::map<std::string, std::set<std::string>> ComponentFiles; |
160 | | }; |
161 | | |
162 | | InstallPrepTargets GetInstallPrepTargets(std::string const& config); |
163 | | |
164 | | // Whether install preparation targets can depend on a generated file that |
165 | | // is not the unique output of a target. |
166 | 0 | virtual bool SupportsInstallPrepFileDependencies() const { return false; } |
167 | | |
168 | | // Whether the name of an install component can be used in the name of its |
169 | | // install preparation target. |
170 | | virtual bool IsInstallPrepComponentRepresentable( |
171 | | std::string const& component) const; |
172 | | |
173 | | // Diagnose install rules that no install preparation target prepares. |
174 | | // Generators that write install preparation targets call this once. |
175 | | void CheckInstallPrepTargets(); |
176 | | |
177 | | // Whether a generated file to be prepared for installation is the unique |
178 | | // output of a target. Generators that cannot depend on a file with no such |
179 | | // owner build its installing target instead, and call this to diagnose it |
180 | | // once per file. |
181 | | bool CheckInstallPrepGeneratedFile(cmGeneratorTarget const* target, |
182 | | std::string const& file, |
183 | | std::set<std::string>& diagnosed); |
184 | | |
185 | | bool AreInstallPrepTargetsEnabled() const; |
186 | | |
187 | | /** Check whether the given name matches the current generator. */ |
188 | | virtual bool MatchesGeneratorName(std::string const& name) const |
189 | 0 | { |
190 | 0 | return this->GetName() == name; |
191 | 0 | } |
192 | | |
193 | | /** Get encoding used by generator for makefile files */ |
194 | | virtual codecvt_Encoding GetMakefileEncoding() const; |
195 | | |
196 | | #if !defined(CMAKE_BOOTSTRAP) |
197 | | /** Get a JSON object describing the generator. */ |
198 | | virtual Json::Value GetJson() const; |
199 | | #endif |
200 | | |
201 | | /** Tell the generator about the target system. */ |
202 | 0 | virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; } |
203 | | |
204 | | /** Set the generator-specific instance. Returns true if supported. */ |
205 | | virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf); |
206 | | |
207 | | /** Set the generator-specific platform name. Returns true if platform |
208 | | is supported and false otherwise. */ |
209 | | virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf); |
210 | | |
211 | | /** Set the generator-specific toolset name. Returns true if toolset |
212 | | is supported and false otherwise. */ |
213 | | virtual bool SetGeneratorToolset(std::string const& ts, bool build, |
214 | | cmMakefile* mf); |
215 | | |
216 | | /** Read any other cache entries needed for cmake --build. */ |
217 | | virtual bool ReadCacheEntriesForBuild(cmState const& /*state*/) |
218 | 0 | { |
219 | 0 | return true; |
220 | 0 | } |
221 | | |
222 | | /** |
223 | | * Create LocalGenerators and process the CMakeLists files. This does not |
224 | | * actually produce any makefiles, DSPs, etc. |
225 | | */ |
226 | | virtual void Configure(); |
227 | | |
228 | 0 | virtual bool InspectConfigTypeVariables() { return true; } |
229 | | |
230 | | enum class CxxModuleSupportQuery |
231 | | { |
232 | | // Support is expected at the call site. |
233 | | Expected, |
234 | | // The call site is querying for support and handles problems by itself. |
235 | | Inspect, |
236 | | }; |
237 | | virtual bool CheckCxxModuleSupport(CxxModuleSupportQuery /*query*/) |
238 | 0 | { |
239 | 0 | return false; |
240 | 0 | } |
241 | | |
242 | 0 | virtual bool SupportsCustomObjectNames() const { return true; } |
243 | | |
244 | 0 | virtual bool SupportsBuildDatabase() const { return false; } |
245 | | bool AddBuildDatabaseTargets(); |
246 | | void AddBuildDatabaseFile(std::string const& lang, std::string const& config, |
247 | | std::string const& path); |
248 | | |
249 | 0 | virtual bool IsGNUMakeJobServerAware() const { return false; } |
250 | | |
251 | | bool Compute(); |
252 | 0 | virtual void AddExtraIDETargets() {} |
253 | | |
254 | | enum TargetTypes |
255 | | { |
256 | | AllTargets, |
257 | | ImportedOnly |
258 | | }; |
259 | | |
260 | | void CreateImportedGenerationObjects( |
261 | | cmMakefile* mf, std::vector<std::string> const& targets, |
262 | | std::vector<cmGeneratorTarget const*>& exports); |
263 | | void CreateGenerationObjects(TargetTypes targetTypes = AllTargets); |
264 | | |
265 | | /** |
266 | | * Generate the all required files for building this project/tree. This |
267 | | * basically creates a series of LocalGenerators for each directory and |
268 | | * requests that they Generate. |
269 | | */ |
270 | | virtual void Generate(); |
271 | | |
272 | | virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer( |
273 | | cmOutputConverter* outputConverter, |
274 | | cmStateDirectory const& stateDir) const; |
275 | | |
276 | | std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer( |
277 | | cmOutputConverter* outputConverter, |
278 | | cmStateDirectory const& stateDir) const; |
279 | | |
280 | | /** |
281 | | * Set/Get and Clear the enabled languages. |
282 | | */ |
283 | | void SetLanguageEnabled(std::string const&, cmMakefile* mf); |
284 | | bool GetLanguageEnabled(std::string const&) const; |
285 | | void ClearEnabledLanguages(); |
286 | | void GetEnabledLanguages(std::vector<std::string>& lang) const; |
287 | | /** |
288 | | * Try to determine system information such as shared library |
289 | | * extension, pthreads, byte order etc. |
290 | | */ |
291 | | virtual void EnableLanguage(std::vector<std::string> const& languages, |
292 | | cmMakefile*, bool optional); |
293 | | |
294 | | /** |
295 | | * Resolve the CMAKE_<lang>_COMPILER setting for the given language. |
296 | | * Intended to be called from EnableLanguage. |
297 | | */ |
298 | | void ResolveLanguageCompiler(std::string const& lang, cmMakefile* mf, |
299 | | bool optional) const; |
300 | | |
301 | | void SetupTryCompile(cmGlobalGenerator* gen, cmMakefile* mf); |
302 | | /** |
303 | | * Try running cmake and building a file. This is used for dynamically |
304 | | * loaded commands, not as part of the usual build process. |
305 | | */ |
306 | | int TryCompile(int jobs, std::string const& bindir, |
307 | | std::string const& projectName, std::string const& targetName, |
308 | | bool fast, std::string& output, cmMakefile* mf); |
309 | | |
310 | | /** |
311 | | * Build a file given the following information. This is a more direct call |
312 | | * that is used by both CTest and TryCompile. If target name is NULL or |
313 | | * empty then all is assumed. clean indicates if a "make clean" should be |
314 | | * done first. |
315 | | */ |
316 | | int Build( |
317 | | cmBuildArgs const& buildArgs, std::vector<std::string> const& targetNames, |
318 | | std::ostream& ostr, std::string const& makeProgram, |
319 | | std::string const& config, cmBuildOptions buildOptions, cmDuration timeout, |
320 | | cmSystemTools::OutputOption outputMode, |
321 | | std::vector<std::string> const& nativeOptions = std::vector<std::string>(), |
322 | | BuildTryCompile isInTryCompile = BuildTryCompile::No); |
323 | | |
324 | | /** |
325 | | * Open a generated IDE project given the following information. |
326 | | */ |
327 | | virtual bool Open(std::string const& bindir, std::string const& projectName, |
328 | | bool dryRun); |
329 | | |
330 | | struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand |
331 | | { |
332 | | }; |
333 | | |
334 | | virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand( |
335 | | std::string const& makeProgram, std::string const& projectName, |
336 | | std::string const& projectDir, std::vector<std::string> const& targetNames, |
337 | | std::string const& config, int jobs, bool verbose, |
338 | | cmBuildOptions buildOptions = cmBuildOptions(), |
339 | | std::vector<std::string> const& makeOptions = std::vector<std::string>(), |
340 | | BuildTryCompile isInTryCompile = BuildTryCompile::No); |
341 | | |
342 | | virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const; |
343 | | |
344 | | /** |
345 | | * Generate a "cmake --build" call for a given target, config and parallel |
346 | | * level. |
347 | | */ |
348 | | std::string GenerateCMakeBuildCommand(std::string const& target, |
349 | | std::string const& config, |
350 | | std::string const& parallel, |
351 | | std::string const& native, |
352 | | bool ignoreErrors); |
353 | | |
354 | | //! Get the CMake instance |
355 | 25.1M | cmake* GetCMakeInstance() const { return this->CMakeInstance; } |
356 | | |
357 | | void SetConfiguredFilesPath(cmGlobalGenerator* gen); |
358 | | std::vector<std::unique_ptr<cmMakefile>> const& GetMakefiles() const |
359 | 0 | { |
360 | 0 | return this->Makefiles; |
361 | 0 | } |
362 | | LocalGeneratorVector const& GetLocalGenerators() const |
363 | 11.8k | { |
364 | 11.8k | return this->LocalGenerators; |
365 | 11.8k | } |
366 | | |
367 | | std::vector<cmGeneratorTarget*> GetLocalGeneratorTargetsInOrder( |
368 | | cmLocalGenerator* lg) const; |
369 | | |
370 | | // Find the single build-system target that produces the given path as a |
371 | | // primary custom-command output, or nullptr if there is none or more than |
372 | | // one. Used to resolve file-level test build dependencies. |
373 | | cmGeneratorTarget* FindOutputOwningTarget(std::string const& output); |
374 | | |
375 | | // Whether the build generates the file, as the output or byproduct of a |
376 | | // custom command or custom target. |
377 | | bool IsGeneratedByBuild(std::string const& file); |
378 | | |
379 | | // Called by local generators when they record a new output or byproduct, |
380 | | // so that IsGeneratedByBuild rebuilds its index before its next lookup. |
381 | | void InvalidateGeneratedByBuildIndex() |
382 | 5.92k | { |
383 | 5.92k | this->GeneratedByBuildIndexComputed = false; |
384 | 5.92k | } |
385 | | |
386 | | // Find the single build-system target whose build produces the given path |
387 | | // as a linked artifact for the given configuration, or nullptr if there is |
388 | | // none or more than one. |
389 | | cmGeneratorTarget* FindArtifactOwningTarget(std::string const& artifact, |
390 | | std::string const& config); |
391 | | |
392 | | cmMakefile* GetCurrentMakefile() const |
393 | 0 | { |
394 | 0 | return this->CurrentConfigureMakefile; |
395 | 0 | } |
396 | | |
397 | | void SetCurrentMakefile(cmMakefile* mf) |
398 | 0 | { |
399 | 0 | this->CurrentConfigureMakefile = mf; |
400 | 0 | } |
401 | | |
402 | | void AddMakefile(std::unique_ptr<cmMakefile> mf); |
403 | | |
404 | | //! Set an generator for an "external makefile based project" |
405 | | void SetExternalMakefileProjectGenerator( |
406 | | std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator); |
407 | | |
408 | | std::string GetExtraGeneratorName() const; |
409 | | |
410 | | void AddInstallComponent(std::string const& component); |
411 | | |
412 | | /** Mark the (absolute path to a) file as generated. */ |
413 | | void MarkAsGeneratedFile(std::string const& filepath); |
414 | | /** Determine if the absolute filepath belongs to a generated file. */ |
415 | | bool IsGeneratedFile(std::string const& filepath); |
416 | | |
417 | | std::set<std::string> const* GetInstallComponents() const |
418 | 0 | { |
419 | 0 | return &this->InstallComponents; |
420 | 0 | } |
421 | | |
422 | 0 | cmExportSetMap& GetExportSets() { return this->ExportSets; } |
423 | | |
424 | | cmValue GetGlobalSetting(std::string const& name) const; |
425 | | bool GlobalSettingIsOn(std::string const& name) const; |
426 | | std::string GetSafeGlobalSetting(std::string const& name) const; |
427 | | |
428 | | /** Add a file to the manifest of generated targets for a configuration. */ |
429 | | void AddToManifest(std::string const& f); |
430 | | |
431 | | void EnableInstallTarget(); |
432 | | |
433 | | cmDuration TryCompileTimeout; |
434 | | |
435 | 5.92k | bool GetForceUnixPaths() const { return this->ForceUnixPaths; } |
436 | 0 | bool GetToolSupportsColor() const { return this->ToolSupportsColor; } |
437 | | |
438 | | //! return the language for the given extension |
439 | | cm::string_view GetLanguageFromExtension(cm::string_view ext) const; |
440 | | //! is an extension to be ignored |
441 | | bool IgnoreFile(cm::string_view ext) const; |
442 | | //! What is the preference for linkers and this language (None or Preferred) |
443 | | int GetLinkerPreference(std::string const& lang) const; |
444 | | //! What is the object file extension for a given source file? |
445 | | std::string GetLanguageOutputExtension(cmSourceFile const&) const; |
446 | | //! What is the object file extension for a given language? |
447 | | std::string GetLanguageOutputExtension(std::string const& lang) const; |
448 | | //! What is the object file extension for a given --emit option in Rust? |
449 | | std::string GetRustEmitOutputExtension(std::string const& emitValue) const; |
450 | | |
451 | | //! What is the configurations directory variable called? |
452 | 5.92k | virtual char const* GetCMakeCFGIntDir() const { return "."; } |
453 | | |
454 | | //! expand CFGIntDir for a configuration |
455 | | virtual std::string ExpandCFGIntDir(std::string const& str, |
456 | | std::string const& config) const; |
457 | | |
458 | | /** Get whether the generator should use a script for link commands. */ |
459 | 0 | bool GetUseLinkScript() const { return this->UseLinkScript; } |
460 | | |
461 | | /** Get whether the generator should produce special marks on rules |
462 | | producing symbolic (non-file) outputs. */ |
463 | 0 | bool GetNeedSymbolicMark() const { return this->NeedSymbolicMark; } |
464 | | |
465 | | /* |
466 | | * Determine what program to use for building the project. |
467 | | */ |
468 | | virtual bool FindMakeProgram(cmMakefile*); |
469 | | |
470 | | //! Find a target by name by searching the local generators. |
471 | | cmTarget* FindTarget(std::string const& name, |
472 | | cm::TargetDomainSet domains = { |
473 | | cm::TargetDomain::NATIVE, |
474 | | cm::TargetDomain::ALIAS }) const; |
475 | | |
476 | | cmGeneratorTarget* FindGeneratorTarget(std::string const& name) const; |
477 | | |
478 | | void AddAlias(std::string const& name, std::string const& tgtName); |
479 | | bool IsAlias(std::string const& name) const; |
480 | | |
481 | | //! Find a rule by name. |
482 | | cmRule* FindRule(std::string const& name) const; |
483 | | cmGeneratorRule* FindGeneratorRule(std::string const& name) const; |
484 | | |
485 | | /** Determine if a name resolves to a framework on disk or a built target |
486 | | that is a framework. */ |
487 | | bool NameResolvesToFramework(std::string const& libname) const; |
488 | | /** Split a framework path to the directory and name of the framework as well |
489 | | * as optional suffix. |
490 | | * Returns std::nullopt if the path does not match with framework format |
491 | | * when extendedFormat is true, required format is relaxed (i.e. extension |
492 | | * `.framework' is optional). Used when FRAMEWORK link feature is |
493 | | * specified */ |
494 | | struct FrameworkDescriptor |
495 | | { |
496 | | FrameworkDescriptor(std::string directory, std::string name) |
497 | 0 | : Directory(std::move(directory)) |
498 | 0 | , Name(std::move(name)) |
499 | 0 | { |
500 | 0 | } |
501 | | FrameworkDescriptor(std::string directory, std::string version, |
502 | | std::string name) |
503 | 0 | : Directory(std::move(directory)) |
504 | 0 | , Version(std::move(version)) |
505 | 0 | , Name(std::move(name)) |
506 | 0 | { |
507 | 0 | } |
508 | | FrameworkDescriptor(std::string directory, std::string version, |
509 | | std::string name, std::string suffix) |
510 | 0 | : Directory(std::move(directory)) |
511 | 0 | , Version(std::move(version)) |
512 | 0 | , Name(std::move(name)) |
513 | 0 | , Suffix(std::move(suffix)) |
514 | 0 | { |
515 | 0 | } |
516 | | std::string GetLinkName() const |
517 | 0 | { |
518 | 0 | return this->Suffix.empty() ? this->Name |
519 | 0 | : cmStrCat(this->Name, ',', this->Suffix); |
520 | 0 | } |
521 | | std::string GetFullName() const |
522 | 0 | { |
523 | 0 | return cmStrCat(this->Name, ".framework/"_s, this->Name, this->Suffix); |
524 | 0 | } |
525 | | std::string GetVersionedName() const |
526 | 0 | { |
527 | 0 | return this->Version.empty() |
528 | 0 | ? this->GetFullName() |
529 | 0 | : cmStrCat(this->Name, ".framework/Versions/"_s, this->Version, '/', |
530 | 0 | this->Name, this->Suffix); |
531 | 0 | } |
532 | | std::string GetFrameworkPath() const |
533 | 0 | { |
534 | 0 | return this->Directory.empty() |
535 | 0 | ? cmStrCat(this->Name, ".framework"_s) |
536 | 0 | : cmStrCat(this->Directory, '/', this->Name, ".framework"_s); |
537 | 0 | } |
538 | | std::string GetFullPath() const |
539 | 0 | { |
540 | 0 | return this->Directory.empty() |
541 | 0 | ? this->GetFullName() |
542 | 0 | : cmStrCat(this->Directory, '/', this->GetFullName()); |
543 | 0 | } |
544 | | std::string GetVersionedPath() const |
545 | 0 | { |
546 | 0 | return this->Directory.empty() |
547 | 0 | ? this->GetVersionedName() |
548 | 0 | : cmStrCat(this->Directory, '/', this->GetVersionedName()); |
549 | 0 | } |
550 | | |
551 | | std::string const Directory; |
552 | | std::string const Version; |
553 | | std::string const Name; |
554 | | std::string const Suffix; |
555 | | }; |
556 | | enum class FrameworkFormat |
557 | | { |
558 | | Strict, |
559 | | Relaxed, |
560 | | Extended |
561 | | }; |
562 | | cm::optional<FrameworkDescriptor> SplitFrameworkPath( |
563 | | std::string const& path, |
564 | | FrameworkFormat format = FrameworkFormat::Relaxed) const; |
565 | | |
566 | | cmMakefile* FindMakefile(std::string const& start_dir) const; |
567 | | cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const; |
568 | | |
569 | | /** Append the subdirectory for the given configuration. If anything is |
570 | | appended the given prefix and suffix will be appended around it, which |
571 | | is useful for leading or trailing slashes. */ |
572 | | virtual void AppendDirectoryForConfig(std::string const& prefix, |
573 | | std::string const& config, |
574 | | std::string const& suffix, |
575 | | std::string& dir); |
576 | | |
577 | | /** Get the content of a directory. Directory listings are cached |
578 | | and re-loaded from disk only when modified. During the generation |
579 | | step the content will include the target files to be built even if |
580 | | they do not yet exist. */ |
581 | | std::set<std::string> const& GetDirectoryContent(std::string const& dir, |
582 | | bool needDisk = true); |
583 | | |
584 | | /** Check whether a file exists for the purpose of resolving the |
585 | | location of a source file. Files found to exist are remembered until |
586 | | the next configure, or until cmake::InvalidateFileSystemCaches, |
587 | | because the same source file is typically looked up many times. |
588 | | Missing files are always checked again so that files created later |
589 | | are still found. */ |
590 | | bool SourceFileExists(std::string const& path); |
591 | 0 | void ClearSourceFileExistsCache() { this->ExistingSourceFiles.clear(); } |
592 | | |
593 | | void IndexTarget(cmTarget* t); |
594 | | void IndexGeneratorTarget(cmGeneratorTarget* gt); |
595 | | |
596 | | // Index the target using a name that is unique to that target |
597 | | // even if other targets have the same name. |
598 | | std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt); |
599 | | |
600 | | static bool IsReservedTarget(std::string const& name); |
601 | | |
602 | 0 | virtual char const* GetAllTargetName() const { return "ALL_BUILD"; } |
603 | 0 | virtual char const* GetInstallTargetName() const { return "INSTALL"; } |
604 | 0 | virtual char const* GetInstallLocalTargetName() const { return nullptr; } |
605 | 0 | virtual char const* GetInstallStripTargetName() const { return nullptr; } |
606 | 0 | virtual char const* GetPreinstallTargetName() const { return nullptr; } |
607 | 0 | virtual char const* GetTestTargetName() const { return "RUN_TESTS"; } |
608 | 0 | virtual char const* GetPackageTargetName() const { return "PACKAGE"; } |
609 | 0 | virtual char const* GetPackageSourceTargetName() const { return nullptr; } |
610 | 0 | virtual char const* GetEditCacheTargetName() const { return nullptr; } |
611 | 0 | virtual char const* GetRebuildCacheTargetName() const { return nullptr; } |
612 | 0 | virtual char const* GetCleanTargetName() const { return nullptr; } |
613 | | |
614 | | void IndexRule(cmRule* rule); |
615 | | void IndexGeneratorRule(cmGeneratorRule* gt); |
616 | | |
617 | | // Lookup edit_cache target command preferred by this generator. |
618 | 0 | virtual std::string GetEditCacheCommand() const { return ""; } |
619 | | |
620 | | // Default config to use for cmake --build |
621 | 0 | virtual std::string GetDefaultBuildConfig() const { return "Debug"; } |
622 | | |
623 | | virtual cmValue GetDebuggerWorkingDirectory(cmGeneratorTarget* gt) const; |
624 | | |
625 | | // Class to track a set of dependencies. |
626 | | using TargetDependSet = cmTargetDependSet; |
627 | | |
628 | | // what targets does the specified target depend on directly |
629 | | // via a target_link_libraries or add_dependencies |
630 | | TargetDependSet const& GetTargetDirectDepends( |
631 | | cmGeneratorTarget const* target) const; |
632 | | |
633 | | // Return true if target 'l' occurs before 'r' in a global ordering |
634 | | // of targets that respects inter-target dependencies. |
635 | | bool TargetOrderIndexLess(cmGeneratorTarget const* l, |
636 | | cmGeneratorTarget const* r) const; |
637 | | |
638 | | std::map<std::string, std::vector<cmLocalGenerator*>> const& GetProjectMap() |
639 | | const |
640 | 0 | { |
641 | 0 | return this->ProjectMap; |
642 | 0 | } |
643 | | |
644 | | // track files replaced during a Generate |
645 | | void FileReplacedDuringGenerate(std::string const& filename); |
646 | | void GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames); |
647 | | |
648 | | void AddRuleHash(std::vector<std::string> const& outputs, |
649 | | std::string const& content); |
650 | | |
651 | | /** Return whether the given binary directory is unused. */ |
652 | | bool BinaryDirectoryIsNew(std::string const& dir) |
653 | 0 | { |
654 | 0 | return this->BinaryDirectories.insert(dir).second; |
655 | 0 | } |
656 | | |
657 | | /** Return true if the generated build tree may contain multiple builds. |
658 | | i.e. "Can I build Debug and Release in the same tree?" */ |
659 | 138k | virtual bool IsMultiConfig() const { return false; } |
660 | | |
661 | 87.2k | virtual bool IsXcode() const { return false; } |
662 | | |
663 | 0 | virtual bool IsVisualStudio() const { return false; } |
664 | | |
665 | 0 | virtual bool IsVisualStudioAtLeast10() const { return false; } |
666 | | |
667 | 0 | virtual bool IsNinja() const { return false; } |
668 | | |
669 | 0 | virtual bool IsFastbuild() const { return false; } |
670 | | |
671 | | /** Return true if we know the exact location of object files for the given |
672 | | cmTarget. If false, store the reason in the given string. This is |
673 | | meaningful only after EnableLanguage has been called. */ |
674 | | virtual bool HasKnownObjectFileLocation(cmTarget const&, std::string*) const |
675 | 13 | { |
676 | 13 | return true; |
677 | 13 | } |
678 | | |
679 | | virtual bool UseFolderProperty() const; |
680 | | |
681 | 0 | virtual bool IsIPOSupported() const { return false; } |
682 | | |
683 | | /** Return whether the generator can import external visual studio project |
684 | | using INCLUDE_EXTERNAL_MSPROJECT */ |
685 | 0 | virtual bool IsIncludeExternalMSProjectSupported() const { return false; } |
686 | | |
687 | | /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is |
688 | | relevant for mixed macOS and iOS builds. */ |
689 | 944 | virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; } |
690 | | |
691 | | /** Return whether the "Resources" folder prefix should be stripped from |
692 | | MacFolder. */ |
693 | | virtual bool ShouldStripResourcePath(cmMakefile*) const; |
694 | | |
695 | 0 | virtual bool SupportsCustomCommandDepfile() const { return false; } |
696 | | virtual cm::optional<cmDepfileFormat> DepfileFormat() const |
697 | 0 | { |
698 | 0 | return cm::nullopt; |
699 | 0 | } |
700 | | |
701 | 0 | virtual bool SupportsLinkerDependencyFile() const { return false; } |
702 | | |
703 | | /** Generate an <output>.rule file path for a given command output. */ |
704 | | virtual std::string GenerateRuleFile(std::string const& output) const; |
705 | | |
706 | 0 | virtual bool SupportsDefaultBuildType() const { return false; } |
707 | 553 | virtual bool SupportsCrossConfigs() const { return false; } |
708 | 0 | virtual bool SupportsDefaultConfigs() const { return false; } |
709 | | |
710 | | virtual std::string ConvertToOutputPath(std::string path) const |
711 | 0 | { |
712 | 0 | return path; |
713 | 0 | } |
714 | | virtual std::string GetConfigDirectory(std::string const& config) const |
715 | 0 | { |
716 | 0 | if (!this->IsMultiConfig() || config.empty()) { |
717 | 0 | return {}; |
718 | 0 | } |
719 | 0 | return cmStrCat('/', config); |
720 | 0 | } |
721 | | |
722 | | static std::string EscapeJSON(std::string const& s); |
723 | | |
724 | | void ProcessEvaluationFiles(); |
725 | | |
726 | | std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets() |
727 | 0 | { |
728 | 0 | return this->BuildExportSets; |
729 | 0 | } |
730 | | /** Scan all build-tree exports in the project and report which of them |
731 | | * reference `target`. Used both by cmExportBuildFileGenerator (to resolve |
732 | | * out-of-export link references) and by cmSbomBuilder (to record which |
733 | | * export sets a target appears in for SBOM dependency tracking). */ |
734 | | cmExportFileGenerator::ExportInfo FindBuildExportInfo( |
735 | | cmGeneratorTarget const* target) const; |
736 | | |
737 | | /** Same as FindBuildExportInfo, but searches install-tree export sets |
738 | | * (those registered via install(EXPORT ...)). */ |
739 | | cmExportFileGenerator::ExportInfo FindInstallExportInfo( |
740 | | cmGeneratorTarget const* target) const; |
741 | | |
742 | | /** Scan all build-tree SBOMs and report which of them cover `target`. */ |
743 | | cmSbomBuilder::SbomInfo FindBuildSbomInfo( |
744 | | cmGeneratorTarget const* target) const; |
745 | | |
746 | | /** Same as FindBuildSbomInfo, but searches install-tree SBOMs. */ |
747 | | cmSbomBuilder::SbomInfo FindInstallSbomInfo( |
748 | | cmGeneratorTarget const* target) const; |
749 | | void AddBuildExportSet(cmExportBuildFileGenerator* gen); |
750 | | void AddBuildExportExportSet(cmExportBuildFileGenerator* gen); |
751 | | void AddBuildSbomGenerator(cmBuildSbomGenerator* gen); |
752 | | std::vector<cmBuildSbomGenerator*> const& GetBuildSbomGenerators() const |
753 | 0 | { |
754 | 0 | return this->BuildSbomGenerators; |
755 | 0 | } |
756 | | |
757 | | // Project-wide registry of install(SBOM) generators. |
758 | | void AddInstallSbomGenerator(cmInstallSbomGenerator const* gen); |
759 | | std::vector<cmInstallSbomGenerator const*> const& GetInstallSbomGenerators() |
760 | | const |
761 | 0 | { |
762 | 0 | return this->InstallSbomGenerators; |
763 | 0 | } |
764 | | |
765 | | bool IsExportedTargetsFile(std::string const& filename) const; |
766 | | |
767 | | /** True if any registered cmBuildSbomGenerator already targets this |
768 | | * output file path. Used to diagnose duplicate `export(SBOM ...)` |
769 | | * calls that would otherwise silently clobber each other's output. */ |
770 | | bool IsBuildSbomFile(std::string const& filepath) const; |
771 | | |
772 | | /** True if any registered cmInstallSbomGenerator already targets this |
773 | | * install file path (DESTINATION + filename). Used to diagnose |
774 | | * duplicate `install(SBOM ...)` calls that would otherwise silently |
775 | | * clobber each other at install time. */ |
776 | | bool IsInstallSbomFile(std::string const& filepath) const; |
777 | | |
778 | | cmExportBuildFileGenerator* GetExportedTargetsFile( |
779 | | std::string const& filename) const; |
780 | | void AddCMP0068WarnTarget(std::string const& target); |
781 | | void AddCMP0224WarnTest(std::string const& test); |
782 | | |
783 | | virtual bool SupportsShortObjectNames() const; |
784 | | bool UseShortObjectNames( |
785 | | cmStateEnums::IntermediateDirKind kind = |
786 | | cmStateEnums::IntermediateDirKind::ObjectFiles) const; |
787 | | virtual std::string GetShortBinaryOutputDir() const; |
788 | | std::string ComputeTargetShortName(std::string const& bindir, |
789 | | std::string const& targetName) const; |
790 | | struct TargetDirectoryRegistration |
791 | | { |
792 | 0 | TargetDirectoryRegistration() = default; |
793 | | TargetDirectoryRegistration(cmGeneratorTarget const* t, bool w) |
794 | 0 | : CollidesWith(t) |
795 | 0 | , Warned(w) |
796 | 0 | { |
797 | 0 | } |
798 | | |
799 | | cmGeneratorTarget const* CollidesWith = nullptr; |
800 | | bool Warned = false; |
801 | | }; |
802 | | TargetDirectoryRegistration& RegisterTargetDirectory( |
803 | | cmGeneratorTarget const* tgt, std::string const& targetDir) const; |
804 | | |
805 | | virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; |
806 | | |
807 | | bool GenerateCPackPropertiesFile(); |
808 | | |
809 | | void SetFilenameTargetDepends( |
810 | | cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts); |
811 | | std::set<cmGeneratorTarget const*> const& GetFilenameTargetDepends( |
812 | | cmSourceFile* sf) const; |
813 | | |
814 | | #if !defined(CMAKE_BOOTSTRAP) |
815 | 23.7k | cmFileLockPool& GetFileLockPool() { return this->FileLockPool; } |
816 | | #endif |
817 | | |
818 | | std::string MakeSilentFlag; |
819 | | |
820 | | size_t RecursionDepth = 0; |
821 | | |
822 | | virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const |
823 | 0 | { |
824 | 0 | configs.emplace_back("$<CONFIG>"); |
825 | 0 | } |
826 | | |
827 | | std::string const& GetRealPath(std::string const& dir); |
828 | | |
829 | | std::string NewDeferId(); |
830 | | |
831 | | cmInstallRuntimeDependencySet* CreateAnonymousRuntimeDependencySet(); |
832 | | |
833 | | cmInstallRuntimeDependencySet* GetNamedRuntimeDependencySet( |
834 | | std::string const& name); |
835 | | |
836 | | enum class StripCommandStyle |
837 | | { |
838 | | Default, |
839 | | Apple, |
840 | | }; |
841 | | StripCommandStyle GetStripCommandStyle(std::string const& strip); |
842 | | |
843 | | std::string GetEncodedLiteral(std::string const& lit); |
844 | 0 | virtual std::string& EncodeLiteral(std::string& lit) { return lit; } |
845 | | |
846 | | bool CheckCMP0171() const; |
847 | | |
848 | | void AddInstallScript(std::string const& file); |
849 | | void AddTestFile(std::string const& file); |
850 | | void AddCMakeFilesToRebuild(std::vector<std::string>& files) const; |
851 | | |
852 | | virtual std::set<std::string> const& GetDefaultConfigs() const |
853 | 0 | { |
854 | 0 | static std::set<std::string> configs; |
855 | 0 | return configs; |
856 | 0 | } |
857 | | |
858 | | bool ShouldWarnCMP0210(std::string const& lang); |
859 | | |
860 | | bool ShouldWarnExperimental(cm::string_view featureName, |
861 | | cm::string_view featureUuid); |
862 | | |
863 | | cm::optional<cmXcFrameworkPlist> GetXcFrameworkPListContent( |
864 | | std::string const& path) const; |
865 | | void SetXcFrameworkPListContent(std::string const& path, |
866 | | cmXcFrameworkPlist const& content); |
867 | | |
868 | | protected: |
869 | | virtual std::string GetTestBuildDependencyPath( |
870 | | cmGeneratorTarget const* target, std::string const& config) const; |
871 | | |
872 | | /** Get all targets produced under the given root, plus the transitive |
873 | | closure of targets on which they depend, possibly from other dirs. */ |
874 | | TargetDependSet GetTargetsForProject( |
875 | | cmLocalGenerator const* root, |
876 | | std::vector<cmLocalGenerator*> const& generators) const; |
877 | | |
878 | | bool IsRootOnlyTarget(cmGeneratorTarget* target) const; |
879 | | void AddTargetDepends(cmGeneratorTarget const* target, |
880 | | TargetDependSet& projectTargets) const; |
881 | | void SetLanguageEnabledFlag(std::string const& l, cmMakefile* mf); |
882 | | void SetLanguageEnabledMaps(std::string const& l, cmMakefile* mf); |
883 | | void FillExtensionToLanguageMap(std::string const& l, cmMakefile* mf); |
884 | | virtual bool CheckLanguages(std::vector<std::string> const& languages, |
885 | | cmMakefile* mf) const; |
886 | | virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang, |
887 | | cmValue envVar) const; |
888 | | |
889 | | virtual bool ComputeTargetDepends(); |
890 | | |
891 | | #if !defined(CMAKE_BOOTSTRAP) |
892 | | void WriteJsonContent(std::string const& fname, |
893 | | Json::Value const& value) const; |
894 | | void WriteInstallJson() const; |
895 | | #endif |
896 | | |
897 | | virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const; |
898 | | |
899 | | bool ApplyCXXStdTarget(); |
900 | | void WriteCxxImportErrorModules(); |
901 | | bool DiscoverSyntheticTargets(); |
902 | | |
903 | | bool AddHeaderSetVerification(); |
904 | | |
905 | | void CreateFileGenerateOutputs(); |
906 | | bool AddAutomaticSources(); |
907 | | |
908 | | std::string SelectMakeProgram(std::string const& makeProgram, |
909 | | std::string const& makeDefault = "") const; |
910 | | |
911 | | // Fill the ProjectMap, this must be called after LocalGenerators |
912 | | // has been populated. |
913 | | void FillProjectMap(); |
914 | | void CheckTargetProperties(); |
915 | | bool IsExcluded(cmStateSnapshot const& root, |
916 | | cmStateSnapshot const& snp) const; |
917 | | bool IsExcluded(cmLocalGenerator const* root, |
918 | | cmLocalGenerator const* gen) const; |
919 | | bool IsExcluded(cmLocalGenerator const* root, |
920 | | cmGeneratorTarget const* target) const; |
921 | 0 | virtual void InitializeProgressMarks() {} |
922 | | |
923 | | struct GlobalTargetInfo |
924 | | { |
925 | | std::string Name; |
926 | | std::string Message; |
927 | | cmCustomCommandLines CommandLines; |
928 | | std::vector<std::string> Depends; |
929 | | std::string WorkingDir; |
930 | | bool UsesTerminal = false; |
931 | | cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes; |
932 | | bool StdPipesUTF8 = false; |
933 | | std::string Role; |
934 | | }; |
935 | | |
936 | | void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets); |
937 | | |
938 | | void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets); |
939 | | void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets); |
940 | | void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets); |
941 | | void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const; |
942 | | void AddGlobalTarget_RebuildCache( |
943 | | std::vector<GlobalTargetInfo>& targets) const; |
944 | | void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets); |
945 | | void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf); |
946 | | |
947 | | void ReserveGlobalTargetCodegen(); |
948 | | |
949 | | // Execute user's callbacks and produce custom commands for file sets |
950 | | // attached to a custom rule |
951 | | void ConfigureRules(); |
952 | | |
953 | | std::string FindMakeProgramFile; |
954 | | std::string ConfiguredFilesPath; |
955 | | cmake* CMakeInstance; |
956 | | std::vector<std::unique_ptr<cmMakefile>> Makefiles; |
957 | | LocalGeneratorVector LocalGenerators; |
958 | | |
959 | | #ifndef CMAKE_BOOTSTRAP |
960 | | std::unique_ptr<cmQtAutoGenGlobalInitializer> QtAutoGen; |
961 | | #endif |
962 | | |
963 | | cmMakefile* CurrentConfigureMakefile; |
964 | | // map from project name to vector of local generators in that project |
965 | | std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap; |
966 | | |
967 | | // Set of named installation components requested by the project. |
968 | | std::set<std::string> InstallComponents; |
969 | | // Sets of named target exports |
970 | | cmExportSetMap ExportSets; |
971 | | std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets; |
972 | | std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets; |
973 | | std::vector<cmBuildSbomGenerator*> BuildSbomGenerators; |
974 | | std::vector<cmInstallSbomGenerator const*> InstallSbomGenerators; |
975 | | |
976 | | std::map<std::string, std::string> AliasTargets; |
977 | | |
978 | | cmTarget* FindTargetImpl(std::string const& name, |
979 | | cm::TargetDomainSet domains) const; |
980 | | |
981 | | cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const; |
982 | | |
983 | | std::string GetPredefinedTargetsFolder() const; |
984 | | |
985 | | private: |
986 | | using TargetMap = std::unordered_map<std::string, cmTarget*>; |
987 | | using GeneratorTargetMap = |
988 | | std::unordered_map<std::string, cmGeneratorTarget*>; |
989 | | using RuleMap = std::unordered_map<std::string, cmRule*>; |
990 | | using GeneratorRuleMap = std::unordered_map<std::string, cmGeneratorRule*>; |
991 | | using MakefileMap = std::unordered_map<std::string, cmMakefile*>; |
992 | | using LocalGeneratorMap = std::unordered_map<std::string, cmLocalGenerator*>; |
993 | | using TargetDirectoryRegistrationMap = |
994 | | std::map<cmGeneratorTarget const*, TargetDirectoryRegistration>; |
995 | | using TargetDirectoryMap = |
996 | | std::unordered_map<std::string, std::set<cmGeneratorTarget const*>>; |
997 | | // Map efficiently from target name to cmTarget instance. |
998 | | // Do not use this structure for looping over all targets. |
999 | | // It contains both normal and globally visible imported targets. |
1000 | | TargetMap TargetSearchIndex; |
1001 | | GeneratorTargetMap GeneratorTargetSearchIndex; |
1002 | | |
1003 | | // Map from target to a directory registration. |
1004 | | mutable TargetDirectoryRegistrationMap TargetDirectoryRegistrations; |
1005 | | // Map from target directories to targets using it. |
1006 | | mutable TargetDirectoryMap TargetDirectories; |
1007 | | |
1008 | | // Map efficiently from rule name to cmRule instance. |
1009 | | // Do not use this structure for looping over all rules. |
1010 | | // It may not contain all of them. |
1011 | | RuleMap RuleSearchIndex; |
1012 | | GeneratorRuleMap GeneratorRuleSearchIndex; |
1013 | | |
1014 | | // Map efficiently from source directory path to cmMakefile instance. |
1015 | | // Do not use this structure for looping over all directories. |
1016 | | // It may not contain all of them (see note in IndexMakefile method). |
1017 | | MakefileMap MakefileSearchIndex; |
1018 | | |
1019 | | // Map efficiently from source directory path to cmLocalGenerator instance. |
1020 | | // Do not use this structure for looping over all directories. |
1021 | | // Its order is not deterministic. |
1022 | | LocalGeneratorMap LocalGeneratorSearchIndex; |
1023 | | |
1024 | | void ComputeTargetOrder(); |
1025 | | void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index); |
1026 | | std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex; |
1027 | | |
1028 | | cmMakefile* TryCompileOuterMakefile; |
1029 | | std::map<std::string, bool> IgnoreExtensions; |
1030 | | std::set<std::string> LanguagesReadyForTryCompile; |
1031 | | std::set<std::string> LanguagesInProgress; |
1032 | | std::map<std::string, std::string> OutputExtensions; |
1033 | | std::map<std::string, std::string> LanguageToOutputExtension; |
1034 | | std::map<std::string, std::string> RustEmitToOutputExtension; |
1035 | | #if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L |
1036 | | std::map<std::string, std::string, std::less<void>> ExtensionToLanguage; |
1037 | | #else |
1038 | | std::map<std::string, std::string> ExtensionToLanguage; |
1039 | | #endif |
1040 | | std::map<std::string, int> LanguageToLinkerPreference; |
1041 | | |
1042 | | #if !defined(CMAKE_BOOTSTRAP) |
1043 | | std::unique_ptr<Json::StreamWriter> JsonWriter; |
1044 | | #endif |
1045 | | |
1046 | | #ifdef __APPLE__ |
1047 | | std::map<std::string, StripCommandStyle> StripCommandStyleMap; |
1048 | | #endif |
1049 | | |
1050 | | // Deferral id generation. |
1051 | | size_t NextDeferId = 0; |
1052 | | |
1053 | | // Record hashes for rules and outputs. |
1054 | | struct RuleHash |
1055 | | { |
1056 | | char Data[32]; |
1057 | | }; |
1058 | | std::map<std::string, RuleHash> RuleHashes; |
1059 | | void CheckRuleHashes(); |
1060 | | void CheckRuleHashes(std::string const& pfile, std::string const& home); |
1061 | | void WriteRuleHashes(std::string const& pfile); |
1062 | | |
1063 | | void WriteSummary(); |
1064 | | void WriteSummary(cmGeneratorTarget* target); |
1065 | | void FinalizeTargetConfiguration(); |
1066 | | |
1067 | | virtual void ForceLinkerLanguages(); |
1068 | | |
1069 | | void CheckTargetLinkLibraries() const; |
1070 | | bool CheckTargetsForMissingSources() const; |
1071 | | bool CheckTargetsForType() const; |
1072 | | void MarkTargetsForPchReuse() const; |
1073 | | |
1074 | | void CreateLocalGenerators(); |
1075 | | |
1076 | | void CheckCompilerIdCompatibility(cmMakefile* mf, |
1077 | | std::string const& lang) const; |
1078 | | |
1079 | | void ComputeBuildFileGenerators(); |
1080 | | |
1081 | | std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator; |
1082 | | |
1083 | | // track files replaced during a Generate |
1084 | | std::vector<std::string> FilesReplacedDuringGenerate; |
1085 | | |
1086 | | // Store computed inter-target dependencies. |
1087 | | using TargetDependMap = std::map<cmGeneratorTarget const*, TargetDependSet>; |
1088 | | TargetDependMap TargetDependencies; |
1089 | | |
1090 | | // Map from a custom-command primary output (collapsed full path) to the |
1091 | | // build-system target(s) that produce it. Built lazily on first use and |
1092 | | // cleared with the other generator members. |
1093 | | std::map<std::string, std::vector<cmGeneratorTarget*>> OutputOwnerIndex; |
1094 | | bool OutputOwnerIndexComputed = false; |
1095 | | void ComputeOutputOwnerIndex(); |
1096 | | |
1097 | | // Map from a configuration to a map from a linked artifact (collapsed full |
1098 | | // path) to the build-system target(s) that produce it. Built lazily for |
1099 | | // each configuration and cleared with the other generator members. |
1100 | | std::map<std::string, std::map<std::string, std::vector<cmGeneratorTarget*>>> |
1101 | | ArtifactOwnerIndex; |
1102 | | |
1103 | | // Every output and byproduct path recorded by any local generator, keyed |
1104 | | // as for cmLocalGenerator::GetSourcesWithOutput. Built lazily on first use |
1105 | | // and invalidated whenever a local generator records a new path. |
1106 | | std::unordered_set<std::string> GeneratedByBuildIndex; |
1107 | | bool GeneratedByBuildIndexComputed = false; |
1108 | | |
1109 | | // The build dependencies of each install rule for each configuration, |
1110 | | // computed once and shared by CheckInstallPrepTargets and |
1111 | | // GetInstallPrepTargets. |
1112 | | std::map<std::pair<cmInstallGenerator const*, std::string>, |
1113 | | std::vector<cmInstallGenerator::BuildDependency>> |
1114 | | InstallPrepDependencies; |
1115 | | std::vector<cmInstallGenerator::BuildDependency> const& |
1116 | | GetInstallPrepDependencies(cmInstallGenerator const* installer, |
1117 | | std::string const& config); |
1118 | | |
1119 | | friend class cmake; |
1120 | | void CreateGeneratorTargets( |
1121 | | TargetTypes targetTypes, cmMakefile* mf, cmLocalGenerator* lg, |
1122 | | std::map<cmTarget*, cmGeneratorTarget*> const& importedMap); |
1123 | | void CreateGeneratorTargets(TargetTypes targetTypes); |
1124 | | |
1125 | | void ClearGeneratorMembers(); |
1126 | | |
1127 | | bool CheckReservedTargetName(std::string const& targetName, |
1128 | | std::string const& reason) const; |
1129 | | bool CheckReservedTargetNamePrefix(std::string const& targetPrefix, |
1130 | | std::string const& reason) const; |
1131 | | |
1132 | | void IndexMakefile(cmMakefile* mf); |
1133 | | void IndexLocalGenerator(cmLocalGenerator* lg); |
1134 | | |
1135 | 0 | virtual char const* GetBuildIgnoreErrorsFlag() const { return nullptr; } |
1136 | | |
1137 | | bool UnsupportedVariableIsDefined(std::string const& name, |
1138 | | bool supported) const; |
1139 | | |
1140 | | // Cache directory content and target files to be built. |
1141 | | struct DirectoryContent |
1142 | | { |
1143 | | long LastDiskTime = -1; |
1144 | | std::set<std::string> All; |
1145 | | std::set<std::string> Generated; |
1146 | | }; |
1147 | | std::map<std::string, DirectoryContent> DirectoryContentMap; |
1148 | | |
1149 | | // Files known to exist, see SourceFileExists. |
1150 | | std::unordered_set<std::string> ExistingSourceFiles; |
1151 | | |
1152 | | // Cache parsed PList files |
1153 | | std::map<std::string, cmXcFrameworkPlist> XcFrameworkPListContentMap; |
1154 | | |
1155 | | // Set of binary directories on disk. |
1156 | | std::set<std::string> BinaryDirectories; |
1157 | | |
1158 | | // track targets to issue CMP0068 warning for. |
1159 | | std::set<std::string> CMP0068WarnTargets; |
1160 | | |
1161 | | // track tests to issue CMP0224 warning for. |
1162 | | std::set<std::string> CMP0224WarnTests; |
1163 | | |
1164 | | std::unordered_set<std::string> WarnedCMP0210Languages; |
1165 | | |
1166 | | std::unordered_set<std::string> WarnedExperimental; |
1167 | | |
1168 | | mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>> |
1169 | | FilenameTargetDepends; |
1170 | | |
1171 | | std::map<std::string, std::string> RealPaths; |
1172 | | |
1173 | | std::unordered_set<std::string> GeneratedFiles; |
1174 | | |
1175 | | std::vector<std::unique_ptr<cmInstallRuntimeDependencySet>> |
1176 | | RuntimeDependencySets; |
1177 | | std::map<std::string, cmInstallRuntimeDependencySet*> |
1178 | | RuntimeDependencySetsByName; |
1179 | | |
1180 | | std::vector<std::string> InstallScripts; |
1181 | | std::vector<std::string> TestFiles; |
1182 | | |
1183 | | #if !defined(CMAKE_BOOTSTRAP) |
1184 | | // Pool of file locks |
1185 | | cmFileLockPool FileLockPool; |
1186 | | #endif |
1187 | | |
1188 | | using PerLanguageModuleDatabases = |
1189 | | std::map<std::string, std::vector<std::string>>; |
1190 | | using PerConfigModuleDatabases = |
1191 | | std::map<std::string, PerLanguageModuleDatabases>; |
1192 | | PerConfigModuleDatabases PerConfigModuleDbs; |
1193 | | PerLanguageModuleDatabases PerLanguageModuleDbs; |
1194 | | |
1195 | | enum class IntermediateDirStrategy |
1196 | | { |
1197 | | Full, |
1198 | | Short, |
1199 | | }; |
1200 | | IntermediateDirStrategy IntDirStrategy = IntermediateDirStrategy::Full; |
1201 | | IntermediateDirStrategy QtAutogenIntDirStrategy = |
1202 | | IntermediateDirStrategy::Full; |
1203 | | |
1204 | | protected: |
1205 | | float FirstTimeProgress; |
1206 | | bool NeedSymbolicMark; |
1207 | | bool UseLinkScript; |
1208 | | bool ForceUnixPaths; |
1209 | | bool ToolSupportsColor; |
1210 | | bool InstallTargetEnabled; |
1211 | | bool AllowGlobalTargetCodegen; |
1212 | | }; |