/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <cstddef>
#include <iosfwd>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>

#include "cmBuildOptions.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmExportSet.h"
#include "cmLocalGenerator.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
#include "cmValue.h"

#if !defined(CMAKE_BOOTSTRAP)
#  include <cm3p/json/value.h>

#  include "cmFileLockPool.h"
#endif

#define CMAKE_DIRECTORY_ID_SEP "::@"

enum class cmDepfileFormat;
enum class codecvt_Encoding;

class cmDirectoryId;
class cmExportBuildFileGenerator;
class cmExternalMakefileProjectGenerator;
class cmGeneratorTarget;
class cmInstallRuntimeDependencySet;
class cmLinkLineComputer;
class cmMakefile;
class cmOutputConverter;
class cmQtAutoGenGlobalInitializer;
class cmSourceFile;
class cmState;
class cmStateDirectory;
class cmake;

namespace detail {
inline void AppendStrs(std::vector<std::string>&)
{
}
template <typename T, typename... Ts>
inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts)
{
  command.emplace_back(std::forward<T>(s));
  AppendStrs(command, std::forward<Ts>(ts)...);
}

struct GeneratedMakeCommand
{
  // Add each argument as a separate element to the vector
  template <typename... T>
  void Add(T&&... args)
  {
    // iterate the args and append each one
    AppendStrs(this->PrimaryCommand, std::forward<T>(args)...);
  }

  // Add each value in the iterators as a separate element to the vector
  void Add(std::vector<std::string>::const_iterator start,
           std::vector<std::string>::const_iterator end)
  {
    cm::append(this->PrimaryCommand, start, end);
  }

  std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); }
  std::string QuotedPrintable() const;

  std::vector<std::string> PrimaryCommand;
  bool RequiresOutputForward = false;
};
}
namespace Json {
class StreamWriter;
}

/** \class cmGlobalGenerator
 * \brief Responsible for overseeing the generation process for the entire tree
 *
 * Subclasses of this class generate makefiles for various
 * platforms.
 */
class cmGlobalGenerator
{
public:
  using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;

  //! Free any memory allocated with the GlobalGenerator
  cmGlobalGenerator(cmake* cm);
  virtual ~cmGlobalGenerator();

  virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
    cmMakefile* mf);

  //! Get the name for this generator
  virtual std::string GetName() const { return "Generic"; }

  /** Check whether the given name matches the current generator.  */
  virtual bool MatchesGeneratorName(const std::string& name) const
  {
    return this->GetName() == name;
  }

  /** Get encoding used by generator for makefile files */
  virtual codecvt_Encoding GetMakefileEncoding() const;

#if !defined(CMAKE_BOOTSTRAP)
  /** Get a JSON object describing the generator.  */
  virtual Json::Value GetJson() const;
#endif

  /** Tell the generator about the target system.  */
  virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; }

  /** Set the generator-specific instance.  Returns true if supported.  */
  virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf);

  /** Set the generator-specific platform name.  Returns true if platform
      is supported and false otherwise.  */
  virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);

  /** Set the generator-specific toolset name.  Returns true if toolset
      is supported and false otherwise.  */
  virtual bool SetGeneratorToolset(std::string const& ts, bool build,
                                   cmMakefile* mf);

  /** Read any other cache entries needed for cmake --build. */
  virtual bool ReadCacheEntriesForBuild(const cmState& /*state*/)
  {
    return true;
  }

  /**
   * Create LocalGenerators and process the CMakeLists files. This does not
   * actually produce any makefiles, DSPs, etc.
   */
  virtual void Configure();

  virtual bool InspectConfigTypeVariables() { return true; }

  enum class CxxModuleSupportQuery
  {
    // Support is expected at the call site.
    Expected,
    // The call site is querying for support and handles problems by itself.
    Inspect,
  };
  virtual bool CheckCxxModuleSupport(CxxModuleSupportQuery /*query*/)
  {
    return false;
  }

  virtual bool SupportsBuildDatabase() const { return false; }
  bool AddBuildDatabaseTargets();
  void AddBuildDatabaseFile(std::string const& lang, std::string const& config,
                            std::string const& path);

  virtual bool IsGNUMakeJobServerAware() const { return false; }

  bool Compute();
  virtual void AddExtraIDETargets() {}

  enum TargetTypes
  {
    AllTargets,
    ImportedOnly
  };

  void CreateImportedGenerationObjects(
    cmMakefile* mf, std::vector<std::string> const& targets,
    std::vector<cmGeneratorTarget const*>& exports);
  void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);

  /**
   * Generate the all required files for building this project/tree. This
   * basically creates a series of LocalGenerators for each directory and
   * requests that they Generate.
   */
  virtual void Generate();

  virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
    cmOutputConverter* outputConverter,
    cmStateDirectory const& stateDir) const;

  std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer(
    cmOutputConverter* outputConverter,
    cmStateDirectory const& stateDir) const;

  /**
   * Set/Get and Clear the enabled languages.
   */
  void SetLanguageEnabled(const std::string&, cmMakefile* mf);
  bool GetLanguageEnabled(const std::string&) const;
  void ClearEnabledLanguages();
  void GetEnabledLanguages(std::vector<std::string>& lang) const;
  /**
   * Try to determine system information such as shared library
   * extension, pthreads, byte order etc.
   */
  virtual void EnableLanguage(std::vector<std::string> const& languages,
                              cmMakefile*, bool optional);

  /**
   * Resolve the CMAKE_<lang>_COMPILER setting for the given language.
   * Intended to be called from EnableLanguage.
   */
  void ResolveLanguageCompiler(const std::string& lang, cmMakefile* mf,
                               bool optional) const;

  /**
   * Try to determine system information, get it from another generator
   */
  void EnableLanguagesFromGenerator(cmGlobalGenerator* gen, cmMakefile* mf);

  /**
   * Try running cmake and building a file. This is used for dynamically
   * loaded commands, not as part of the usual build process.
   */
  int TryCompile(int jobs, const std::string& srcdir,
                 const std::string& bindir, const std::string& projectName,
                 const std::string& targetName, bool fast, std::string& output,
                 cmMakefile* mf);

  /**
   * Build a file given the following information. This is a more direct call
   * that is used by both CTest and TryCompile. If target name is NULL or
   * empty then all is assumed. clean indicates if a "make clean" should be
   * done first.
   */
  int Build(
    int jobs, const std::string& srcdir, const std::string& bindir,
    const std::string& projectName,
    std::vector<std::string> const& targetNames, std::ostream& ostr,
    const std::string& makeProgram, const std::string& config,
    const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout,
    cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE,
    std::vector<std::string> const& nativeOptions =
      std::vector<std::string>());

  /**
   * Open a generated IDE project given the following information.
   */
  virtual bool Open(const std::string& bindir, const std::string& projectName,
                    bool dryRun);

  struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand
  {
  };

  virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand(
    const std::string& makeProgram, const std::string& projectName,
    const std::string& projectDir, std::vector<std::string> const& targetNames,
    const std::string& config, int jobs, bool verbose,
    const cmBuildOptions& buildOptions = cmBuildOptions(),
    std::vector<std::string> const& makeOptions = std::vector<std::string>());

  virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const;

  /**
   * Generate a "cmake --build" call for a given target, config and parallel
   * level.
   */
  std::string GenerateCMakeBuildCommand(const std::string& target,
                                        const std::string& config,
                                        const std::string& parallel,
                                        const std::string& native,
                                        bool ignoreErrors);

  //! Get the CMake instance
  cmake* GetCMakeInstance() const { return this->CMakeInstance; }

  void SetConfiguredFilesPath(cmGlobalGenerator* gen);
  const std::vector<std::unique_ptr<cmMakefile>>& GetMakefiles() const
  {
    return this->Makefiles;
  }
  const LocalGeneratorVector& GetLocalGenerators() const
  {
    return this->LocalGenerators;
  }

  std::vector<cmGeneratorTarget*> GetLocalGeneratorTargetsInOrder(
    cmLocalGenerator* lg) const;

  cmMakefile* GetCurrentMakefile() const
  {
    return this->CurrentConfigureMakefile;
  }

  void SetCurrentMakefile(cmMakefile* mf)
  {
    this->CurrentConfigureMakefile = mf;
  }

  void AddMakefile(std::unique_ptr<cmMakefile> mf);

  //! Set an generator for an "external makefile based project"
  void SetExternalMakefileProjectGenerator(
    std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator);

  std::string GetExtraGeneratorName() const;

  void AddInstallComponent(const std::string& component);

  /** Mark the (absolute path to a) file as generated.  */
  void MarkAsGeneratedFile(const std::string& filepath);
  /** Determine if the absolute filepath belongs to a generated file.  */
  bool IsGeneratedFile(const std::string& filepath);

  const std::set<std::string>* GetInstallComponents() const
  {
    return &this->InstallComponents;
  }

  cmExportSetMap& GetExportSets() { return this->ExportSets; }

  cmValue GetGlobalSetting(std::string const& name) const;
  bool GlobalSettingIsOn(std::string const& name) const;
  std::string GetSafeGlobalSetting(std::string const& name) const;

  /** Add a file to the manifest of generated targets for a configuration.  */
  void AddToManifest(std::string const& f);

  void EnableInstallTarget();

  cmDuration TryCompileTimeout;

  bool GetForceUnixPaths() const { return this->ForceUnixPaths; }
  bool GetToolSupportsColor() const { return this->ToolSupportsColor; }

  //! return the language for the given extension
  std::string GetLanguageFromExtension(const char* ext) const;
  //! is an extension to be ignored
  bool IgnoreFile(const char* ext) const;
  //! What is the preference for linkers and this language (None or Preferred)
  int GetLinkerPreference(const std::string& lang) const;
  //! What is the object file extension for a given source file?
  std::string GetLanguageOutputExtension(cmSourceFile const&) const;
  //! What is the object file extension for a given language?
  std::string GetLanguageOutputExtension(std::string const& lang) const;

  //! What is the configurations directory variable called?
  virtual const char* GetCMakeCFGIntDir() const { return "."; }

  //! expand CFGIntDir for a configuration
  virtual std::string ExpandCFGIntDir(const std::string& str,
                                      const std::string& config) const;

  /** Get whether the generator should use a script for link commands.  */
  bool GetUseLinkScript() const { return this->UseLinkScript; }

  /** Get whether the generator should produce special marks on rules
      producing symbolic (non-file) outputs.  */
  bool GetNeedSymbolicMark() const { return this->NeedSymbolicMark; }

  /*
   * Determine what program to use for building the project.
   */
  virtual bool FindMakeProgram(cmMakefile*);

  //! Find a target by name by searching the local generators.
  cmTarget* FindTarget(const std::string& name,
                       bool excludeAliases = false) const;

  cmGeneratorTarget* FindGeneratorTarget(const std::string& name) const;

  void AddAlias(const std::string& name, const std::string& tgtName);
  bool IsAlias(const std::string& name) const;

  /** Determine if a name resolves to a framework on disk or a built target
      that is a framework. */
  bool NameResolvesToFramework(const std::string& libname) const;
  /** Split a framework path to the directory and name of the framework as well
   * as optional suffix.
   * Returns std::nullopt if the path does not match with framework format
   * when extendedFormat is true, required format is relaxed (i.e. extension
   * `.framework' is optional). Used when FRAMEWORK link feature is
   * specified */
  struct FrameworkDescriptor
  {
    FrameworkDescriptor(std::string directory, std::string name)
      : Directory(std::move(directory))
      , Name(std::move(name))
    {
    }
    FrameworkDescriptor(std::string directory, std::string version,
                        std::string name)
      : Directory(std::move(directory))
      , Version(std::move(version))
      , Name(std::move(name))
    {
    }
    FrameworkDescriptor(std::string directory, std::string version,
                        std::string name, std::string suffix)
      : Directory(std::move(directory))
      , Version(std::move(version))
      , Name(std::move(name))
      , Suffix(std::move(suffix))
    {
    }
    std::string GetLinkName() const
    {
      return this->Suffix.empty() ? this->Name
                                  : cmStrCat(this->Name, ',', this->Suffix);
    }
    std::string GetFullName() const
    {
      return cmStrCat(this->Name, ".framework/"_s, this->Name, this->Suffix);
    }
    std::string GetVersionedName() const
    {
      return this->Version.empty()
        ? this->GetFullName()
        : cmStrCat(this->Name, ".framework/Versions/"_s, this->Version, '/',
                   this->Name, this->Suffix);
    }
    std::string GetFrameworkPath() const
    {
      return this->Directory.empty()
        ? cmStrCat(this->Name, ".framework"_s)
        : cmStrCat(this->Directory, '/', this->Name, ".framework"_s);
    }
    std::string GetFullPath() const
    {
      return this->Directory.empty()
        ? this->GetFullName()
        : cmStrCat(this->Directory, '/', this->GetFullName());
    }
    std::string GetVersionedPath() const
    {
      return this->Directory.empty()
        ? this->GetVersionedName()
        : cmStrCat(this->Directory, '/', this->GetVersionedName());
    }

    const std::string Directory;
    const std::string Version;
    const std::string Name;
    const std::string Suffix;
  };
  enum class FrameworkFormat
  {
    Strict,
    Relaxed,
    Extended
  };
  cm::optional<FrameworkDescriptor> SplitFrameworkPath(
    const std::string& path,
    FrameworkFormat format = FrameworkFormat::Relaxed) const;

  cmMakefile* FindMakefile(const std::string& start_dir) const;
  cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const;

  /** Append the subdirectory for the given configuration.  If anything is
      appended the given prefix and suffix will be appended around it, which
      is useful for leading or trailing slashes.  */
  virtual void AppendDirectoryForConfig(const std::string& prefix,
                                        const std::string& config,
                                        const std::string& suffix,
                                        std::string& dir);

  /** Get the content of a directory.  Directory listings are cached
      and re-loaded from disk only when modified.  During the generation
      step the content will include the target files to be built even if
      they do not yet exist.  */
  std::set<std::string> const& GetDirectoryContent(std::string const& dir,
                                                   bool needDisk = true);

  void IndexTarget(cmTarget* t);
  void IndexGeneratorTarget(cmGeneratorTarget* gt);

  // Index the target using a name that is unique to that target
  // even if other targets have the same name.
  std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt);

  static bool IsReservedTarget(std::string const& name);

  virtual const char* GetAllTargetName() const { return "ALL_BUILD"; }
  virtual const char* GetInstallTargetName() const { return "INSTALL"; }
  virtual const char* GetInstallLocalTargetName() const { return nullptr; }
  virtual const char* GetInstallStripTargetName() const { return nullptr; }
  virtual const char* GetPreinstallTargetName() const { return nullptr; }
  virtual const char* GetTestTargetName() const { return "RUN_TESTS"; }
  virtual const char* GetPackageTargetName() const { return "PACKAGE"; }
  virtual const char* GetPackageSourceTargetName() const { return nullptr; }
  virtual const char* GetEditCacheTargetName() const { return nullptr; }
  virtual const char* GetRebuildCacheTargetName() const { return nullptr; }
  virtual const char* GetCleanTargetName() const { return nullptr; }

  // Lookup edit_cache target command preferred by this generator.
  virtual std::string GetEditCacheCommand() const { return ""; }

  // Default config to use for cmake --build
  virtual std::string GetDefaultBuildConfig() const { return "Debug"; }

  // Class to track a set of dependencies.
  using TargetDependSet = cmTargetDependSet;

  // what targets does the specified target depend on directly
  // via a target_link_libraries or add_dependencies
  TargetDependSet const& GetTargetDirectDepends(
    const cmGeneratorTarget* target);

  // Return true if target 'l' occurs before 'r' in a global ordering
  // of targets that respects inter-target dependencies.
  bool TargetOrderIndexLess(cmGeneratorTarget const* l,
                            cmGeneratorTarget const* r) const;

  const std::map<std::string, std::vector<cmLocalGenerator*>>& GetProjectMap()
    const
  {
    return this->ProjectMap;
  }

  // track files replaced during a Generate
  void FileReplacedDuringGenerate(const std::string& filename);
  void GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames);

  void AddRuleHash(const std::vector<std::string>& outputs,
                   std::string const& content);

  /** Return whether the given binary directory is unused.  */
  bool BinaryDirectoryIsNew(const std::string& dir)
  {
    return this->BinaryDirectories.insert(dir).second;
  }

  /** Return true if the generated build tree may contain multiple builds.
      i.e. "Can I build Debug and Release in the same tree?" */
  virtual bool IsMultiConfig() const { return false; }

  virtual bool IsXcode() const { return false; }

  virtual bool IsVisualStudio() const { return false; }

  virtual bool IsVisualStudioAtLeast10() const { return false; }

  virtual bool IsNinja() const { return false; }

  /** Return true if we know the exact location of object files for the given
     cmTarget. If false, store the reason in the given string. This is
     meaningful only after EnableLanguage has been called.  */
  virtual bool HasKnownObjectFileLocation(cmTarget const&, std::string*) const
  {
    return true;
  }

  virtual bool UseFolderProperty() const;

  virtual bool IsIPOSupported() const { return false; }

  /** Return whether the generator can import external visual studio project
      using INCLUDE_EXTERNAL_MSPROJECT */
  virtual bool IsIncludeExternalMSProjectSupported() const { return false; }

  /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is
      relevant for mixed macOS and iOS builds. */
  virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }

  /** Return whether the "Resources" folder prefix should be stripped from
      MacFolder. */
  virtual bool ShouldStripResourcePath(cmMakefile*) const;

  virtual bool SupportsCustomCommandDepfile() const { return false; }
  virtual cm::optional<cmDepfileFormat> DepfileFormat() const
  {
    return cm::nullopt;
  }

  virtual bool SupportsLinkerDependencyFile() const { return false; }

  std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;

  /** Generate an <output>.rule file path for a given command output.  */
  virtual std::string GenerateRuleFile(std::string const& output) const;

  virtual bool SupportsDefaultBuildType() const { return false; }
  virtual bool SupportsCrossConfigs() const { return false; }
  virtual bool SupportsDefaultConfigs() const { return false; }

  virtual std::string ConvertToOutputPath(std::string path) const
  {
    return path;
  }
  virtual std::string GetConfigDirectory(std::string const& config) const
  {
    if (!this->IsMultiConfig() || config.empty()) {
      return {};
    }
    return cmStrCat('/', config);
  }

  static std::string EscapeJSON(const std::string& s);

  void ProcessEvaluationFiles();

  std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
  {
    return this->BuildExportSets;
  }
  void AddBuildExportSet(cmExportBuildFileGenerator* gen);
  void AddBuildExportExportSet(cmExportBuildFileGenerator* gen);
  bool IsExportedTargetsFile(const std::string& filename) const;
  bool GenerateImportFile(const std::string& file);
  cmExportBuildFileGenerator* GetExportedTargetsFile(
    const std::string& filename) const;
  void AddCMP0042WarnTarget(const std::string& target);
  void AddCMP0068WarnTarget(const std::string& target);

  virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;

  bool GenerateCPackPropertiesFile();

  void SetFilenameTargetDepends(
    cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts);
  const std::set<const cmGeneratorTarget*>& GetFilenameTargetDepends(
    cmSourceFile* sf) const;

#if !defined(CMAKE_BOOTSTRAP)
  cmFileLockPool& GetFileLockPool() { return this->FileLockPool; }
#endif

  bool GetConfigureDoneCMP0026() const
  {
    return this->ConfigureDoneCMP0026AndCMP0024;
  }

  std::string MakeSilentFlag;

  size_t RecursionDepth = 0;

  virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
  {
    configs.emplace_back("$<CONFIG>");
  }

  std::string const& GetRealPath(std::string const& dir);

  std::string NewDeferId();

  cmInstallRuntimeDependencySet* CreateAnonymousRuntimeDependencySet();

  cmInstallRuntimeDependencySet* GetNamedRuntimeDependencySet(
    const std::string& name);

  enum class StripCommandStyle
  {
    Default,
    Apple,
  };
  StripCommandStyle GetStripCommandStyle(std::string const& strip);

  virtual std::string& EncodeLiteral(std::string& lit) { return lit; }

  bool CheckCMP0171() const;

  void AddInstallScript(std::string const& file);

protected:
  // for a project collect all its targets by following depend
  // information, and also collect all the targets
  void GetTargetSets(TargetDependSet& projectTargets,
                     TargetDependSet& originalTargets, cmLocalGenerator* root,
                     std::vector<cmLocalGenerator*>& generators);
  bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
  void AddTargetDepends(const cmGeneratorTarget* target,
                        TargetDependSet& projectTargets);
  void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf);
  void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf);
  void FillExtensionToLanguageMap(const std::string& l, cmMakefile* mf);
  virtual bool CheckLanguages(std::vector<std::string> const& languages,
                              cmMakefile* mf) const;
  virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
                                   cmValue envVar) const;

  virtual bool ComputeTargetDepends();

#if !defined(CMAKE_BOOTSTRAP)
  void WriteJsonContent(const std::string& fname,
                        const Json::Value& value) const;
  void WriteInstallJson() const;
#endif

  virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;

  bool ApplyCXXStdTargets();
  bool DiscoverSyntheticTargets();

  bool AddHeaderSetVerification();

  void CreateFileGenerateOutputs();
  bool AddAutomaticSources();

  std::string SelectMakeProgram(const std::string& makeProgram,
                                const std::string& makeDefault = "") const;

  // Fill the ProjectMap, this must be called after LocalGenerators
  // has been populated.
  void FillProjectMap();
  void CheckTargetProperties();
  bool IsExcluded(cmStateSnapshot const& root,
                  cmStateSnapshot const& snp) const;
  bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
  bool IsExcluded(cmLocalGenerator* root,
                  const cmGeneratorTarget* target) const;
  virtual void InitializeProgressMarks() {}

  struct GlobalTargetInfo
  {
    std::string Name;
    std::string Message;
    cmCustomCommandLines CommandLines;
    std::vector<std::string> Depends;
    std::string WorkingDir;
    bool UsesTerminal = false;
    cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
    bool StdPipesUTF8 = false;
  };

  void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);

  void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
  void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
  void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
  void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const;
  void AddGlobalTarget_RebuildCache(
    std::vector<GlobalTargetInfo>& targets) const;
  void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
  void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);

  void ReserveGlobalTargetCodegen();

  std::string FindMakeProgramFile;
  std::string ConfiguredFilesPath;
  cmake* CMakeInstance;
  std::vector<std::unique_ptr<cmMakefile>> Makefiles;
  LocalGeneratorVector LocalGenerators;

#ifndef CMAKE_BOOTSTRAP
  std::unique_ptr<cmQtAutoGenGlobalInitializer> QtAutoGen;
#endif

  cmMakefile* CurrentConfigureMakefile;
  // map from project name to vector of local generators in that project
  std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;

  // Set of named installation components requested by the project.
  std::set<std::string> InstallComponents;
  // Sets of named target exports
  cmExportSetMap ExportSets;
  std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
  std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;

  std::map<std::string, std::string> AliasTargets;

  cmTarget* FindTargetImpl(std::string const& name) const;

  cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;

  std::string GetPredefinedTargetsFolder() const;

private:
  using TargetMap = std::unordered_map<std::string, cmTarget*>;
  using GeneratorTargetMap =
    std::unordered_map<std::string, cmGeneratorTarget*>;
  using MakefileMap = std::unordered_map<std::string, cmMakefile*>;
  using LocalGeneratorMap = std::unordered_map<std::string, cmLocalGenerator*>;
  // Map efficiently from target name to cmTarget instance.
  // Do not use this structure for looping over all targets.
  // It contains both normal and globally visible imported targets.
  TargetMap TargetSearchIndex;
  GeneratorTargetMap GeneratorTargetSearchIndex;

  // Map efficiently from source directory path to cmMakefile instance.
  // Do not use this structure for looping over all directories.
  // It may not contain all of them (see note in IndexMakefile method).
  MakefileMap MakefileSearchIndex;

  // Map efficiently from source directory path to cmLocalGenerator instance.
  // Do not use this structure for looping over all directories.
  // Its order is not deterministic.
  LocalGeneratorMap LocalGeneratorSearchIndex;

  void ComputeTargetOrder();
  void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index);
  std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;

  cmMakefile* TryCompileOuterMakefile;
  // If you add a new map here, make sure it is copied
  // in EnableLanguagesFromGenerator
  std::map<std::string, bool> IgnoreExtensions;
  std::set<std::string> LanguagesReady; // Ready for try_compile
  std::set<std::string> LanguagesInProgress;
  std::map<std::string, std::string> OutputExtensions;
  std::map<std::string, std::string> LanguageToOutputExtension;
  std::map<std::string, std::string> ExtensionToLanguage;
  std::map<std::string, int> LanguageToLinkerPreference;
  std::map<std::string, std::string> LanguageToOriginalSharedLibFlags;

#if !defined(CMAKE_BOOTSTRAP)
  std::unique_ptr<Json::StreamWriter> JsonWriter;
#endif

#ifdef __APPLE__
  std::map<std::string, StripCommandStyle> StripCommandStyleMap;
#endif

  // Deferral id generation.
  size_t NextDeferId = 0;

  // Record hashes for rules and outputs.
  struct RuleHash
  {
    char Data[32];
  };
  std::map<std::string, RuleHash> RuleHashes;
  void CheckRuleHashes();
  void CheckRuleHashes(std::string const& pfile, std::string const& home);
  void WriteRuleHashes(std::string const& pfile);

  void WriteSummary();
  void WriteSummary(cmGeneratorTarget* target);
  void FinalizeTargetConfiguration();

  virtual void ForceLinkerLanguages();

  void CheckTargetLinkLibraries() const;
  bool CheckTargetsForMissingSources() const;
  bool CheckTargetsForType() const;
  bool CheckTargetsForPchCompilePdb() const;

  void CreateLocalGenerators();

  void CheckCompilerIdCompatibility(cmMakefile* mf,
                                    std::string const& lang) const;

  void ComputeBuildFileGenerators();

  std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator;

  // track files replaced during a Generate
  std::vector<std::string> FilesReplacedDuringGenerate;

  // Store computed inter-target dependencies.
  using TargetDependMap = std::map<cmGeneratorTarget const*, TargetDependSet>;
  TargetDependMap TargetDependencies;

  friend class cmake;
  void CreateGeneratorTargets(
    TargetTypes targetTypes, cmMakefile* mf, cmLocalGenerator* lg,
    std::map<cmTarget*, cmGeneratorTarget*> const& importedMap);
  void CreateGeneratorTargets(TargetTypes targetTypes);

  void ClearGeneratorMembers();

  bool CheckCMP0037(std::string const& targetName,
                    std::string const& reason) const;
  bool CheckCMP0037Prefix(std::string const& targetPrefix,
                          std::string const& reason) const;

  void IndexMakefile(cmMakefile* mf);
  void IndexLocalGenerator(cmLocalGenerator* lg);

  virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }

  bool UnsupportedVariableIsDefined(const std::string& name,
                                    bool supported) const;

  // Cache directory content and target files to be built.
  struct DirectoryContent
  {
    long LastDiskTime = -1;
    std::set<std::string> All;
    std::set<std::string> Generated;
  };
  std::map<std::string, DirectoryContent> DirectoryContentMap;

  // Set of binary directories on disk.
  std::set<std::string> BinaryDirectories;

  // track targets to issue CMP0042 warning for.
  std::set<std::string> CMP0042WarnTargets;
  // track targets to issue CMP0068 warning for.
  std::set<std::string> CMP0068WarnTargets;

  mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
    FilenameTargetDepends;

  std::map<std::string, std::string> RealPaths;

  std::unordered_set<std::string> GeneratedFiles;

  std::vector<std::unique_ptr<cmInstallRuntimeDependencySet>>
    RuntimeDependencySets;
  std::map<std::string, cmInstallRuntimeDependencySet*>
    RuntimeDependencySetsByName;

  std::vector<std::string> InstallScripts;

#if !defined(CMAKE_BOOTSTRAP)
  // Pool of file locks
  cmFileLockPool FileLockPool;
#endif

  using PerLanguageModuleDatabases =
    std::map<std::string, std::vector<std::string>>;
  using PerConfigModuleDatabases =
    std::map<std::string, PerLanguageModuleDatabases>;
  PerConfigModuleDatabases PerConfigModuleDbs;
  PerLanguageModuleDatabases PerLanguageModuleDbs;

protected:
  float FirstTimeProgress;
  bool NeedSymbolicMark;
  bool UseLinkScript;
  bool ForceUnixPaths;
  bool ToolSupportsColor;
  bool InstallTargetEnabled;
  bool ConfigureDoneCMP0026AndCMP0024;
  bool AllowGlobalTargetCodegen;
};
