27838b29e1506b23e9842e1d7eddde415a080fb2
[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);
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   /**
380    * Determine if the given context, name pair has already been reported
381    * in context of CMP0054.
382    */
383   bool HasCMP0054AlreadyBeenReported(const cmListFileContext& context) const;
384
385   bool IgnoreErrorsCMP0061() const;
386
387   std::string const& GetHomeDirectory() const;
388   std::string const& GetHomeOutputDirectory() const;
389
390   /**
391    * Set CMAKE_SCRIPT_MODE_FILE variable when running a -P script.
392    */
393   void SetScriptModeFile(std::string const& scriptfile);
394
395   /**
396    * Set CMAKE_ARGC, CMAKE_ARGV0 ... variables.
397    */
398   void SetArgcArgv(const std::vector<std::string>& args);
399
400   std::string const& GetCurrentSourceDirectory() const;
401   std::string const& GetCurrentBinaryDirectory() const;
402
403   //@}
404
405   /**
406    * Set a regular expression that include files must match
407    * in order to be considered as part of the depend information.
408    */
409   void SetIncludeRegularExpression(const std::string& regex)
410   {
411     this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex.c_str());
412   }
413   const std::string& GetIncludeRegularExpression() const
414   {
415     return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
416   }
417
418   /**
419    * Set a regular expression that include files that are not found
420    * must match in order to be considered a problem.
421    */
422   void SetComplainRegularExpression(const std::string& regex)
423   {
424     this->ComplainFileRegularExpression = regex;
425   }
426   const std::string& GetComplainRegularExpression() const
427   {
428     return this->ComplainFileRegularExpression;
429   }
430
431   // -- List of targets
432   using cmTargetMap = std::unordered_map<std::string, cmTarget>;
433   /** Get the target map */
434   cmTargetMap& GetTargets() { return this->Targets; }
435   /** Get the target map - const version */
436   cmTargetMap const& GetTargets() const { return this->Targets; }
437
438   const std::vector<std::unique_ptr<cmTarget>>& GetOwnedImportedTargets() const
439   {
440     return this->ImportedTargetsOwned;
441   }
442   std::vector<cmTarget*> GetImportedTargets() const;
443
444   cmTarget* FindLocalNonAliasTarget(const std::string& name) const;
445
446   /** Find a target to use in place of the given name.  The target
447       returned may be imported or built within the project.  */
448   cmTarget* FindTargetToUse(const std::string& name,
449                             bool excludeAliases = false) const;
450   bool IsAlias(const std::string& name) const;
451
452   std::map<std::string, std::string> GetAliasTargets() const
453   {
454     return this->AliasTargets;
455   }
456
457   /**
458    * Mark include directories as system directories.
459    */
460   void AddSystemIncludeDirectories(const std::set<std::string>& incs);
461
462   /** Get a cmSourceFile pointer for a given source name, if the name is
463    *  not found, then a null pointer is returned.
464    */
465   cmSourceFile* GetSource(
466     const std::string& sourceName,
467     cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous) const;
468
469   /** Create the source file and return it. generated
470    * indicates if it is a generated file, this is used in determining
471    * how to create the source file instance e.g. name
472    */
473   cmSourceFile* CreateSource(
474     const std::string& sourceName, bool generated = false,
475     cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
476
477   /** Get a cmSourceFile pointer for a given source name, if the name is
478    *  not found, then create the source file and return it. generated
479    * indicates if it is a generated file, this is used in determining
480    * how to create the source file instance e.g. name
481    */
482   cmSourceFile* GetOrCreateSource(
483     const std::string& sourceName, bool generated = false,
484     cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
485
486   /** Get a cmSourceFile pointer for a given source name and always mark the
487    * file as generated, if the name is not found, then create the source file
488    * and return it.
489    */
490   cmSourceFile* GetOrCreateGeneratedSource(const std::string& sourceName);
491
492   void AddTargetObject(std::string const& tgtName, std::string const& objFile);
493
494   /**
495    * Given a variable name, return its value (as a string).
496    * If the variable is not found in this makefile instance, the
497    * cache is then queried.
498    */
499   cmValue GetDefinition(const std::string&) const;
500   const std::string& GetSafeDefinition(const std::string&) const;
501   const std::string& GetRequiredDefinition(const std::string& name) const;
502   bool IsDefinitionSet(const std::string&) const;
503   bool IsNormalDefinitionSet(const std::string&) const;
504   bool GetDefExpandList(const std::string& name, std::vector<std::string>& out,
505                         bool emptyArgs = false) const;
506   /**
507    * Get the list of all variables in the current space. If argument
508    * cacheonly is specified and is greater than 0, then only cache
509    * variables will be listed.
510    */
511   std::vector<std::string> GetDefinitions() const;
512
513   /**
514    * Test a boolean variable to see if it is true or false.
515    * If the variable is not found in this makefile instance, the
516    * cache is then queried.
517    * Returns false if no entry defined.
518    */
519   bool IsOn(const std::string& name) const;
520   bool IsSet(const std::string& name) const;
521
522   /** Return whether the target platform is 32-bit. */
523   bool PlatformIs32Bit() const;
524
525   /** Return whether the target platform is 64-bit.  */
526   bool PlatformIs64Bit() const;
527   /** Return whether the target platform is x32.  */
528   bool PlatformIsx32() const;
529
530   /** Apple SDK Type */
531   enum class AppleSDK
532   {
533     MacOS,
534     IPhoneOS,
535     IPhoneSimulator,
536     AppleTVOS,
537     AppleTVSimulator,
538     WatchOS,
539     WatchSimulator,
540   };
541
542   /** What SDK type points CMAKE_OSX_SYSROOT to? */
543   AppleSDK GetAppleSDKType() const;
544
545   /** Return whether the target platform is Apple iOS.  */
546   bool PlatformIsAppleEmbedded() const;
547
548   /** Retrieve soname flag for the specified language if supported */
549   const char* GetSONameFlag(const std::string& language) const;
550
551   /**
552    * Get a list of preprocessor define flags.
553    */
554   std::string GetDefineFlags() const { return this->DefineFlags; }
555
556   /**
557    * Make sure CMake can write this file
558    */
559   bool CanIWriteThisFile(std::string const& fileName) const;
560
561 #if !defined(CMAKE_BOOTSTRAP)
562   /**
563    * Get the vector source groups.
564    */
565   const std::vector<cmSourceGroup>& GetSourceGroups() const
566   {
567     return this->SourceGroups;
568   }
569
570   /**
571    * Get the source group
572    */
573   cmSourceGroup* GetSourceGroup(const std::vector<std::string>& name) const;
574
575   /**
576    * Add a root source group for consideration when adding a new source.
577    */
578   void AddSourceGroup(const std::string& name, const char* regex = nullptr);
579
580   /**
581    * Add a source group for consideration when adding a new source.
582    * name is tokenized.
583    */
584   void AddSourceGroup(const std::vector<std::string>& name,
585                       const char* regex = nullptr);
586
587   /**
588    * Get and existing or create a new source group.
589    */
590   cmSourceGroup* GetOrCreateSourceGroup(
591     const std::vector<std::string>& folders);
592
593   /**
594    * Get and existing or create a new source group.
595    * The name will be tokenized.
596    */
597   cmSourceGroup* GetOrCreateSourceGroup(const std::string& name);
598
599   /**
600    * find what source group this source is in
601    */
602   cmSourceGroup* FindSourceGroup(const std::string& source,
603                                  std::vector<cmSourceGroup>& groups) const;
604 #endif
605
606   /**
607    * Get the vector of list files on which this makefile depends
608    */
609   const std::vector<std::string>& GetListFiles() const
610   {
611     return this->ListFiles;
612   }
613   //! When the file changes cmake will be re-run from the build system.
614   void AddCMakeDependFile(const std::string& file)
615   {
616     this->ListFiles.push_back(file);
617   }
618   void AddCMakeDependFilesFromUser();
619
620   std::string FormatListFileStack() const;
621
622   /**
623    * Get the current context backtrace.
624    */
625   cmListFileBacktrace GetBacktrace() const;
626
627   /**
628    * Get the vector of  files created by this makefile
629    */
630   const std::vector<std::string>& GetOutputFiles() const
631   {
632     return this->OutputFiles;
633   }
634   void AddCMakeOutputFile(const std::string& file)
635   {
636     this->OutputFiles.push_back(file);
637   }
638
639   /**
640    * Expand all defined variables in the string.
641    * Defined variables come from the this->Definitions map.
642    * They are expanded with ${var} where var is the
643    * entry in the this->Definitions map.  Also \@var\@ is
644    * expanded to match autoconf style expansions.
645    */
646   const std::string& ExpandVariablesInString(std::string& source) const;
647   const std::string& ExpandVariablesInString(
648     std::string& source, bool escapeQuotes, bool noEscapes,
649     bool atOnly = false, const char* filename = nullptr, long line = -1,
650     bool removeEmpty = false, bool replaceAt = false) const;
651
652   /**
653    * Remove any remaining variables in the string. Anything with ${var} or
654    * \@var\@ will be removed.
655    */
656   void RemoveVariablesInString(std::string& source, bool atOnly = false) const;
657
658   /**
659    * Expand variables in the makefiles ivars such as link directories etc
660    */
661   void ExpandVariablesCMP0019();
662
663   /**
664    * Replace variables and #cmakedefine lines in the given string.
665    * See cmConfigureFileCommand for details.
666    */
667   void ConfigureString(const std::string& input, std::string& output,
668                        bool atOnly, bool escapeQuotes) const;
669
670   /**
671    * Copy file but change lines according to ConfigureString
672    */
673   int ConfigureFile(const std::string& infile, const std::string& outfile,
674                     bool copyonly, bool atOnly, bool escapeQuotes,
675                     mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
676
677   enum class CommandMissingFromStack
678   {
679     No,
680     Yes,
681   };
682
683   /**
684    * Print a command's invocation
685    */
686   void PrintCommandTrace(
687     cmListFileFunction const& lff, cmListFileBacktrace const& bt,
688     CommandMissingFromStack missing = CommandMissingFromStack::No) const;
689
690   /**
691    * Set a callback that is invoked whenever ExecuteCommand is called.
692    */
693   void OnExecuteCommand(std::function<void()> callback);
694
695   /**
696    * Execute a single CMake command.  Returns true if the command
697    * succeeded or false if it failed.
698    */
699   bool ExecuteCommand(const cmListFileFunction& lff, cmExecutionStatus& status,
700                       cm::optional<std::string> deferId = {});
701
702   //! Enable support for named language, if nil then all languages are
703   /// enabled.
704   void EnableLanguage(std::vector<std::string> const& languages,
705                       bool optional);
706
707   cmState* GetState() const;
708
709 /**
710  * Get the variable watch. This is used to determine when certain variables
711  * are accessed.
712  */
713 #ifndef CMAKE_BOOTSTRAP
714   cmVariableWatch* GetVariableWatch() const;
715 #endif
716
717   //! Display progress or status message.
718   void DisplayStatus(const std::string&, float) const;
719
720   /**
721    * Expand the given list file arguments into the full set after
722    * variable replacement and list expansion.
723    */
724   bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
725                        std::vector<std::string>& outArgs) const;
726   bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
727                        std::vector<cmExpandedCommandArgument>& outArgs) const;
728
729   /**
730    * Get the instance
731    */
732   cmake* GetCMakeInstance() const;
733   cmMessenger* GetMessenger() const;
734   cmGlobalGenerator* GetGlobalGenerator() const;
735
736   /**
737    * Get all the source files this makefile knows about
738    */
739   const std::vector<std::unique_ptr<cmSourceFile>>& GetSourceFiles() const
740   {
741     return this->SourceFiles;
742   }
743
744   std::vector<cmTarget*> const& GetOrderedTargets() const
745   {
746     return this->OrderedTargets;
747   }
748
749   //! Add a new cmTest to the list of tests for this makefile.
750   cmTest* CreateTest(const std::string& testName);
751
752   /** Get a cmTest pointer for a given test name, if the name is
753    *  not found, then a null pointer is returned.
754    */
755   cmTest* GetTest(const std::string& testName) const;
756
757   /**
758    * Get all tests that run under the given configuration.
759    */
760   void GetTests(const std::string& config, std::vector<cmTest*>& tests) const;
761
762   /**
763    * Return a location of a file in cmake or custom modules directory
764    */
765   std::string GetModulesFile(const std::string& name) const
766   {
767     bool system;
768     std::string debugBuffer;
769     return this->GetModulesFile(name, system, false, debugBuffer);
770   }
771
772   /**
773    * Return a location of a file in cmake or custom modules directory
774    */
775   std::string GetModulesFile(const std::string& name, bool& system) const
776   {
777     std::string debugBuffer;
778     return this->GetModulesFile(name, system, false, debugBuffer);
779   }
780
781   std::string GetModulesFile(const std::string& name, bool& system, bool debug,
782                              std::string& debugBuffer) const;
783
784   //! Set/Get a property of this directory
785   void SetProperty(const std::string& prop, const char* value);
786   void SetProperty(const std::string& prop, cmValue value);
787   void SetProperty(const std::string& prop, const std::string& value)
788   {
789     this->SetProperty(prop, cmValue(value));
790   }
791   void AppendProperty(const std::string& prop, const std::string& value,
792                       bool asString = false);
793   cmValue GetProperty(const std::string& prop) const;
794   cmValue GetProperty(const std::string& prop, bool chain) const;
795   bool GetPropertyAsBool(const std::string& prop) const;
796   std::vector<std::string> GetPropertyKeys() const;
797
798   //! Initialize a makefile from its parent
799   void InitializeFromParent(cmMakefile* parent);
800
801   void AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g);
802
803   std::vector<std::unique_ptr<cmInstallGenerator>>& GetInstallGenerators()
804   {
805     return this->InstallGenerators;
806   }
807   const std::vector<std::unique_ptr<cmInstallGenerator>>&
808   GetInstallGenerators() const
809   {
810     return this->InstallGenerators;
811   }
812
813   void AddTestGenerator(std::unique_ptr<cmTestGenerator> g);
814
815   const std::vector<std::unique_ptr<cmTestGenerator>>& GetTestGenerators()
816     const
817   {
818     return this->TestGenerators;
819   }
820
821   class FunctionPushPop
822   {
823   public:
824     FunctionPushPop(cmMakefile* mf, std::string const& fileName,
825                     cmPolicies::PolicyMap const& pm);
826     ~FunctionPushPop();
827
828     FunctionPushPop(const FunctionPushPop&) = delete;
829     FunctionPushPop& operator=(const FunctionPushPop&) = delete;
830
831     void Quiet() { this->ReportError = false; }
832
833   private:
834     cmMakefile* Makefile;
835     bool ReportError = true;
836   };
837
838   class MacroPushPop
839   {
840   public:
841     MacroPushPop(cmMakefile* mf, std::string const& fileName,
842                  cmPolicies::PolicyMap const& pm);
843     ~MacroPushPop();
844
845     MacroPushPop(const MacroPushPop&) = delete;
846     MacroPushPop& operator=(const MacroPushPop&) = delete;
847
848     void Quiet() { this->ReportError = false; }
849
850   private:
851     cmMakefile* Makefile;
852     bool ReportError = true;
853   };
854
855   void PushFunctionScope(std::string const& fileName,
856                          cmPolicies::PolicyMap const& pm);
857   void PopFunctionScope(bool reportError);
858   void PushMacroScope(std::string const& fileName,
859                       cmPolicies::PolicyMap const& pm);
860   void PopMacroScope(bool reportError);
861   void PushScope();
862   void PopScope();
863   void RaiseScope(const std::string& var, const char* value);
864
865   // push and pop loop scopes
866   void PushLoopBlockBarrier();
867   void PopLoopBlockBarrier();
868
869   bool IsImportedTargetGlobalScope() const;
870
871   enum class ImportedTargetScope
872   {
873     Local,
874     Global,
875   };
876
877   /** Helper class to manage whether imported packages
878    * should be globally scoped based off the find package command
879    */
880   class SetGlobalTargetImportScope
881   {
882   public:
883     SetGlobalTargetImportScope(cmMakefile* mk, ImportedTargetScope const scope)
884       : Makefile(mk)
885     {
886       if (scope == ImportedTargetScope::Global &&
887           !this->Makefile->IsImportedTargetGlobalScope()) {
888         this->Makefile->CurrentImportedTargetScope = scope;
889         this->Set = true;
890       } else {
891         this->Set = false;
892       }
893     }
894     ~SetGlobalTargetImportScope()
895     {
896       if (this->Set) {
897         this->Makefile->CurrentImportedTargetScope =
898           ImportedTargetScope::Local;
899       }
900     }
901
902   private:
903     cmMakefile* Makefile;
904     bool Set;
905   };
906
907   /** Helper class to push and pop scopes automatically.  */
908   class ScopePushPop
909   {
910   public:
911     ScopePushPop(cmMakefile* m)
912       : Makefile(m)
913     {
914       this->Makefile->PushScope();
915     }
916
917     ~ScopePushPop() { this->Makefile->PopScope(); }
918
919     ScopePushPop(ScopePushPop const&) = delete;
920     ScopePushPop& operator=(ScopePushPop const&) = delete;
921
922   private:
923     cmMakefile* Makefile;
924   };
925
926   void IssueMessage(MessageType t, std::string const& text) const;
927
928   /** Set whether or not to report a CMP0000 violation.  */
929   void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
930
931   bool CheckCMP0037(std::string const& targetName,
932                     cmStateEnums::TargetType targetType) const;
933
934   cmBTStringRange GetIncludeDirectoriesEntries() const;
935   cmBTStringRange GetCompileOptionsEntries() const;
936   cmBTStringRange GetCompileDefinitionsEntries() const;
937   cmBTStringRange GetLinkOptionsEntries() const;
938   cmBTStringRange GetLinkDirectoriesEntries() const;
939
940   std::set<std::string> const& GetSystemIncludeDirectories() const
941   {
942     return this->SystemIncludeDirectories;
943   }
944
945   bool PolicyOptionalWarningEnabled(std::string const& var) const;
946
947   void PushLoopBlock();
948   void PopLoopBlock();
949   bool IsLoopBlock() const;
950
951   void ClearMatches();
952   void StoreMatches(cmsys::RegularExpression& re);
953
954   cmStateSnapshot GetStateSnapshot() const;
955
956   const char* GetDefineFlagsCMP0059() const;
957
958   void EnforceDirectoryLevelRules() const;
959
960   void AddEvaluationFile(
961     const std::string& inputFile, const std::string& targetName,
962     std::unique_ptr<cmCompiledGeneratorExpression> outputName,
963     std::unique_ptr<cmCompiledGeneratorExpression> condition,
964     const std::string& newLineCharacter, mode_t permissions,
965     bool inputIsContent);
966   const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
967   GetEvaluationFiles() const;
968
969   std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
970   GetExportBuildFileGenerators() const;
971   void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
972   void AddExportBuildFileGenerator(
973     std::unique_ptr<cmExportBuildFileGenerator> gen);
974
975   // Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
976   // searches
977   std::deque<std::vector<std::string>> FindPackageRootPathStack;
978
979   class DebugFindPkgRAII
980   {
981     cmMakefile* Makefile;
982     bool OldValue;
983
984   public:
985     DebugFindPkgRAII(cmMakefile* mf, std::string const& pkg);
986     ~DebugFindPkgRAII();
987   };
988
989   bool GetDebugFindPkgMode() const;
990
991   void MaybeWarnCMP0074(std::string const& pkg);
992   void MaybeWarnUninitialized(std::string const& variable,
993                               const char* sourceFilename) const;
994   bool IsProjectFile(const char* filename) const;
995
996   int GetRecursionDepth() const;
997   void SetRecursionDepth(int recursionDepth);
998
999   std::string NewDeferId() const;
1000   bool DeferCall(std::string id, std::string fileName, cmListFileFunction lff);
1001   bool DeferCancelCall(std::string const& id);
1002   cm::optional<std::string> DeferGetCallIds() const;
1003   cm::optional<std::string> DeferGetCall(std::string const& id) const;
1004
1005 protected:
1006   // add link libraries and directories to the target
1007   void AddGlobalLinkInformation(cmTarget& target);
1008
1009   mutable std::set<cmListFileContext> CMP0054ReportedIds;
1010
1011   // libraries, classes, and executables
1012   mutable cmTargetMap Targets;
1013   std::map<std::string, std::string> AliasTargets;
1014
1015   std::vector<cmTarget*> OrderedTargets;
1016
1017   std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
1018
1019   // Because cmSourceFile names are compared in a fuzzy way (see
1020   // cmSourceFileLocation::Match()) we can't have a straight mapping from
1021   // filename to cmSourceFile.  To make lookups more efficient we store the
1022   // Name portion of the cmSourceFileLocation and then compare on the list of
1023   // cmSourceFiles that might match that name.  Note that on platforms which
1024   // have a case-insensitive filesystem we store the key in all lowercase.
1025   using SourceFileMap =
1026     std::unordered_map<std::string, std::vector<cmSourceFile*>>;
1027   SourceFileMap SourceFileSearchIndex;
1028
1029   // For "Known" paths we can store a direct filename to cmSourceFile map
1030   std::unordered_map<std::string, cmSourceFile*> KnownFileSearchIndex;
1031
1032   // Tests
1033   std::map<std::string, std::unique_ptr<cmTest>> Tests;
1034
1035   // The set of include directories that are marked as system include
1036   // directories.
1037   std::set<std::string> SystemIncludeDirectories;
1038
1039   std::vector<std::string> ListFiles;
1040   std::vector<std::string> OutputFiles;
1041
1042   std::vector<std::unique_ptr<cmInstallGenerator>> InstallGenerators;
1043   std::vector<std::unique_ptr<cmTestGenerator>> TestGenerators;
1044
1045   std::string ComplainFileRegularExpression;
1046   std::string DefineFlags;
1047
1048   // Track the value of the computed DEFINITIONS property.
1049   std::string DefineFlagsOrig;
1050
1051 #if !defined(CMAKE_BOOTSTRAP)
1052   std::vector<cmSourceGroup> SourceGroups;
1053   size_t ObjectLibrariesSourceGroupIndex;
1054 #endif
1055
1056   cmGlobalGenerator* GlobalGenerator;
1057   bool IsFunctionBlocked(const cmListFileFunction& lff,
1058                          cmExecutionStatus& status);
1059
1060 private:
1061   cmStateSnapshot StateSnapshot;
1062   cmListFileBacktrace Backtrace;
1063   int RecursionDepth;
1064
1065   struct DeferCommand
1066   {
1067     // Id is empty for an already-executed or canceled operation.
1068     std::string Id;
1069     std::string FilePath;
1070     cmListFileFunction Command;
1071   };
1072   struct DeferCommands
1073   {
1074     std::vector<DeferCommand> Commands;
1075   };
1076   std::unique_ptr<DeferCommands> Defer;
1077   bool DeferRunning = false;
1078
1079   void DoGenerate(cmLocalGenerator& lg);
1080
1081   void RunListFile(cmListFile const& listFile,
1082                    const std::string& filenametoread,
1083                    DeferCommands* defer = nullptr);
1084
1085   bool ParseDefineFlag(std::string const& definition, bool remove);
1086
1087   bool EnforceUniqueDir(const std::string& srcPath,
1088                         const std::string& binPath) const;
1089
1090   std::function<void()> ExecuteCommandCallback;
1091   using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
1092   using FunctionBlockersType =
1093     std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
1094   FunctionBlockersType FunctionBlockers;
1095   std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
1096   void PushFunctionBlockerBarrier();
1097   void PopFunctionBlockerBarrier(bool reportError = true);
1098
1099   std::stack<int> LoopBlockCounter;
1100
1101   mutable cmsys::RegularExpression cmDefineRegex;
1102   mutable cmsys::RegularExpression cmDefine01Regex;
1103   mutable cmsys::RegularExpression cmAtVarRegex;
1104   mutable cmsys::RegularExpression cmNamedCurly;
1105
1106   std::vector<cmMakefile*> UnConfiguredDirectories;
1107   std::vector<std::unique_ptr<cmExportBuildFileGenerator>>
1108     ExportBuildFileGenerators;
1109
1110   std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>
1111     EvaluationFiles;
1112
1113   std::vector<cmExecutionStatus*> ExecutionStatusStack;
1114   friend class cmMakefileCall;
1115   friend class cmParseFileScope;
1116
1117   std::vector<std::unique_ptr<cmTarget>> ImportedTargetsOwned;
1118   using TargetMap = std::unordered_map<std::string, cmTarget*>;
1119   TargetMap ImportedTargets;
1120
1121   // Internal policy stack management.
1122   void PushPolicy(bool weak = false,
1123                   cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
1124   void PopPolicy();
1125   void PopSnapshot(bool reportError = true);
1126   friend bool cmCMakePolicyCommand(std::vector<std::string> const& args,
1127                                    cmExecutionStatus& status);
1128   class IncludeScope;
1129   friend class IncludeScope;
1130
1131   class ListFileScope;
1132   friend class ListFileScope;
1133
1134   class DeferScope;
1135   friend class DeferScope;
1136
1137   class DeferCallScope;
1138   friend class DeferCallScope;
1139
1140   class BuildsystemFileScope;
1141   friend class BuildsystemFileScope;
1142
1143   // CMP0053 == old
1144   MessageType ExpandVariablesInStringOld(std::string& errorstr,
1145                                          std::string& source,
1146                                          bool escapeQuotes, bool noEscapes,
1147                                          bool atOnly, const char* filename,
1148                                          long line, bool removeEmpty,
1149                                          bool replaceAt) const;
1150   // CMP0053 == new
1151   MessageType ExpandVariablesInStringNew(std::string& errorstr,
1152                                          std::string& source,
1153                                          bool escapeQuotes, bool noEscapes,
1154                                          bool atOnly, const char* filename,
1155                                          long line, bool replaceAt) const;
1156
1157   bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
1158
1159   void CreateGeneratedOutputs(const std::vector<std::string>& outputs);
1160
1161   std::vector<BT<GeneratorAction>> GeneratorActions;
1162   bool GeneratorActionsInvoked = false;
1163
1164   bool DebugFindPkg = false;
1165
1166   bool CheckSystemVars;
1167   bool CheckCMP0000;
1168   std::set<std::string> WarnedCMP0074;
1169   bool IsSourceFileTryCompile;
1170   mutable bool SuppressSideEffects;
1171   ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;
1172 };