resolve cyclic dependency with zstd
[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 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <cstddef>
8 #include <iosfwd>
9 #include <map>
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <unordered_map>
14 #include <utility>
15 #include <vector>
16
17 #include <cm/optional>
18
19 #include <cm3p/kwiml/int.h>
20
21 #include "cmCustomCommandTypes.h"
22 #include "cmListFileCache.h"
23 #include "cmMessageType.h"
24 #include "cmOutputConverter.h"
25 #include "cmPolicies.h"
26 #include "cmStateSnapshot.h"
27 #include "cmValue.h"
28
29 class cmCompiledGeneratorExpression;
30 class cmComputeLinkInformation;
31 class cmCustomCommand;
32 class cmCustomCommandGenerator;
33 class cmCustomCommandLines;
34 class cmGeneratorTarget;
35 class cmGlobalGenerator;
36 class cmImplicitDependsList;
37 class cmLinkLineComputer;
38 class cmLinkLineDeviceComputer;
39 class cmMakefile;
40 class cmRulePlaceholderExpander;
41 class cmSourceFile;
42 class cmState;
43 class cmTarget;
44 class cmake;
45
46 template <typename Iter>
47 class cmRange;
48
49 /** Flag if byproducts shall also be considered.  */
50 enum class cmSourceOutputKind
51 {
52   OutputOnly,
53   OutputOrByproduct
54 };
55
56 /** What scanner to use for dependencies lookup.  */
57 enum class cmDependencyScannerKind
58 {
59   CMake,
60   Compiler
61 };
62
63 /** What to compute language flags for */
64 enum class cmBuildStep
65 {
66   Compile,
67   Link
68 };
69
70 /** Target and source file which have a specific output.  */
71 struct cmSourcesWithOutput
72 {
73   /** Target with byproduct.  */
74   cmTarget* Target = nullptr;
75
76   /** Source file with output or byproduct.  */
77   cmSourceFile* Source = nullptr;
78   bool SourceIsByproduct = false;
79 };
80
81 /** \class cmLocalGenerator
82  * \brief Create required build files for a directory.
83  *
84  * Subclasses of this abstract class generate makefiles, DSP, etc for various
85  * platforms. This class should never be constructed directly. A
86  * GlobalGenerator will create it and invoke the appropriate commands on it.
87  */
88 class cmLocalGenerator : public cmOutputConverter
89 {
90 public:
91   cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
92   virtual ~cmLocalGenerator();
93
94   /**
95    * Generate the makefile for this directory.
96    */
97   virtual void Generate() {}
98
99   virtual void ComputeHomeRelativeOutputPath() {}
100
101   /**
102    * Calls TraceVSDependencies() on all targets of this generator.
103    */
104   void TraceDependencies() const;
105
106   virtual void AddHelperCommands() {}
107
108   /**
109    * Generate the install rules files in this directory.
110    */
111   void GenerateInstallRules();
112
113   /**
114    * Generate the test files for tests.
115    */
116   void GenerateTestFiles();
117
118   /**
119    * Generate a manifest of target files that will be built.
120    */
121   void ComputeTargetManifest();
122
123   bool ComputeTargetCompileFeatures();
124
125   bool IsRootMakefile() const;
126
127   //! Get the makefile for this generator
128   cmMakefile* GetMakefile() { return this->Makefile; }
129
130   //! Get the makefile for this generator, const version
131   const cmMakefile* GetMakefile() const { return this->Makefile; }
132
133   //! Get the GlobalGenerator this is associated with
134   cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
135   const cmGlobalGenerator* GetGlobalGenerator() const
136   {
137     return this->GlobalGenerator;
138   }
139
140   virtual cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const;
141
142   std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
143                                  cmGeneratorTarget& tgt) const;
144
145   cmState* GetState() const;
146   cmStateSnapshot GetStateSnapshot() const;
147
148   void AddArchitectureFlags(std::string& flags,
149                             cmGeneratorTarget const* target,
150                             const std::string& lang, const std::string& config,
151                             const std::string& filterArch = std::string());
152
153   void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
154                         cmBuildStep compileOrLink, const std::string& lang,
155                         const std::string& config);
156   void AddLanguageFlagsForLinking(std::string& flags,
157                                   cmGeneratorTarget const* target,
158                                   const std::string& lang,
159                                   const std::string& config);
160   void AddCMP0018Flags(std::string& flags, cmGeneratorTarget const* target,
161                        std::string const& lang, const std::string& config);
162   void AddVisibilityPresetFlags(std::string& flags,
163                                 cmGeneratorTarget const* target,
164                                 const std::string& lang);
165   void AddConfigVariableFlags(std::string& flags, const std::string& var,
166                               const std::string& config);
167   void AddCompilerRequirementFlag(std::string& flags,
168                                   cmGeneratorTarget const* target,
169                                   const std::string& lang,
170                                   const std::string& config);
171   void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang);
172   //! Append flags to a string.
173   virtual void AppendFlags(std::string& flags,
174                            const std::string& newFlags) const;
175   virtual void AppendFlags(std::string& flags,
176                            const std::vector<BT<std::string>>& newFlags) const;
177   virtual void AppendFlagEscape(std::string& flags,
178                                 const std::string& rawFlag) const;
179   void AddISPCDependencies(cmGeneratorTarget* target);
180   void AddPchDependencies(cmGeneratorTarget* target);
181   void AddUnityBuild(cmGeneratorTarget* target);
182   virtual void AddXCConfigSources(cmGeneratorTarget* /* target */) {}
183   void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
184                             const std::string& config,
185                             const std::string& lang);
186   void AppendPositionIndependentLinkerFlags(std::string& flags,
187                                             cmGeneratorTarget* target,
188                                             const std::string& config,
189                                             const std::string& lang);
190   void AppendModuleDefinitionFlag(std::string& flags,
191                                   cmGeneratorTarget const* target,
192                                   cmLinkLineComputer* linkLineComputer,
193                                   std::string const& config);
194   bool AppendLWYUFlags(std::string& flags, const cmGeneratorTarget* target,
195                        const std::string& lang);
196
197   //! Get the include flags for the current makefile and language
198   std::string GetIncludeFlags(std::vector<std::string> const& includes,
199                               cmGeneratorTarget* target,
200                               std::string const& lang,
201                               std::string const& config,
202                               bool forResponseFile = false);
203
204   using GeneratorTargetVector =
205     std::vector<std::unique_ptr<cmGeneratorTarget>>;
206   const GeneratorTargetVector& GetGeneratorTargets() const
207   {
208     return this->GeneratorTargets;
209   }
210
211   const GeneratorTargetVector& GetOwnedImportedGeneratorTargets() const
212   {
213     return this->OwnedImportedGeneratorTargets;
214   }
215
216   void AddGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
217   void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
218   void AddOwnedImportedGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
219
220   cmGeneratorTarget* FindLocalNonAliasGeneratorTarget(
221     const std::string& name) const;
222   cmGeneratorTarget* FindGeneratorTargetToUse(const std::string& name) const;
223
224   /**
225    * Process a list of include directories
226    */
227   void AppendIncludeDirectories(std::vector<std::string>& includes,
228                                 std::string const& includes_list,
229                                 const cmSourceFile& sourceFile) const;
230   void AppendIncludeDirectories(std::vector<std::string>& includes,
231                                 const std::vector<std::string>& includes_vec,
232                                 const cmSourceFile& sourceFile) const;
233
234   /**
235    * Encode a list of preprocessor definitions for the compiler
236    * command line.
237    */
238   void AppendDefines(std::set<std::string>& defines,
239                      std::string const& defines_list) const;
240   void AppendDefines(std::set<BT<std::string>>& defines,
241                      std::string const& defines_list) const;
242   void AppendDefines(std::set<BT<std::string>>& defines,
243                      const std::vector<BT<std::string>>& defines_vec) const;
244
245   /**
246    * Encode a list of compile options for the compiler
247    * command line.
248    */
249   void AppendCompileOptions(std::string& options,
250                             std::string const& options_list,
251                             const char* regex = nullptr) const;
252   void AppendCompileOptions(std::string& options,
253                             const std::vector<std::string>& options_vec,
254                             const char* regex = nullptr) const;
255   void AppendCompileOptions(std::vector<BT<std::string>>& options,
256                             const std::vector<BT<std::string>>& options_vec,
257                             const char* regex = nullptr) const;
258
259   /**
260    * Join a set of defines into a definesString with a space separator.
261    */
262   void JoinDefines(const std::set<std::string>& defines,
263                    std::string& definesString, const std::string& lang);
264
265   /** Lookup and append options associated with a particular feature.  */
266   void AppendFeatureOptions(std::string& flags, const std::string& lang,
267                             const char* feature);
268
269   cmValue GetFeature(const std::string& feature, const std::string& config);
270
271   /** \brief Get absolute path to dependency \a name
272    *
273    * Translate a dependency as given in CMake code to the name to
274    * appear in a generated build file.
275    * - If \a name is a utility target, returns false.
276    * - If \a name is a CMake target, it will be transformed to the real output
277    *   location of that target for the given configuration.
278    * - If \a name is the full path to a file, it will be returned.
279    * - Otherwise \a name is treated as a relative path with respect to
280    *   the source directory of this generator.  This should only be
281    *   used for dependencies of custom commands.
282    */
283   bool GetRealDependency(const std::string& name, const std::string& config,
284                          std::string& dep);
285
286   /** Called from command-line hook to clear dependencies.  */
287   virtual void ClearDependencies(cmMakefile* /* mf */, bool /* verbose */) {}
288
289   /** Called from command-line hook to update dependencies.  */
290   virtual bool UpdateDependencies(const std::string& /* tgtInfo */,
291                                   bool /*verbose*/, bool /*color*/)
292   {
293     return true;
294   }
295
296   /** @brief Get the include directories for the current makefile and language
297    * and optional the compiler implicit include directories.
298    *
299    * @arg stripImplicitDirs Strip all directories found in
300    *      CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES from the result.
301    * @arg appendAllImplicitDirs Append all directories found in
302    *      CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES to the result.
303    */
304   std::vector<BT<std::string>> GetIncludeDirectoriesImplicit(
305     cmGeneratorTarget const* target, std::string const& lang = "C",
306     std::string const& config = "", bool stripImplicitDirs = true,
307     bool appendAllImplicitDirs = false) const;
308
309   /** @brief Get the include directories for the current makefile and language
310    * and optional the compiler implicit include directories.
311    *
312    * @arg dirs Directories are appended to this list
313    */
314   void GetIncludeDirectoriesImplicit(std::vector<std::string>& dirs,
315                                      cmGeneratorTarget const* target,
316                                      const std::string& lang = "C",
317                                      const std::string& config = "",
318                                      bool stripImplicitDirs = true,
319                                      bool appendAllImplicitDirs = false) const;
320
321   /** @brief Get the include directories for the current makefile and language.
322    * @arg dirs Include directories are appended to this list
323    */
324   void GetIncludeDirectories(std::vector<std::string>& dirs,
325                              cmGeneratorTarget const* target,
326                              const std::string& lang = "C",
327                              const std::string& config = "") const;
328
329   /** @brief Get the include directories for the current makefile and language.
330    * @return The include directory list
331    */
332   std::vector<BT<std::string>> GetIncludeDirectories(
333     cmGeneratorTarget const* target, std::string const& lang = "C",
334     std::string const& config = "") const;
335
336   void AddCompileOptions(std::string& flags, cmGeneratorTarget* target,
337                          const std::string& lang, const std::string& config);
338   void AddCompileOptions(std::vector<BT<std::string>>& flags,
339                          cmGeneratorTarget* target, const std::string& lang,
340                          const std::string& config);
341
342   /**
343    * Add a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a target.
344    */
345   cmTarget* AddCustomCommandToTarget(
346     const std::string& target, cmCustomCommandType type,
347     std::unique_ptr<cmCustomCommand> cc,
348     cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
349
350   /**
351    * Add a custom command to a source file.
352    */
353   cmSourceFile* AddCustomCommandToOutput(std::unique_ptr<cmCustomCommand> cc,
354                                          bool replace = false);
355
356   /**
357    * Add a utility to the build.  A utility target is a command that is run
358    * every time the target is built.
359    */
360   cmTarget* AddUtilityCommand(const std::string& utilityName,
361                               bool excludeFromAll,
362                               std::unique_ptr<cmCustomCommand> cc);
363
364   virtual std::string CreateUtilityOutput(
365     std::string const& targetName, std::vector<std::string> const& byproducts,
366     cmListFileBacktrace const& bt);
367
368   virtual std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
369     cmCustomCommand const& cc, std::string const& config);
370
371   std::vector<std::string> ExpandCustomCommandOutputPaths(
372     cmCompiledGeneratorExpression const& cge, std::string const& config);
373   std::vector<std::string> ExpandCustomCommandOutputGenex(
374     std::string const& o, cmListFileBacktrace const& bt);
375
376   /**
377    * Add target byproducts.
378    */
379   void AddTargetByproducts(cmTarget* target,
380                            const std::vector<std::string>& byproducts,
381                            cmListFileBacktrace const& bt,
382                            cmCommandOrigin origin);
383
384   enum class OutputRole
385   {
386     Primary,
387     Byproduct,
388   };
389
390   /**
391    * Add source file outputs.
392    */
393   void AddSourceOutputs(cmSourceFile* source,
394                         std::vector<std::string> const& outputs,
395                         OutputRole role, cmListFileBacktrace const& bt,
396                         cmCommandOrigin origin);
397
398   /**
399    * Return the target if the provided source name is a byproduct of a utility
400    * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
401    * Return the source file which has the provided source name as output.
402    */
403   cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
404
405   /**
406    * Is there a source file that has the provided source name as an output?
407    * If so then return it.
408    */
409   cmSourceFile* GetSourceFileWithOutput(
410     const std::string& name,
411     cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
412
413   std::string GetProjectName() const;
414
415   /** Compute the language used to compile the given source file.  */
416   std::string GetSourceFileLanguage(const cmSourceFile& source);
417
418   // Fill the vector with the target names for the object files,
419   // preprocessed files and assembly files.
420   void GetIndividualFileTargets(std::vector<std::string>&) {}
421
422   /**
423    * Get the relative path from the generator output directory to a
424    * per-target support directory.
425    */
426   virtual std::string GetTargetDirectory(
427     cmGeneratorTarget const* target) const;
428
429   /**
430    * Get the level of backwards compatibility requested by the project
431    * in this directory.  This is the value of the CMake variable
432    * CMAKE_BACKWARDS_COMPATIBILITY whose format is
433    * "major.minor[.patch]".  The returned integer is encoded as
434    *
435    *   CMake_VERSION_ENCODE(major, minor, patch)
436    *
437    * and is monotonically increasing with the CMake version.
438    */
439   KWIML_INT_uint64_t GetBackwardsCompatibility();
440
441   /**
442    * Test whether compatibility is set to a given version or lower.
443    */
444   bool NeedBackwardsCompatibility_2_4();
445
446   cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;
447
448   cmake* GetCMakeInstance() const;
449
450   std::string const& GetSourceDirectory() const;
451   std::string const& GetBinaryDirectory() const;
452
453   std::string const& GetCurrentBinaryDirectory() const;
454   std::string const& GetCurrentSourceDirectory() const;
455
456   /**
457    * Generate a macOS application bundle Info.plist file.
458    */
459   void GenerateAppleInfoPList(cmGeneratorTarget* target,
460                               const std::string& targetName,
461                               const std::string& fname);
462
463   /**
464    * Generate a macOS framework Info.plist file.
465    */
466   void GenerateFrameworkInfoPList(cmGeneratorTarget* target,
467                                   const std::string& targetName,
468                                   const std::string& fname);
469   /** Construct a comment for a custom command.  */
470   std::string ConstructComment(cmCustomCommandGenerator const& ccg,
471                                const char* default_comment = "") const;
472   // Compute object file names.
473   std::string GetObjectFileNameWithoutTarget(
474     const cmSourceFile& source, std::string const& dir_max,
475     bool* hasSourceExtension = nullptr,
476     char const* customOutputExtension = nullptr);
477
478   /** Fill out the static linker flags for the given target.  */
479   void GetStaticLibraryFlags(std::string& flags, std::string const& config,
480                              std::string const& linkLanguage,
481                              cmGeneratorTarget* target);
482   std::vector<BT<std::string>> GetStaticLibraryFlags(
483     std::string const& config, std::string const& linkLanguage,
484     cmGeneratorTarget* target);
485
486   /** Fill out these strings for the given target.  Libraries to link,
487    *  flags, and linkflags. */
488   void GetDeviceLinkFlags(cmLinkLineDeviceComputer& linkLineComputer,
489                           const std::string& config, std::string& linkLibs,
490                           std::string& linkFlags, std::string& frameworkPath,
491                           std::string& linkPath, cmGeneratorTarget* target);
492
493   void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
494                       const std::string& config, std::string& linkLibs,
495                       std::string& flags, std::string& linkFlags,
496                       std::string& frameworkPath, std::string& linkPath,
497                       cmGeneratorTarget* target);
498   void GetTargetFlags(
499     cmLinkLineComputer* linkLineComputer, const std::string& config,
500     std::vector<BT<std::string>>& linkLibs, std::string& flags,
501     std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
502     std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target);
503   void GetTargetDefines(cmGeneratorTarget const* target,
504                         std::string const& config, std::string const& lang,
505                         std::set<std::string>& defines) const;
506   std::set<BT<std::string>> GetTargetDefines(cmGeneratorTarget const* target,
507                                              std::string const& config,
508                                              std::string const& lang) const;
509   void GetTargetCompileFlags(cmGeneratorTarget* target,
510                              std::string const& config,
511                              std::string const& lang, std::string& flags,
512                              std::string const& arch);
513   std::vector<BT<std::string>> GetTargetCompileFlags(
514     cmGeneratorTarget* target, std::string const& config,
515     std::string const& lang, std::string const& arch = std::string());
516
517   std::string GetFrameworkFlags(std::string const& l,
518                                 std::string const& config,
519                                 cmGeneratorTarget* target);
520   virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
521                                             std::string const& config);
522
523   virtual void ComputeObjectFilenames(
524     std::map<cmSourceFile const*, std::string>& mapping,
525     cmGeneratorTarget const* gt = nullptr);
526
527   bool IsWindowsShell() const;
528   bool IsWatcomWMake() const;
529   bool IsMinGWMake() const;
530   bool IsNMake() const;
531   bool IsNinjaMulti() const;
532
533   void IssueMessage(MessageType t, std::string const& text) const;
534
535   void CreateEvaluationFileOutputs();
536   void CreateEvaluationFileOutputs(const std::string& config);
537   void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
538
539   cmValue GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop);
540
541 protected:
542   // The default implementation converts to a Windows shortpath to
543   // help older toolchains handle spaces and such.  A generator may
544   // override this to avoid that conversion.
545   virtual std::string ConvertToIncludeReference(
546     std::string const& path, cmOutputConverter::OutputFormat format);
547
548   //! put all the libraries for a target on into the given stream
549   void OutputLinkLibraries(cmComputeLinkInformation* pcli,
550                            cmLinkLineComputer* linkLineComputer,
551                            std::string& linkLibraries,
552                            std::string& frameworkPath, std::string& linkPath);
553   void OutputLinkLibraries(cmComputeLinkInformation* pcli,
554                            cmLinkLineComputer* linkLineComputer,
555                            std::vector<BT<std::string>>& linkLibraries,
556                            std::string& frameworkPath,
557                            std::vector<BT<std::string>>& linkPath);
558
559   // Handle old-style install rules stored in the targets.
560   void GenerateTargetInstallRules(
561     std::ostream& os, const std::string& config,
562     std::vector<std::string> const& configurationTypes);
563
564   virtual void AddGeneratorSpecificInstallSetup(std::ostream&) {}
565
566   std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
567                                               std::string const& dir_max);
568
569   /** Check whether the native build system supports the given
570       definition.  Issues a warning.  */
571   virtual bool CheckDefinition(std::string const& define) const;
572
573   cmMakefile* Makefile;
574   cmListFileBacktrace DirectoryBacktrace;
575   cmGlobalGenerator* GlobalGenerator;
576   std::map<std::string, std::string> UniqueObjectNamesMap;
577   std::string::size_type ObjectPathMax;
578   std::set<std::string> ObjectMaxPathViolations;
579
580   std::vector<std::string> EnvCPATH;
581
582   using GeneratorTargetMap =
583     std::unordered_map<std::string, cmGeneratorTarget*>;
584   GeneratorTargetMap GeneratorTargetSearchIndex;
585   GeneratorTargetVector GeneratorTargets;
586
587   std::set<cmGeneratorTarget const*> WarnCMP0063;
588   GeneratorTargetMap ImportedGeneratorTargets;
589   GeneratorTargetVector OwnedImportedGeneratorTargets;
590   std::map<std::string, std::string> AliasTargets;
591
592   std::map<std::string, std::string> Compilers;
593   std::map<std::string, std::string> VariableMappings;
594   std::string CompilerSysroot;
595   std::string LinkerSysroot;
596   std::unordered_map<std::string, std::string> AppleArchSysroots;
597
598   bool EmitUniversalBinaryFlags;
599
600   KWIML_INT_uint64_t BackwardsCompatibility;
601   bool BackwardsCompatibilityFinal;
602
603 private:
604   /**
605    * See LinearGetSourceFileWithOutput for background information
606    */
607   cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
608
609   /**
610    * Generalized old version of GetSourceFileWithOutput kept for
611    * backward-compatibility. It implements a linear search and supports
612    * relative file paths. It is used as a fall back by GetSourceFileWithOutput
613    * and GetSourcesWithOutput.
614    */
615   cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
616                                               cmSourceOutputKind kind,
617                                               bool& byproduct) const;
618   struct SourceEntry
619   {
620     cmSourcesWithOutput Sources;
621   };
622
623   // A map for fast output to input look up.
624   using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
625   OutputToSourceMap OutputToSource;
626
627   void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target,
628                                cmListFileBacktrace const& bt,
629                                cmCommandOrigin origin);
630   void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
631                                OutputRole role, cmListFileBacktrace const& bt,
632                                cmCommandOrigin origin);
633
634   void AddSharedFlags(std::string& flags, const std::string& lang,
635                       bool shared);
636   bool GetShouldUseOldFlags(bool shared, const std::string& lang) const;
637   void AddPositionIndependentFlags(std::string& flags, std::string const& l,
638                                    int targetType);
639
640   void ComputeObjectMaxPath();
641   bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs,
642                                       cmValue sysroot);
643
644   void CopyPchCompilePdb(const std::string& config, cmGeneratorTarget* target,
645                          const std::string& ReuseFrom,
646                          cmGeneratorTarget* reuseTarget,
647                          std::vector<std::string> const& extensions);
648
649   // Returns MSVC_DEBUG_INFORMATION_FORMAT value if CMP0141 is NEW.
650   cm::optional<std::string> GetMSVCDebugFormatName(
651     std::string const& config, cmGeneratorTarget const* target);
652
653   struct UnityBatchedSource
654   {
655     cmSourceFile* Source = nullptr;
656     std::vector<size_t> Configs;
657     UnityBatchedSource(cmSourceFile* sf)
658       : Source(sf)
659     {
660     }
661   };
662   struct UnitySource
663   {
664     std::string Path;
665     bool PerConfig = false;
666     UnitySource(std::string path, bool perConfig)
667       : Path(std::move(path))
668       , PerConfig(perConfig)
669     {
670     }
671   };
672
673   UnitySource WriteUnitySource(
674     cmGeneratorTarget* target, std::vector<std::string> const& configs,
675     cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
676     cmValue beforeInclude, cmValue afterInclude, std::string filename) const;
677   void WriteUnitySourceInclude(std::ostream& unity_file,
678                                cm::optional<std::string> const& cond,
679                                std::string const& sf_full_path,
680                                cmValue beforeInclude, cmValue afterInclude,
681                                cmValue uniqueIdName) const;
682   std::vector<UnitySource> AddUnityFilesModeAuto(
683     cmGeneratorTarget* target, std::string const& lang,
684     std::vector<std::string> const& configs,
685     std::vector<UnityBatchedSource> const& filtered_sources,
686     cmValue beforeInclude, cmValue afterInclude,
687     std::string const& filename_base, size_t batchSize);
688   std::vector<UnitySource> AddUnityFilesModeGroup(
689     cmGeneratorTarget* target, std::string const& lang,
690     std::vector<std::string> const& configs,
691     std::vector<UnityBatchedSource> const& filtered_sources,
692     cmValue beforeInclude, cmValue afterInclude,
693     std::string const& filename_base);
694 };
695
696 #if !defined(CMAKE_BOOTSTRAP)
697 bool cmLocalGeneratorCheckObjectName(std::string& objName,
698                                      std::string::size_type dir_len,
699                                      std::string::size_type max_total_len);
700 #endif
701
702 namespace detail {
703 void AddCustomCommandToTarget(cmLocalGenerator& lg, cmCommandOrigin origin,
704                               cmTarget* target, cmCustomCommandType type,
705                               std::unique_ptr<cmCustomCommand> cc);
706
707 cmSourceFile* AddCustomCommandToOutput(cmLocalGenerator& lg,
708                                        cmCommandOrigin origin,
709                                        std::unique_ptr<cmCustomCommand> cc,
710                                        bool replace);
711
712 void AppendCustomCommandToOutput(cmLocalGenerator& lg,
713                                  const cmListFileBacktrace& lfbt,
714                                  const std::string& output,
715                                  const std::vector<std::string>& depends,
716                                  const cmImplicitDependsList& implicit_depends,
717                                  const cmCustomCommandLines& commandLines);
718
719 void AddUtilityCommand(cmLocalGenerator& lg, cmCommandOrigin origin,
720                        cmTarget* target, std::unique_ptr<cmCustomCommand> cc);
721
722 std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target);
723 std::vector<std::string> ComputeISPCExtraObjects(
724   std::string const& objectName, std::string const& buildDirectory,
725   std::vector<std::string> const& ispcSuffixes);
726 }