88194b7a29ccb8a5aaac0d57680ff6e3d0e7eb27
[platform/upstream/cmake.git] / Source / cmLocalGenerator.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #ifndef cmLocalGenerator_h
4 #define cmLocalGenerator_h
5
6 #include "cmConfigure.h" // IWYU pragma: keep
7
8 #include <iosfwd>
9 #include <map>
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <unordered_map>
14 #include <vector>
15
16 #include "cm_kwiml.h"
17
18 #include "cmCustomCommandTypes.h"
19 #include "cmListFileCache.h"
20 #include "cmMessageType.h"
21 #include "cmOutputConverter.h"
22 #include "cmPolicies.h"
23 #include "cmStateSnapshot.h"
24
25 class cmComputeLinkInformation;
26 class cmCustomCommandGenerator;
27 class cmCustomCommandLines;
28 class cmGeneratorTarget;
29 class cmGlobalGenerator;
30 class cmImplicitDependsList;
31 class cmLinkLineComputer;
32 class cmMakefile;
33 class cmRulePlaceholderExpander;
34 class cmSourceFile;
35 class cmState;
36 class cmTarget;
37 class cmake;
38
39 /** \class cmLocalGenerator
40  * \brief Create required build files for a directory.
41  *
42  * Subclasses of this abstract class generate makefiles, DSP, etc for various
43  * platforms. This class should never be constructed directly. A
44  * GlobalGenerator will create it and invoke the appropriate commands on it.
45  */
46 class cmLocalGenerator : public cmOutputConverter
47 {
48 public:
49   cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
50   virtual ~cmLocalGenerator();
51
52   /**
53    * Generate the makefile for this directory.
54    */
55   virtual void Generate() {}
56
57   virtual void ComputeHomeRelativeOutputPath() {}
58
59   /**
60    * Calls TraceVSDependencies() on all targets of this generator.
61    */
62   void TraceDependencies();
63
64   virtual void AddHelperCommands() {}
65
66   /**
67    * Generate the install rules files in this directory.
68    */
69   void GenerateInstallRules();
70
71   /**
72    * Generate the test files for tests.
73    */
74   void GenerateTestFiles();
75
76   /**
77    * Generate a manifest of target files that will be built.
78    */
79   void ComputeTargetManifest();
80
81   bool ComputeTargetCompileFeatures();
82
83   bool IsRootMakefile() const;
84
85   //! Get the makefile for this generator
86   cmMakefile* GetMakefile() { return this->Makefile; }
87
88   //! Get the makefile for this generator, const version
89   const cmMakefile* GetMakefile() const { return this->Makefile; }
90
91   //! Get the GlobalGenerator this is associated with
92   cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
93   const cmGlobalGenerator* GetGlobalGenerator() const
94   {
95     return this->GlobalGenerator;
96   }
97
98   virtual cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const;
99
100   std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
101                                  cmGeneratorTarget& tgt) const;
102
103   cmState* GetState() const;
104   cmStateSnapshot GetStateSnapshot() const;
105
106   void AddArchitectureFlags(std::string& flags,
107                             cmGeneratorTarget const* target,
108                             const std::string& lang,
109                             const std::string& config);
110
111   void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
112                         const std::string& lang, const std::string& config);
113   void AddLanguageFlagsForLinking(std::string& flags,
114                                   cmGeneratorTarget const* target,
115                                   const std::string& lang,
116                                   const std::string& config);
117   void AddCMP0018Flags(std::string& flags, cmGeneratorTarget const* target,
118                        std::string const& lang, const std::string& config);
119   void AddVisibilityPresetFlags(std::string& flags,
120                                 cmGeneratorTarget const* target,
121                                 const std::string& lang);
122   void AddConfigVariableFlags(std::string& flags, const std::string& var,
123                               const std::string& config);
124   void AddCompilerRequirementFlag(std::string& flags,
125                                   cmGeneratorTarget const* target,
126                                   const std::string& lang);
127   //! Append flags to a string.
128   virtual void AppendFlags(std::string& flags,
129                            const std::string& newFlags) const;
130   virtual void AppendFlags(std::string& flags,
131                            const std::vector<BT<std::string>>& newFlags) const;
132   virtual void AppendFlagEscape(std::string& flags,
133                                 const std::string& rawFlag) const;
134   void AddPchDependencies(cmGeneratorTarget* target);
135   void AddUnityBuild(cmGeneratorTarget* target);
136   void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
137                             const std::string& config,
138                             const std::string& lang);
139   void AppendPositionIndependentLinkerFlags(std::string& flags,
140                                             cmGeneratorTarget* target,
141                                             const std::string& config,
142                                             const std::string& lang);
143   //! Get the include flags for the current makefile and language
144   std::string GetIncludeFlags(const std::vector<std::string>& includes,
145                               cmGeneratorTarget* target,
146                               const std::string& lang,
147                               bool forceFullPaths = false,
148                               bool forResponseFile = false,
149                               const std::string& config = "");
150
151   using GeneratorTargetVector =
152     std::vector<std::unique_ptr<cmGeneratorTarget>>;
153   const GeneratorTargetVector& GetGeneratorTargets() const
154   {
155     return this->GeneratorTargets;
156   }
157
158   void AddGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
159   void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
160   void AddOwnedImportedGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
161
162   cmGeneratorTarget* FindLocalNonAliasGeneratorTarget(
163     const std::string& name) const;
164   cmGeneratorTarget* FindGeneratorTargetToUse(const std::string& name) const;
165
166   /**
167    * Process a list of include directories
168    */
169   void AppendIncludeDirectories(std::vector<std::string>& includes,
170                                 std::string const& includes_list,
171                                 const cmSourceFile& sourceFile) const;
172   void AppendIncludeDirectories(std::vector<std::string>& includes,
173                                 const std::vector<std::string>& includes_vec,
174                                 const cmSourceFile& sourceFile) const;
175
176   /**
177    * Encode a list of preprocessor definitions for the compiler
178    * command line.
179    */
180   void AppendDefines(std::set<std::string>& defines,
181                      std::string const& defines_list) const;
182   void AppendDefines(std::set<BT<std::string>>& defines,
183                      std::string const& defines_list) const;
184   void AppendDefines(std::set<BT<std::string>>& defines,
185                      const std::vector<BT<std::string>>& defines_vec) const;
186
187   /**
188    * Encode a list of compile options for the compiler
189    * command line.
190    */
191   void AppendCompileOptions(std::string& options,
192                             std::string const& options_list,
193                             const char* regex = nullptr) const;
194   void AppendCompileOptions(std::string& options,
195                             const std::vector<std::string>& options_vec,
196                             const char* regex = nullptr) const;
197   void AppendCompileOptions(std::vector<BT<std::string>>& options,
198                             const std::vector<BT<std::string>>& options_vec,
199                             const char* regex = nullptr) const;
200
201   /**
202    * Join a set of defines into a definesString with a space separator.
203    */
204   void JoinDefines(const std::set<std::string>& defines,
205                    std::string& definesString, const std::string& lang);
206
207   /** Lookup and append options associated with a particular feature.  */
208   void AppendFeatureOptions(std::string& flags, const std::string& lang,
209                             const char* feature);
210
211   const char* GetFeature(const std::string& feature,
212                          const std::string& config);
213
214   /** \brief Get absolute path to dependency \a name
215    *
216    * Translate a dependency as given in CMake code to the name to
217    * appear in a generated build file.
218    * - If \a name is a utility target, returns false.
219    * - If \a name is a CMake target, it will be transformed to the real output
220    *   location of that target for the given configuration.
221    * - If \a name is the full path to a file, it will be returned.
222    * - Otherwise \a name is treated as a relative path with respect to
223    *   the source directory of this generator.  This should only be
224    *   used for dependencies of custom commands.
225    */
226   bool GetRealDependency(const std::string& name, const std::string& config,
227                          std::string& dep);
228
229   virtual std::string ConvertToIncludeReference(
230     std::string const& path,
231     cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL,
232     bool forceFullPaths = false);
233
234   /** Called from command-line hook to clear dependencies.  */
235   virtual void ClearDependencies(cmMakefile* /* mf */, bool /* verbose */) {}
236
237   /** Called from command-line hook to update dependencies.  */
238   virtual bool UpdateDependencies(const std::string& /* tgtInfo */,
239                                   bool /*verbose*/, bool /*color*/)
240   {
241     return true;
242   }
243
244   /** @brief Get the include directories for the current makefile and language
245    * and optional the compiler implicit include directories.
246    *
247    * @arg stripImplicitDirs Strip all directories found in
248    *      CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES from the result.
249    * @arg appendAllImplicitDirs Append all directories found in
250    *      CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES to the result.
251    */
252   std::vector<BT<std::string>> GetIncludeDirectoriesImplicit(
253     cmGeneratorTarget const* target, std::string const& lang = "C",
254     std::string const& config = "", bool stripImplicitDirs = true,
255     bool appendAllImplicitDirs = false) const;
256
257   /** @brief Get the include directories for the current makefile and language
258    * and optional the compiler implicit include directories.
259    *
260    * @arg dirs Directories are appended to this list
261    */
262   void GetIncludeDirectoriesImplicit(std::vector<std::string>& dirs,
263                                      cmGeneratorTarget const* target,
264                                      const std::string& lang = "C",
265                                      const std::string& config = "",
266                                      bool stripImplicitDirs = true,
267                                      bool appendAllImplicitDirs = false) const;
268
269   /** @brief Get the include directories for the current makefile and language.
270    * @arg dirs Include directories are appended to this list
271    */
272   void GetIncludeDirectories(std::vector<std::string>& dirs,
273                              cmGeneratorTarget const* target,
274                              const std::string& lang = "C",
275                              const std::string& config = "") const;
276
277   /** @brief Get the include directories for the current makefile and language.
278    * @return The include directory list
279    */
280   std::vector<BT<std::string>> GetIncludeDirectories(
281     cmGeneratorTarget const* target, std::string const& lang = "C",
282     std::string const& config = "") const;
283
284   void AddCompileOptions(std::string& flags, cmGeneratorTarget* target,
285                          const std::string& lang, const std::string& config);
286   void AddCompileOptions(std::vector<BT<std::string>>& flags,
287                          cmGeneratorTarget* target, const std::string& lang,
288                          const std::string& config);
289
290   /**
291    * Add a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a target.
292    */
293   cmTarget* AddCustomCommandToTarget(
294     const std::string& target, const std::vector<std::string>& byproducts,
295     const std::vector<std::string>& depends,
296     const cmCustomCommandLines& commandLines, cmCustomCommandType type,
297     const char* comment, const char* workingDir, bool escapeOldStyle = true,
298     bool uses_terminal = false, const std::string& depfile = "",
299     const std::string& job_pool = "", bool command_expand_lists = false,
300     cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
301
302   /**
303    * Add a custom command to a source file.
304    */
305   cmSourceFile* AddCustomCommandToOutput(
306     const std::string& output, const std::vector<std::string>& depends,
307     const std::string& main_dependency,
308     const cmCustomCommandLines& commandLines, const char* comment,
309     const char* workingDir, bool replace = false, bool escapeOldStyle = true,
310     bool uses_terminal = false, bool command_expand_lists = false,
311     const std::string& depfile = "", const std::string& job_pool = "");
312   cmSourceFile* AddCustomCommandToOutput(
313     const std::vector<std::string>& outputs,
314     const std::vector<std::string>& byproducts,
315     const std::vector<std::string>& depends,
316     const std::string& main_dependency,
317     const cmImplicitDependsList& implicit_depends,
318     const cmCustomCommandLines& commandLines, const char* comment,
319     const char* workingDir, bool replace = false, bool escapeOldStyle = true,
320     bool uses_terminal = false, bool command_expand_lists = false,
321     const std::string& depfile = "", const std::string& job_pool = "");
322
323   /**
324    * Add a utility to the build.  A utility target is a command that is run
325    * every time the target is built.
326    */
327   cmTarget* AddUtilityCommand(
328     const std::string& utilityName, bool excludeFromAll,
329     const char* workingDir, const std::vector<std::string>& byproducts,
330     const std::vector<std::string>& depends,
331     const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
332     const char* comment = nullptr, bool uses_terminal = false,
333     bool command_expand_lists = false, const std::string& job_pool = "");
334
335   std::string GetProjectName() const;
336
337   /** Compute the language used to compile the given source file.  */
338   std::string GetSourceFileLanguage(const cmSourceFile& source);
339
340   // Fill the vector with the target names for the object files,
341   // preprocessed files and assembly files.
342   void GetIndividualFileTargets(std::vector<std::string>&) {}
343
344   /**
345    * Get the relative path from the generator output directory to a
346    * per-target support directory.
347    */
348   virtual std::string GetTargetDirectory(
349     cmGeneratorTarget const* target) const;
350
351   /**
352    * Get the level of backwards compatibility requested by the project
353    * in this directory.  This is the value of the CMake variable
354    * CMAKE_BACKWARDS_COMPATIBILITY whose format is
355    * "major.minor[.patch]".  The returned integer is encoded as
356    *
357    *   CMake_VERSION_ENCODE(major, minor, patch)
358    *
359    * and is monotonically increasing with the CMake version.
360    */
361   KWIML_INT_uint64_t GetBackwardsCompatibility();
362
363   /**
364    * Test whether compatibility is set to a given version or lower.
365    */
366   bool NeedBackwardsCompatibility_2_4();
367
368   cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;
369
370   cmake* GetCMakeInstance() const;
371
372   std::string const& GetSourceDirectory() const;
373   std::string const& GetBinaryDirectory() const;
374
375   std::string const& GetCurrentBinaryDirectory() const;
376   std::string const& GetCurrentSourceDirectory() const;
377
378   /**
379    * Convert the given remote path to a relative path with respect to
380    * the given local path.  Both paths must use forward slashes and not
381    * already be escaped or quoted.
382    * The conversion is skipped if the paths are not both in the source
383    * or both in the binary tree.
384    */
385   std::string MaybeConvertToRelativePath(std::string const& local_path,
386                                          std::string const& remote_path) const;
387
388   /**
389    * Generate a macOS application bundle Info.plist file.
390    */
391   void GenerateAppleInfoPList(cmGeneratorTarget* target,
392                               const std::string& targetName,
393                               const std::string& fname);
394
395   /**
396    * Generate a macOS framework Info.plist file.
397    */
398   void GenerateFrameworkInfoPList(cmGeneratorTarget* target,
399                                   const std::string& targetName,
400                                   const std::string& fname);
401   /** Construct a comment for a custom command.  */
402   std::string ConstructComment(cmCustomCommandGenerator const& ccg,
403                                const char* default_comment = "");
404   // Compute object file names.
405   std::string GetObjectFileNameWithoutTarget(
406     const cmSourceFile& source, std::string const& dir_max,
407     bool* hasSourceExtension = nullptr,
408     char const* customOutputExtension = nullptr);
409
410   /** Fill out the static linker flags for the given target.  */
411   void GetStaticLibraryFlags(std::string& flags, std::string const& config,
412                              std::string const& linkLanguage,
413                              cmGeneratorTarget* target);
414   std::vector<BT<std::string>> GetStaticLibraryFlags(
415     std::string const& config, std::string const& linkLanguage,
416     cmGeneratorTarget* target);
417
418   /** Fill out these strings for the given target.  Libraries to link,
419    *  flags, and linkflags. */
420   void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
421                       const std::string& config, std::string& linkLibs,
422                       std::string& flags, std::string& linkFlags,
423                       std::string& frameworkPath, std::string& linkPath,
424                       cmGeneratorTarget* target);
425   void GetTargetFlags(
426     cmLinkLineComputer* linkLineComputer, const std::string& config,
427     std::vector<BT<std::string>>& linkLibs, std::string& flags,
428     std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
429     std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target);
430   void GetTargetDefines(cmGeneratorTarget const* target,
431                         std::string const& config, std::string const& lang,
432                         std::set<std::string>& defines) const;
433   std::set<BT<std::string>> GetTargetDefines(cmGeneratorTarget const* target,
434                                              std::string const& config,
435                                              std::string const& lang) const;
436   void GetTargetCompileFlags(cmGeneratorTarget* target,
437                              std::string const& config,
438                              std::string const& lang, std::string& flags);
439   std::vector<BT<std::string>> GetTargetCompileFlags(cmGeneratorTarget* target,
440                                                      std::string const& config,
441                                                      std::string const& lang);
442
443   std::string GetFrameworkFlags(std::string const& l,
444                                 std::string const& config,
445                                 cmGeneratorTarget* target);
446   virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
447                                             std::string const& config);
448
449   virtual void ComputeObjectFilenames(
450     std::map<cmSourceFile const*, std::string>& mapping,
451     cmGeneratorTarget const* gt = nullptr);
452
453   bool IsWindowsShell() const;
454   bool IsWatcomWMake() const;
455   bool IsMinGWMake() const;
456   bool IsNMake() const;
457   bool IsNinjaMulti() const;
458
459   void IssueMessage(MessageType t, std::string const& text) const;
460
461   void CreateEvaluationFileOutputs();
462   void CreateEvaluationFileOutputs(const std::string& config);
463   void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
464
465   const char* GetRuleLauncher(cmGeneratorTarget* target,
466                               const std::string& prop);
467
468 protected:
469   //! put all the libraries for a target on into the given stream
470   void OutputLinkLibraries(cmComputeLinkInformation* pcli,
471                            cmLinkLineComputer* linkLineComputer,
472                            std::string& linkLibraries,
473                            std::string& frameworkPath, std::string& linkPath);
474   void OutputLinkLibraries(cmComputeLinkInformation* pcli,
475                            cmLinkLineComputer* linkLineComputer,
476                            std::vector<BT<std::string>>& linkLibraries,
477                            std::string& frameworkPath,
478                            std::vector<BT<std::string>>& linkPath);
479
480   // Handle old-style install rules stored in the targets.
481   void GenerateTargetInstallRules(
482     std::ostream& os, const std::string& config,
483     std::vector<std::string> const& configurationTypes);
484
485   std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
486                                               std::string const& dir_max);
487
488   /** Check whether the native build system supports the given
489       definition.  Issues a warning.  */
490   virtual bool CheckDefinition(std::string const& define) const;
491
492   cmMakefile* Makefile;
493   cmStateSnapshot StateSnapshot;
494   cmListFileBacktrace DirectoryBacktrace;
495   cmGlobalGenerator* GlobalGenerator;
496   std::map<std::string, std::string> UniqueObjectNamesMap;
497   std::string::size_type ObjectPathMax;
498   std::set<std::string> ObjectMaxPathViolations;
499
500   std::set<std::string> EnvCPATH;
501
502   using GeneratorTargetMap =
503     std::unordered_map<std::string, cmGeneratorTarget*>;
504   GeneratorTargetMap GeneratorTargetSearchIndex;
505   GeneratorTargetVector GeneratorTargets;
506
507   std::set<cmGeneratorTarget const*> WarnCMP0063;
508   GeneratorTargetMap ImportedGeneratorTargets;
509   GeneratorTargetVector OwnedImportedGeneratorTargets;
510   std::map<std::string, std::string> AliasTargets;
511
512   std::map<std::string, std::string> Compilers;
513   std::map<std::string, std::string> VariableMappings;
514   std::string CompilerSysroot;
515   std::string LinkerSysroot;
516
517   bool EmitUniversalBinaryFlags;
518
519   KWIML_INT_uint64_t BackwardsCompatibility;
520   bool BackwardsCompatibilityFinal;
521
522 private:
523   void AddSharedFlags(std::string& flags, const std::string& lang,
524                       bool shared);
525   bool GetShouldUseOldFlags(bool shared, const std::string& lang) const;
526   void AddPositionIndependentFlags(std::string& flags, std::string const& l,
527                                    int targetType);
528
529   void ComputeObjectMaxPath();
530 };
531
532 #if !defined(CMAKE_BOOTSTRAP)
533 bool cmLocalGeneratorCheckObjectName(std::string& objName,
534                                      std::string::size_type dir_len,
535                                      std::string::size_type max_total_len);
536 #endif
537
538 namespace detail {
539 void AddCustomCommandToTarget(cmLocalGenerator& lg,
540                               const cmListFileBacktrace& lfbt,
541                               cmCommandOrigin origin, cmTarget* target,
542                               const std::vector<std::string>& byproducts,
543                               const std::vector<std::string>& depends,
544                               const cmCustomCommandLines& commandLines,
545                               cmCustomCommandType type, const char* comment,
546                               const char* workingDir, bool escapeOldStyle,
547                               bool uses_terminal, const std::string& depfile,
548                               const std::string& job_pool,
549                               bool command_expand_lists);
550
551 cmSourceFile* AddCustomCommandToOutput(
552   cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
553   cmCommandOrigin origin, const std::vector<std::string>& outputs,
554   const std::vector<std::string>& byproducts,
555   const std::vector<std::string>& depends, const std::string& main_dependency,
556   const cmImplicitDependsList& implicit_depends,
557   const cmCustomCommandLines& commandLines, const char* comment,
558   const char* workingDir, bool replace, bool escapeOldStyle,
559   bool uses_terminal, bool command_expand_lists, const std::string& depfile,
560   const std::string& job_pool);
561
562 void AppendCustomCommandToOutput(cmLocalGenerator& lg,
563                                  const cmListFileBacktrace& lfbt,
564                                  const std::string& output,
565                                  const std::vector<std::string>& depends,
566                                  const cmImplicitDependsList& implicit_depends,
567                                  const cmCustomCommandLines& commandLines);
568
569 void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
570                        cmCommandOrigin origin, cmTarget* target,
571                        const cmUtilityOutput& force, const char* workingDir,
572                        const std::vector<std::string>& byproducts,
573                        const std::vector<std::string>& depends,
574                        const cmCustomCommandLines& commandLines,
575                        bool escapeOldStyle, const char* comment,
576                        bool uses_terminal, bool command_expand_lists,
577                        const std::string& job_pool);
578 }
579
580 #endif