resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmMakefile.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 <deque>
9 #include <functional>
10 #include <map>
11 #include <memory>
12 #include <set>
13 #include <stack>
14 #include <string>
15 #include <unordered_map>
16 #include <utility>
17 #include <vector>
18
19 #include <cm/optional>
20 #include <cm/string_view>
21
22 #include "cmsys/RegularExpression.hxx"
23
24 #include "cm_sys_stat.h"
25
26 #include "cmAlgorithms.h"
27 #include "cmCustomCommand.h"
28 #include "cmCustomCommandTypes.h"
29 #include "cmListFileCache.h"
30 #include "cmMessageType.h"
31 #include "cmNewLineStyle.h"
32 #include "cmPolicies.h"
33 #include "cmSourceFileLocationKind.h"
34 #include "cmStateSnapshot.h"
35 #include "cmStateTypes.h"
36 #include "cmValue.h"
37
38 // IWYU does not see that 'std::unordered_map<std::string, cmTarget>'
39 // will not compile without the complete type.
40 #include "cmTarget.h" // IWYU pragma: keep
41
42 #if !defined(CMAKE_BOOTSTRAP)
43 #  include "cmSourceGroup.h"
44 #endif
45
46 class cmCompiledGeneratorExpression;
47 class cmCustomCommandLines;
48 class cmExecutionStatus;
49 class cmExpandedCommandArgument;
50 class cmExportBuildFileGenerator;
51 class cmFunctionBlocker;
52 class cmGeneratorExpressionEvaluationFile;
53 class cmGlobalGenerator;
54 class cmInstallGenerator;
55 class cmLocalGenerator;
56 class cmMessenger;
57 class cmSourceFile;
58 class cmState;
59 class cmTest;
60 class cmTestGenerator;
61 class cmVariableWatch;
62 class cmake;
63
64 /** A type-safe wrapper for a string representing a directory id.  */
65 class cmDirectoryId
66 {
67 public:
68   cmDirectoryId(std::string s);
69   std::string String;
70 };
71
72 /** \class cmMakefile
73  * \brief Process the input CMakeLists.txt file.
74  *
75  * Process and store into memory the input CMakeLists.txt file.
76  * Each CMakeLists.txt file is parsed and the commands found there
77  * are added into the build process.
78  */
79 class cmMakefile
80 {
81 public:
82   /* Mark a variable as used */
83   void MarkVariableAsUsed(const std::string& var);
84   /* return true if a variable has been initialized */
85   bool VariableInitialized(const std::string&) const;
86
87   /**
88    * Construct an empty makefile.
89    */
90   cmMakefile(cmGlobalGenerator* globalGenerator,
91              const cmStateSnapshot& snapshot);
92
93   /**
94    * Destructor.
95    */
96   ~cmMakefile();
97
98   cmMakefile(cmMakefile const&) = delete;
99   cmMakefile& operator=(cmMakefile const&) = delete;
100
101   cmDirectoryId GetDirectoryId() const;
102
103   bool ReadListFile(const std::string& filename);
104
105   bool ReadListFileAsString(const std::string& content,
106                             const std::string& virtualFileName);
107
108   bool ReadDependentFile(const std::string& filename,
109                          bool noPolicyScope = true);
110
111   /**
112    * Add a function blocker to this makefile
113    */
114   void AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb);
115
116   /// @return whether we are processing the top CMakeLists.txt file.
117   bool IsRootMakefile() const;
118
119   /**
120    * Remove the function blocker whose scope ends with the given command.
121    * This returns ownership of the function blocker object.
122    */
123   std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
124
125   /**
126    * Try running cmake and building a file. This is used for dynamically
127    * loaded commands, not as part of the usual build process.
128    */
129   int TryCompile(const std::string& srcdir, const std::string& bindir,
130                  const std::string& projectName, const std::string& targetName,
131                  bool fast, int jobs,
132                  const std::vector<std::string>* cmakeArgs,
133                  std::string& output);
134
135   bool GetIsSourceFileTryCompile() const;
136
137   /**
138    * Help enforce global target name uniqueness.
139    */
140   bool EnforceUniqueName(std::string const& name, std::string& msg,
141                          bool isCustom = false) const;
142
143   class GeneratorAction
144   {
145     using ActionT =
146       std::function<void(cmLocalGenerator&, const cmListFileBacktrace&)>;
147     using CCActionT =
148       std::function<void(cmLocalGenerator&, const cmListFileBacktrace&,
149                          std::unique_ptr<cmCustomCommand> cc)>;
150
151   public:
152     GeneratorAction(ActionT&& action)
153       : Action(std::move(action))
154     {
155     }
156
157     GeneratorAction(std::unique_ptr<cmCustomCommand> tcc, CCActionT&& action)
158       : CCAction(std::move(action))
159       , cc(std::move(tcc))
160     {
161     }
162
163     void operator()(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt);
164
165   private:
166     ActionT Action;
167
168     // FIXME: Use std::variant
169     CCActionT CCAction;
170     std::unique_ptr<cmCustomCommand> cc;
171   };
172
173   /**
174    * Register an action that is executed during Generate
175    */
176   void AddGeneratorAction(GeneratorAction&& action);
177
178   /// Helper to insert the constructor GeneratorAction(args...)
179   template <class... Args>
180   void AddGeneratorAction(Args&&... args)
181   {
182     AddGeneratorAction(GeneratorAction(std::move(args)...));
183   }
184
185   /**
186    * Perform generate actions, Library dependency analysis etc before output of
187    * the makefile.
188    */
189   void Generate(cmLocalGenerator& lg);
190
191   /**
192    * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
193    */
194   cmTarget* GetCustomCommandTarget(const std::string& target,
195                                    cmObjectLibraryCommands objLibCommands,
196                                    const cmListFileBacktrace& lfbt) const;
197
198   /**
199    * Dispatch adding a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a
200    * target.
201    */
202   cmTarget* AddCustomCommandToTarget(const std::string& target,
203                                      cmCustomCommandType type,
204                                      std::unique_ptr<cmCustomCommand> cc);
205
206   /**
207    * Called for each file with custom command.
208    */
209   using CommandSourceCallback = std::function<void(cmSourceFile*)>;
210
211   /**
212    * Dispatch adding a custom command to a source file.
213    */
214   void AddCustomCommandToOutput(
215     std::unique_ptr<cmCustomCommand> cc,
216     const CommandSourceCallback& callback = nullptr, bool replace = false);
217   void AddCustomCommandOldStyle(const std::string& target,
218                                 const std::vector<std::string>& outputs,
219                                 const std::vector<std::string>& depends,
220                                 const std::string& source,
221                                 const cmCustomCommandLines& commandLines,
222                                 const char* comment);
223   void AppendCustomCommandToOutput(
224     const std::string& output, const std::vector<std::string>& depends,
225     const cmImplicitDependsList& implicit_depends,
226     const cmCustomCommandLines& commandLines);
227
228   /**
229    * Add a define flag to the build.
230    */
231   void AddDefineFlag(std::string const& definition);
232   void RemoveDefineFlag(std::string const& definition);
233   void AddCompileDefinition(std::string const& definition);
234   void AddCompileOption(std::string const& option);
235   void AddLinkOption(std::string const& option);
236   void AddLinkDirectory(std::string const& directory, bool before = false);
237
238   /** Create a new imported target with the name and type given.  */
239   cmTarget* AddImportedTarget(const std::string& name,
240                               cmStateEnums::TargetType type, bool global);
241
242   std::pair<cmTarget&, bool> CreateNewTarget(
243     const std::string& name, cmStateEnums::TargetType type,
244     cmTarget::PerConfig perConfig = cmTarget::PerConfig::Yes);
245
246   cmTarget* AddNewTarget(cmStateEnums::TargetType type,
247                          const std::string& name);
248
249   /** Create a target instance for the utility.  */
250   cmTarget* AddNewUtilityTarget(const std::string& utilityName,
251                                 bool excludeFromAll);
252
253   /**
254    * Add an executable to the build.
255    */
256   cmTarget* AddExecutable(const std::string& exename,
257                           const std::vector<std::string>& srcs,
258                           bool excludeFromAll = false);
259
260   /**
261    * Dispatch adding a utility to the build.  A utility target is a command
262    * that is run every time the target is built.
263    */
264   cmTarget* AddUtilityCommand(const std::string& utilityName,
265                               bool excludeFromAll,
266                               std::unique_ptr<cmCustomCommand> cc);
267
268   /**
269    * Add a subdirectory to the build.
270    */
271   void AddSubDirectory(const std::string& fullSrcDir,
272                        const std::string& fullBinDir, bool excludeFromAll,
273                        bool immediate, bool system);
274
275   void Configure();
276
277   /**
278    * Configure a subdirectory
279    */
280   void ConfigureSubDirectory(cmMakefile* mf);
281
282   /**
283    * Add an include directory to the build.
284    */
285   void AddIncludeDirectories(const std::vector<std::string>& incs,
286                              bool before = false);
287
288   /**
289    * Add a variable definition to the build. This variable
290    * can be used in CMake to refer to lists, directories, etc.
291    */
292   void AddDefinition(const std::string& name, cm::string_view value);
293   void AddDefinition(const std::string& name, cmValue value)
294   {
295     this->AddDefinition(name, *value);
296   }
297   /**
298    * Add bool variable definition to the build.
299    */
300   void AddDefinitionBool(const std::string& name, bool);
301   //! Add a definition to this makefile and the global cmake cache.
302   void AddCacheDefinition(const std::string& name, const char* value,
303                           const char* doc, cmStateEnums::CacheEntryType type,
304                           bool force = false);
305   void AddCacheDefinition(const std::string& name, const std::string& value,
306                           const char* doc, cmStateEnums::CacheEntryType type,
307                           bool force = false)
308   {
309     this->AddCacheDefinition(name, value.c_str(), doc, type, force);
310   }
311
312   /**
313    * Remove a variable definition from the build.  This is not valid
314    * for cache entries, and will only affect the current makefile.
315    */
316   void RemoveDefinition(const std::string& name);
317   //! Remove a definition from the cache.
318   void RemoveCacheDefinition(const std::string& name) const;
319
320   /**
321    * Specify the name of the project for this build.
322    */
323   void SetProjectName(std::string const& name);
324
325   void InitCMAKE_CONFIGURATION_TYPES(std::string const& genDefault);
326
327   /* Get the default configuration */
328   std::string GetDefaultConfiguration() const;
329
330   enum GeneratorConfigQuery
331   {
332     IncludeEmptyConfig, // Include "" aka noconfig
333     ExcludeEmptyConfig, // Exclude "" aka noconfig
334     OnlyMultiConfig,
335   };
336
337   /** Get the configurations for dependency checking.  */
338   std::vector<std::string> GetGeneratorConfigs(
339     GeneratorConfigQuery mode) const;
340
341   /**
342    * Set the name of the library.
343    */
344   cmTarget* AddLibrary(const std::string& libname,
345                        cmStateEnums::TargetType type,
346                        const std::vector<std::string>& srcs,
347                        bool excludeFromAll = false);
348   void AddAlias(const std::string& libname, const std::string& tgt,
349                 bool globallyVisible = true);
350
351   //@{
352   /**
353    * Set, Push, Pop policy values for CMake.
354    */
355   bool SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
356   bool SetPolicy(const char* id, cmPolicies::PolicyStatus status);
357   cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id,
358                                            bool parent_scope = false) const;
359   bool SetPolicyVersion(std::string const& version_min,
360                         std::string const& version_max);
361   void RecordPolicies(cmPolicies::PolicyMap& pm) const;
362   //@}
363
364   /** Helper class to push and pop policies automatically.  */
365   class PolicyPushPop
366   {
367   public:
368     PolicyPushPop(cmMakefile* m);
369     ~PolicyPushPop();
370
371     PolicyPushPop(const PolicyPushPop&) = delete;
372     PolicyPushPop& operator=(const PolicyPushPop&) = delete;
373
374   private:
375     cmMakefile* Makefile;
376   };
377   friend class PolicyPushPop;
378
379   /** Helper class to push and pop variables scopes automatically. */
380   class VariablePushPop
381   {
382   public:
383     VariablePushPop(cmMakefile* m);
384     ~VariablePushPop();
385
386     VariablePushPop(VariablePushPop const&) = delete;
387     VariablePushPop& operator=(VariablePushPop const&) = delete;
388
389   private:
390     cmMakefile* Makefile;
391   };
392
393   /**
394    * Determine if the given context, name pair has already been reported
395    * in context of CMP0054.
396    */
397   bool HasCMP0054AlreadyBeenReported(const cmListFileContext& context) const;
398
399   bool IgnoreErrorsCMP0061() const;
400
401   std::string const& GetHomeDirectory() const;
402   std::string const& GetHomeOutputDirectory() const;
403
404   /**
405    * Set CMAKE_SCRIPT_MODE_FILE variable when running a -P script.
406    */
407   void SetScriptModeFile(std::string const& scriptfile);
408
409   /**
410    * Set CMAKE_ARGC, CMAKE_ARGV0 ... variables.
411    */
412   void SetArgcArgv(const std::vector<std::string>& args);
413
414   std::string const& GetCurrentSourceDirectory() const;
415   std::string const& GetCurrentBinaryDirectory() const;
416
417   //@}
418
419   /**
420    * Set a regular expression that include files must match
421    * in order to be considered as part of the depend information.
422    */
423   void SetIncludeRegularExpression(const std::string& regex)
424   {
425     this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex.c_str());
426   }
427   const std::string& GetIncludeRegularExpression() const
428   {
429     return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
430   }
431
432   /**
433    * Set a regular expression that include files that are not found
434    * must match in order to be considered a problem.
435    */
436   void SetComplainRegularExpression(const std::string& regex)
437   {
438     this->ComplainFileRegularExpression = regex;
439   }
440   const std::string& GetComplainRegularExpression() const
441   {
442     return this->ComplainFileRegularExpression;
443   }
444
445   // -- List of targets
446   using cmTargetMap = std::unordered_map<std::string, cmTarget>;
447   /** Get the target map */
448   cmTargetMap& GetTargets() { return this->Targets; }
449   /** Get the target map - const version */
450   cmTargetMap const& GetTargets() const { return this->Targets; }
451
452   const std::vector<std::unique_ptr<cmTarget>>& GetOwnedImportedTargets() const
453   {
454     return this->ImportedTargetsOwned;
455   }
456   std::vector<cmTarget*> GetImportedTargets() const;
457
458   cmTarget* FindLocalNonAliasTarget(const std::string& name) const;
459
460   /** Find a target to use in place of the given name.  The target
461       returned may be imported or built within the project.  */
462   cmTarget* FindTargetToUse(const std::string& name,
463                             bool excludeAliases = false) const;
464   bool IsAlias(const std::string& name) const;
465
466   std::map<std::string, std::string> GetAliasTargets() const
467   {
468     return this->AliasTargets;
469   }
470
471   /**
472    * Mark include directories as system directories.
473    */
474   void AddSystemIncludeDirectories(const std::set<std::string>& incs);
475
476   /** Get a cmSourceFile pointer for a given source name, if the name is
477    *  not found, then a null pointer is returned.
478    */
479   cmSourceFile* GetSource(
480     const std::string& sourceName,
481     cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous) const;
482
483   /** Create the source file and return it. generated
484    * indicates if it is a generated file, this is used in determining
485    * how to create the source file instance e.g. name
486    */
487   cmSourceFile* CreateSource(
488     const std::string& sourceName, bool generated = false,
489     cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
490
491   /** Get a cmSourceFile pointer for a given source name, if the name is
492    *  not found, then create the source file and return it. generated
493    * indicates if it is a generated file, this is used in determining
494    * how to create the source file instance e.g. name
495    */
496   cmSourceFile* GetOrCreateSource(
497     const std::string& sourceName, bool generated = false,
498     cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
499
500   /** Get a cmSourceFile pointer for a given source name and always mark the
501    * file as generated, if the name is not found, then create the source file
502    * and return it.
503    */
504   cmSourceFile* GetOrCreateGeneratedSource(const std::string& sourceName);
505
506   void AddTargetObject(std::string const& tgtName, std::string const& objFile);
507
508   /**
509    * Given a variable name, return its value (as a string).
510    * If the variable is not found in this makefile instance, the
511    * cache is then queried.
512    */
513   cmValue GetDefinition(const std::string&) const;
514   const std::string& GetSafeDefinition(const std::string&) const;
515   const std::string& GetRequiredDefinition(const std::string& name) const;
516   bool IsDefinitionSet(const std::string&) const;
517   bool IsNormalDefinitionSet(const std::string&) const;
518   bool GetDefExpandList(const std::string& name, std::vector<std::string>& out,
519                         bool emptyArgs = false) const;
520   /**
521    * Get the list of all variables in the current space. If argument
522    * cacheonly is specified and is greater than 0, then only cache
523    * variables will be listed.
524    */
525   std::vector<std::string> GetDefinitions() const;
526
527   /**
528    * Test a boolean variable to see if it is true or false.
529    * If the variable is not found in this makefile instance, the
530    * cache is then queried.
531    * Returns false if no entry defined.
532    */
533   bool IsOn(const std::string& name) const;
534   bool IsSet(const std::string& name) const;
535
536   /** Return whether the target platform is 32-bit. */
537   bool PlatformIs32Bit() const;
538
539   /** Return whether the target platform is 64-bit.  */
540   bool PlatformIs64Bit() const;
541   /** Return whether the target platform is x32.  */
542   bool PlatformIsx32() const;
543
544   /** Apple SDK Type */
545   enum class AppleSDK
546   {
547     MacOS,
548     IPhoneOS,
549     IPhoneSimulator,
550     AppleTVOS,
551     AppleTVSimulator,
552     WatchOS,
553     WatchSimulator,
554   };
555
556   /** What SDK type points CMAKE_OSX_SYSROOT to? */
557   AppleSDK GetAppleSDKType() const;
558
559   /** Return whether the target platform is Apple iOS.  */
560   bool PlatformIsAppleEmbedded() const;
561
562   /** Retrieve soname flag for the specified language if supported */
563   const char* GetSONameFlag(const std::string& language) const;
564
565   /**
566    * Get a list of preprocessor define flags.
567    */
568   std::string GetDefineFlags() const { return this->DefineFlags; }
569
570   /**
571    * Make sure CMake can write this file
572    */
573   bool CanIWriteThisFile(std::string const& fileName) const;
574
575 #if !defined(CMAKE_BOOTSTRAP)
576   /**
577    * Get the vector source groups.
578    */
579   const std::vector<cmSourceGroup>& GetSourceGroups() const
580   {
581     return this->SourceGroups;
582   }
583
584   /**
585    * Get the source group
586    */
587   cmSourceGroup* GetSourceGroup(const std::vector<std::string>& name) const;
588
589   /**
590    * Add a root source group for consideration when adding a new source.
591    */
592   void AddSourceGroup(const std::string& name, const char* regex = nullptr);
593
594   /**
595    * Add a source group for consideration when adding a new source.
596    * name is tokenized.
597    */
598   void AddSourceGroup(const std::vector<std::string>& name,
599                       const char* regex = nullptr);
600
601   /**
602    * Get and existing or create a new source group.
603    */
604   cmSourceGroup* GetOrCreateSourceGroup(
605     const std::vector<std::string>& folders);
606
607   /**
608    * Get and existing or create a new source group.
609    * The name will be tokenized.
610    */
611   cmSourceGroup* GetOrCreateSourceGroup(const std::string& name);
612
613   /**
614    * find what source group this source is in
615    */
616   cmSourceGroup* FindSourceGroup(const std::string& source,
617                                  std::vector<cmSourceGroup>& groups) const;
618 #endif
619
620   /**
621    * Get the vector of list files on which this makefile depends
622    */
623   const std::vector<std::string>& GetListFiles() const
624   {
625     return this->ListFiles;
626   }
627   //! When the file changes cmake will be re-run from the build system.
628   void AddCMakeDependFile(const std::string& file)
629   {
630     this->ListFiles.push_back(file);
631   }
632   void AddCMakeDependFilesFromUser();
633
634   std::string FormatListFileStack() const;
635
636   /**
637    * Get the current context backtrace.
638    */
639   cmListFileBacktrace GetBacktrace() const;
640
641   /**
642    * Get the vector of  files created by this makefile
643    */
644   const std::vector<std::string>& GetOutputFiles() const
645   {
646     return this->OutputFiles;
647   }
648   void AddCMakeOutputFile(const std::string& file)
649   {
650     this->OutputFiles.push_back(file);
651   }
652
653   /**
654    * Expand all defined variables in the string.
655    * Defined variables come from the this->Definitions map.
656    * They are expanded with ${var} where var is the
657    * entry in the this->Definitions map.  Also \@var\@ is
658    * expanded to match autoconf style expansions.
659    */
660   const std::string& ExpandVariablesInString(std::string& source) const;
661   const std::string& ExpandVariablesInString(
662     std::string& source, bool escapeQuotes, bool noEscapes,
663     bool atOnly = false, const char* filename = nullptr, long line = -1,
664     bool removeEmpty = false, bool replaceAt = false) const;
665
666   /**
667    * Remove any remaining variables in the string. Anything with ${var} or
668    * \@var\@ will be removed.
669    */
670   void RemoveVariablesInString(std::string& source, bool atOnly = false) const;
671
672   /**
673    * Expand variables in the makefiles ivars such as link directories etc
674    */
675   void ExpandVariablesCMP0019();
676
677   /**
678    * Replace variables and #cmakedefine lines in the given string.
679    * See cmConfigureFileCommand for details.
680    */
681   void ConfigureString(const std::string& input, std::string& output,
682                        bool atOnly, bool escapeQuotes) const;
683
684   /**
685    * Copy file but change lines according to ConfigureString
686    */
687   int ConfigureFile(const std::string& infile, const std::string& outfile,
688                     bool copyonly, bool atOnly, bool escapeQuotes,
689                     mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
690
691   enum class CommandMissingFromStack
692   {
693     No,
694     Yes,
695   };
696
697   /**
698    * Print a command's invocation
699    */
700   void PrintCommandTrace(
701     cmListFileFunction const& lff, cmListFileBacktrace const& bt,
702     CommandMissingFromStack missing = CommandMissingFromStack::No) const;
703
704   /**
705    * Set a callback that is invoked whenever ExecuteCommand is called.
706    */
707   void OnExecuteCommand(std::function<void()> callback);
708
709   /**
710    * Execute a single CMake command.  Returns true if the command
711    * succeeded or false if it failed.
712    */
713   bool ExecuteCommand(const cmListFileFunction& lff, cmExecutionStatus& status,
714                       cm::optional<std::string> deferId = {});
715
716   //! Enable support for named language, if nil then all languages are
717   /// enabled.
718   void EnableLanguage(std::vector<std::string> const& languages,
719                       bool optional);
720
721   cmState* GetState() const;
722
723 /**
724  * Get the variable watch. This is used to determine when certain variables
725  * are accessed.
726  */
727 #ifndef CMAKE_BOOTSTRAP
728   cmVariableWatch* GetVariableWatch() const;
729 #endif
730
731   //! Display progress or status message.
732   void DisplayStatus(const std::string&, float) const;
733
734   /**
735    * Expand the given list file arguments into the full set after
736    * variable replacement and list expansion.
737    */
738   bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
739                        std::vector<std::string>& outArgs) const;
740   bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
741                        std::vector<cmExpandedCommandArgument>& outArgs) const;
742
743   /**
744    * Get the instance
745    */
746   cmake* GetCMakeInstance() const;
747   cmMessenger* GetMessenger() const;
748   cmGlobalGenerator* GetGlobalGenerator() const;
749
750   /**
751    * Get all the source files this makefile knows about
752    */
753   const std::vector<std::unique_ptr<cmSourceFile>>& GetSourceFiles() const
754   {
755     return this->SourceFiles;
756   }
757
758   std::vector<cmTarget*> const& GetOrderedTargets() const
759   {
760     return this->OrderedTargets;
761   }
762
763   //! Add a new cmTest to the list of tests for this makefile.
764   cmTest* CreateTest(const std::string& testName);
765
766   /** Get a cmTest pointer for a given test name, if the name is
767    *  not found, then a null pointer is returned.
768    */
769   cmTest* GetTest(const std::string& testName) const;
770
771   /**
772    * Get all tests that run under the given configuration.
773    */
774   void GetTests(const std::string& config, std::vector<cmTest*>& tests) const;
775
776   /**
777    * Return a location of a file in cmake or custom modules directory
778    */
779   std::string GetModulesFile(const std::string& name) const
780   {
781     bool system;
782     std::string debugBuffer;
783     return this->GetModulesFile(name, system, false, debugBuffer);
784   }
785
786   /**
787    * Return a location of a file in cmake or custom modules directory
788    */
789   std::string GetModulesFile(const std::string& name, bool& system) const
790   {
791     std::string debugBuffer;
792     return this->GetModulesFile(name, system, false, debugBuffer);
793   }
794
795   std::string GetModulesFile(const std::string& name, bool& system, bool debug,
796                              std::string& debugBuffer) const;
797
798   //! Set/Get a property of this directory
799   void SetProperty(const std::string& prop, const char* value);
800   void SetProperty(const std::string& prop, cmValue value);
801   void SetProperty(const std::string& prop, const std::string& value)
802   {
803     this->SetProperty(prop, cmValue(value));
804   }
805   void AppendProperty(const std::string& prop, const std::string& value,
806                       bool asString = false);
807   cmValue GetProperty(const std::string& prop) const;
808   cmValue GetProperty(const std::string& prop, bool chain) const;
809   bool GetPropertyAsBool(const std::string& prop) const;
810   std::vector<std::string> GetPropertyKeys() const;
811
812   //! Initialize a makefile from its parent
813   void InitializeFromParent(cmMakefile* parent);
814
815   void AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g);
816
817   std::vector<std::unique_ptr<cmInstallGenerator>>& GetInstallGenerators()
818   {
819     return this->InstallGenerators;
820   }
821   const std::vector<std::unique_ptr<cmInstallGenerator>>&
822   GetInstallGenerators() const
823   {
824     return this->InstallGenerators;
825   }
826
827   void AddTestGenerator(std::unique_ptr<cmTestGenerator> g);
828
829   const std::vector<std::unique_ptr<cmTestGenerator>>& GetTestGenerators()
830     const
831   {
832     return this->TestGenerators;
833   }
834
835   class FunctionPushPop
836   {
837   public:
838     FunctionPushPop(cmMakefile* mf, std::string const& fileName,
839                     cmPolicies::PolicyMap const& pm);
840     ~FunctionPushPop();
841
842     FunctionPushPop(const FunctionPushPop&) = delete;
843     FunctionPushPop& operator=(const FunctionPushPop&) = delete;
844
845     void Quiet() { this->ReportError = false; }
846
847   private:
848     cmMakefile* Makefile;
849     bool ReportError = true;
850   };
851
852   class MacroPushPop
853   {
854   public:
855     MacroPushPop(cmMakefile* mf, std::string const& fileName,
856                  cmPolicies::PolicyMap const& pm);
857     ~MacroPushPop();
858
859     MacroPushPop(const MacroPushPop&) = delete;
860     MacroPushPop& operator=(const MacroPushPop&) = delete;
861
862     void Quiet() { this->ReportError = false; }
863
864   private:
865     cmMakefile* Makefile;
866     bool ReportError = true;
867   };
868
869   void PushFunctionScope(std::string const& fileName,
870                          cmPolicies::PolicyMap const& pm);
871   void PopFunctionScope(bool reportError);
872   void PushMacroScope(std::string const& fileName,
873                       cmPolicies::PolicyMap const& pm);
874   void PopMacroScope(bool reportError);
875   void PushScope();
876   void PopScope();
877   void RaiseScope(const std::string& var, const char* value);
878   void RaiseScope(const std::string& var, cmValue value)
879   {
880     this->RaiseScope(var, value.GetCStr());
881   }
882   void RaiseScope(const std::vector<std::string>& variables);
883
884   // push and pop loop scopes
885   void PushLoopBlockBarrier();
886   void PopLoopBlockBarrier();
887
888   bool IsImportedTargetGlobalScope() const;
889
890   enum class ImportedTargetScope
891   {
892     Local,
893     Global,
894   };
895
896   /** Helper class to manage whether imported packages
897    * should be globally scoped based off the find package command
898    */
899   class SetGlobalTargetImportScope
900   {
901   public:
902     SetGlobalTargetImportScope(cmMakefile* mk, ImportedTargetScope const scope)
903       : Makefile(mk)
904     {
905       if (scope == ImportedTargetScope::Global &&
906           !this->Makefile->IsImportedTargetGlobalScope()) {
907         this->Makefile->CurrentImportedTargetScope = scope;
908         this->Set = true;
909       } else {
910         this->Set = false;
911       }
912     }
913     ~SetGlobalTargetImportScope()
914     {
915       if (this->Set) {
916         this->Makefile->CurrentImportedTargetScope =
917           ImportedTargetScope::Local;
918       }
919     }
920
921   private:
922     cmMakefile* Makefile;
923     bool Set;
924   };
925
926   /** Helper class to push and pop scopes automatically.  */
927   class ScopePushPop
928   {
929   public:
930     ScopePushPop(cmMakefile* m)
931       : Makefile(m)
932     {
933       this->Makefile->PushScope();
934     }
935
936     ~ScopePushPop() { this->Makefile->PopScope(); }
937
938     ScopePushPop(ScopePushPop const&) = delete;
939     ScopePushPop& operator=(ScopePushPop const&) = delete;
940
941   private:
942     cmMakefile* Makefile;
943   };
944
945   void IssueMessage(MessageType t, std::string const& text) const;
946   Message::LogLevel GetCurrentLogLevel() const;
947
948   /** Set whether or not to report a CMP0000 violation.  */
949   void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
950
951   bool CheckCMP0037(std::string const& targetName,
952                     cmStateEnums::TargetType targetType) const;
953
954   cmBTStringRange GetIncludeDirectoriesEntries() const;
955   cmBTStringRange GetCompileOptionsEntries() const;
956   cmBTStringRange GetCompileDefinitionsEntries() const;
957   cmBTStringRange GetLinkOptionsEntries() const;
958   cmBTStringRange GetLinkDirectoriesEntries() const;
959
960   std::set<std::string> const& GetSystemIncludeDirectories() const
961   {
962     return this->SystemIncludeDirectories;
963   }
964
965   bool PolicyOptionalWarningEnabled(std::string const& var) const;
966
967   void PushLoopBlock();
968   void PopLoopBlock();
969   bool IsLoopBlock() const;
970
971   void ClearMatches();
972   void StoreMatches(cmsys::RegularExpression& re);
973
974   cmStateSnapshot GetStateSnapshot() const;
975
976   const char* GetDefineFlagsCMP0059() const;
977
978   void EnforceDirectoryLevelRules() const;
979
980   void AddEvaluationFile(
981     const std::string& inputFile, const std::string& targetName,
982     std::unique_ptr<cmCompiledGeneratorExpression> outputName,
983     std::unique_ptr<cmCompiledGeneratorExpression> condition,
984     const std::string& newLineCharacter, mode_t permissions,
985     bool inputIsContent);
986   const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
987   GetEvaluationFiles() const;
988
989   std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
990   GetExportBuildFileGenerators() const;
991   void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
992   void AddExportBuildFileGenerator(
993     std::unique_ptr<cmExportBuildFileGenerator> gen);
994
995   // Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
996   // searches
997   std::deque<std::vector<std::string>> FindPackageRootPathStack;
998
999   class DebugFindPkgRAII
1000   {
1001     cmMakefile* Makefile;
1002     bool OldValue;
1003
1004   public:
1005     DebugFindPkgRAII(cmMakefile* mf, std::string const& pkg);
1006     ~DebugFindPkgRAII();
1007   };
1008
1009   bool GetDebugFindPkgMode() const;
1010
1011   void MaybeWarnCMP0074(std::string const& pkg);
1012   void MaybeWarnUninitialized(std::string const& variable,
1013                               const char* sourceFilename) const;
1014   bool IsProjectFile(const char* filename) const;
1015
1016   int GetRecursionDepth() const;
1017   void SetRecursionDepth(int recursionDepth);
1018
1019   std::string NewDeferId() const;
1020   bool DeferCall(std::string id, std::string fileName, cmListFileFunction lff);
1021   bool DeferCancelCall(std::string const& id);
1022   cm::optional<std::string> DeferGetCallIds() const;
1023   cm::optional<std::string> DeferGetCall(std::string const& id) const;
1024
1025 protected:
1026   // add link libraries and directories to the target
1027   void AddGlobalLinkInformation(cmTarget& target);
1028
1029   mutable std::set<cmListFileContext> CMP0054ReportedIds;
1030
1031   // libraries, classes, and executables
1032   mutable cmTargetMap Targets;
1033   std::map<std::string, std::string> AliasTargets;
1034
1035   std::vector<cmTarget*> OrderedTargets;
1036
1037   std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
1038
1039   // Because cmSourceFile names are compared in a fuzzy way (see
1040   // cmSourceFileLocation::Match()) we can't have a straight mapping from
1041   // filename to cmSourceFile.  To make lookups more efficient we store the
1042   // Name portion of the cmSourceFileLocation and then compare on the list of
1043   // cmSourceFiles that might match that name.  Note that on platforms which
1044   // have a case-insensitive filesystem we store the key in all lowercase.
1045   using SourceFileMap =
1046     std::unordered_map<std::string, std::vector<cmSourceFile*>>;
1047   SourceFileMap SourceFileSearchIndex;
1048
1049   // For "Known" paths we can store a direct filename to cmSourceFile map
1050   std::unordered_map<std::string, cmSourceFile*> KnownFileSearchIndex;
1051
1052   // Tests
1053   std::map<std::string, std::unique_ptr<cmTest>> Tests;
1054
1055   // The set of include directories that are marked as system include
1056   // directories.
1057   std::set<std::string> SystemIncludeDirectories;
1058
1059   std::vector<std::string> ListFiles;
1060   std::vector<std::string> OutputFiles;
1061
1062   std::vector<std::unique_ptr<cmInstallGenerator>> InstallGenerators;
1063   std::vector<std::unique_ptr<cmTestGenerator>> TestGenerators;
1064
1065   std::string ComplainFileRegularExpression;
1066   std::string DefineFlags;
1067
1068   // Track the value of the computed DEFINITIONS property.
1069   std::string DefineFlagsOrig;
1070
1071 #if !defined(CMAKE_BOOTSTRAP)
1072   std::vector<cmSourceGroup> SourceGroups;
1073   size_t ObjectLibrariesSourceGroupIndex;
1074 #endif
1075
1076   cmGlobalGenerator* GlobalGenerator;
1077   bool IsFunctionBlocked(const cmListFileFunction& lff,
1078                          cmExecutionStatus& status);
1079
1080 private:
1081   cmStateSnapshot StateSnapshot;
1082   cmListFileBacktrace Backtrace;
1083   int RecursionDepth;
1084
1085   struct DeferCommand
1086   {
1087     // Id is empty for an already-executed or canceled operation.
1088     std::string Id;
1089     std::string FilePath;
1090     cmListFileFunction Command;
1091   };
1092   struct DeferCommands
1093   {
1094     std::vector<DeferCommand> Commands;
1095   };
1096   std::unique_ptr<DeferCommands> Defer;
1097   bool DeferRunning = false;
1098
1099   void DoGenerate(cmLocalGenerator& lg);
1100
1101   void RunListFile(cmListFile const& listFile,
1102                    const std::string& filenametoread,
1103                    DeferCommands* defer = nullptr);
1104
1105   bool ParseDefineFlag(std::string const& definition, bool remove);
1106
1107   bool EnforceUniqueDir(const std::string& srcPath,
1108                         const std::string& binPath) const;
1109
1110   std::function<void()> ExecuteCommandCallback;
1111   using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
1112   using FunctionBlockersType =
1113     std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
1114   FunctionBlockersType FunctionBlockers;
1115   std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
1116   void PushFunctionBlockerBarrier();
1117   void PopFunctionBlockerBarrier(bool reportError = true);
1118
1119   std::stack<int> LoopBlockCounter;
1120
1121   mutable cmsys::RegularExpression cmDefineRegex;
1122   mutable cmsys::RegularExpression cmDefine01Regex;
1123   mutable cmsys::RegularExpression cmAtVarRegex;
1124   mutable cmsys::RegularExpression cmNamedCurly;
1125
1126   std::vector<cmMakefile*> UnConfiguredDirectories;
1127   std::vector<std::unique_ptr<cmExportBuildFileGenerator>>
1128     ExportBuildFileGenerators;
1129
1130   std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>
1131     EvaluationFiles;
1132
1133   std::vector<cmExecutionStatus*> ExecutionStatusStack;
1134   friend class cmMakefileCall;
1135   friend class cmParseFileScope;
1136
1137   std::vector<std::unique_ptr<cmTarget>> ImportedTargetsOwned;
1138   using TargetMap = std::unordered_map<std::string, cmTarget*>;
1139   TargetMap ImportedTargets;
1140
1141   // Internal policy stack management.
1142   void PushPolicy(bool weak = false,
1143                   cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
1144   void PopPolicy();
1145   void PopSnapshot(bool reportError = true);
1146   friend bool cmCMakePolicyCommand(std::vector<std::string> const& args,
1147                                    cmExecutionStatus& status);
1148   class IncludeScope;
1149   friend class IncludeScope;
1150
1151   class ListFileScope;
1152   friend class ListFileScope;
1153
1154   class DeferScope;
1155   friend class DeferScope;
1156
1157   class DeferCallScope;
1158   friend class DeferCallScope;
1159
1160   class BuildsystemFileScope;
1161   friend class BuildsystemFileScope;
1162
1163   // CMP0053 == old
1164   MessageType ExpandVariablesInStringOld(std::string& errorstr,
1165                                          std::string& source,
1166                                          bool escapeQuotes, bool noEscapes,
1167                                          bool atOnly, const char* filename,
1168                                          long line, bool removeEmpty,
1169                                          bool replaceAt) const;
1170   // CMP0053 == new
1171   MessageType ExpandVariablesInStringNew(std::string& errorstr,
1172                                          std::string& source,
1173                                          bool escapeQuotes, bool noEscapes,
1174                                          bool atOnly, const char* filename,
1175                                          long line, bool replaceAt) const;
1176
1177   bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
1178
1179   void CreateGeneratedOutputs(const std::vector<std::string>& outputs);
1180
1181   std::vector<BT<GeneratorAction>> GeneratorActions;
1182   bool GeneratorActionsInvoked = false;
1183
1184   bool DebugFindPkg = false;
1185
1186   bool CheckSystemVars;
1187   bool CheckCMP0000;
1188   std::set<std::string> WarnedCMP0074;
1189   bool IsSourceFileTryCompile;
1190   mutable bool SuppressSideEffects;
1191   ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;
1192 };