cmGlobalGenerator.h 24.3 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
Ken Martin's avatar
Ken Martin committed
3 4 5
#ifndef cmGlobalGenerator_h
#define cmGlobalGenerator_h

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

8 9 10 11
#include <iosfwd>
#include <map>
#include <set>
#include <string>
12
#include <unordered_map>
13 14 15 16
#include <utility>
#include <vector>

#include "cmCustomCommandLines.h"
17
#include "cmDuration.h"
18
#include "cmExportSetMap.h"
19
#include "cmStateSnapshot.h"
20 21 22
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
23
#include "cm_codecvt.hxx"
24

25
#if defined(CMAKE_BUILD_WITH_CMAKE)
26
#  include "cmFileLockPool.h"
27
#  include "cm_jsoncpp_value.h"
28 29
#endif

30 31 32
#define CMAKE_DIRECTORY_ID_SEP "::@"

class cmDirectoryId;
33 34
class cmExportBuildFileGenerator;
class cmExternalMakefileProjectGenerator;
35
class cmGeneratorTarget;
36
class cmLinkLineComputer;
37
class cmLocalGenerator;
38
class cmMakefile;
39
class cmOutputConverter;
40 41
class cmSourceFile;
class cmStateDirectory;
42
class cmake;
Ken Martin's avatar
Ken Martin committed
43

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
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(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)
  {
    PrimaryCommand.insert(PrimaryCommand.end(), start, end);
  }

  std::string printable() const
  {
    std::size_t size = PrimaryCommand.size();
    for (auto&& i : PrimaryCommand) {
      size += i.size();
    }
    std::string buffer;
    buffer.reserve(size);
    for (auto&& i : PrimaryCommand) {
      buffer.append(i);
      buffer.append(1, ' ');
    }
    return buffer;
  }

  std::vector<std::string> PrimaryCommand;
  bool RequiresOutputForward = false;
};
}

Ken Martin's avatar
Ken Martin committed
92
/** \class cmGlobalGenerator
93
 * \brief Responsible for overseeing the generation process for the entire tree
Ken Martin's avatar
Ken Martin committed
94 95 96 97 98 99 100 101
 *
 * Subclasses of this class generate makefiles for various
 * platforms.
 */
class cmGlobalGenerator
{
public:
  ///! Free any memory allocated with the GlobalGenerator
102
  cmGlobalGenerator(cmake* cm);
Ken Martin's avatar
Ken Martin committed
103
  virtual ~cmGlobalGenerator();
104

105
  virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
Ken Martin's avatar
Ken Martin committed
106 107

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

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

116 117 118 119 120 121
  /** Get encoding used by generator for makefile files */
  virtual codecvt::Encoding GetMakefileEncoding() const
  {
    return codecvt::None;
  }

122 123 124 125 126
#if defined(CMAKE_BUILD_WITH_CMAKE)
  /** Get a JSON object describing the generator.  */
  virtual Json::Value GetJson() const;
#endif

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

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

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

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

Ken Martin's avatar
Ken Martin committed
141 142
  /**
   * Create LocalGenerators and process the CMakeLists files. This does not
143
   * actually produce any makefiles, DSPs, etc.
Ken Martin's avatar
Ken Martin committed
144 145 146
   */
  virtual void Configure();

147
  bool Compute();
148
  virtual void AddExtraIDETargets() {}
149

150 151
  enum TargetTypes
  {
152 153 154 155
    AllTargets,
    ImportedOnly
  };

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

Ken Martin's avatar
Ken Martin committed
161 162 163
  /**
   * Generate the all required files for building this project/tree. This
   * basically creates a series of LocalGenerators for each directory and
164
   * requests that they Generate.
Ken Martin's avatar
Ken Martin committed
165
   */
166
  virtual void Generate();
Ken Martin's avatar
Ken Martin committed
167

168
  virtual cmLinkLineComputer* CreateLinkLineComputer(
169 170
    cmOutputConverter* outputConverter,
    cmStateDirectory const& stateDir) const;
171 172

  cmLinkLineComputer* CreateMSVC60LinkLineComputer(
173 174
    cmOutputConverter* outputConverter,
    cmStateDirectory const& stateDir) const;
175

Ken Martin's avatar
Ken Martin committed
176
  /**
177
   * Set/Get and Clear the enabled languages.
Ken Martin's avatar
Ken Martin committed
178
   */
179 180
  void SetLanguageEnabled(const std::string&, cmMakefile* mf);
  bool GetLanguageEnabled(const std::string&) const;
Ken Martin's avatar
Ken Martin committed
181
  void ClearEnabledLanguages();
182
  void GetEnabledLanguages(std::vector<std::string>& lang) const;
Ken Martin's avatar
Ken Martin committed
183
  /**
184
   * Try to determine system information such as shared library
185
   * extension, pthreads, byte order etc.
Ken Martin's avatar
Ken Martin committed
186
   */
187 188
  virtual void EnableLanguage(std::vector<std::string> const& languages,
                              cmMakefile*, bool optional);
Ken Martin's avatar
Ken Martin committed
189

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

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

Ken Martin's avatar
Ken Martin committed
202
  /**
Nicolas Despres's avatar
Nicolas Despres committed
203
   * Try running cmake and building a file. This is used for dynamically
Ken Martin's avatar
Ken Martin committed
204 205
   * loaded commands, not as part of the usual build process.
   */
206 207 208 209
  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);
210

211 212 213 214 215 216
  /**
   * 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.
   */
217 218 219 220 221 222 223 224 225
  int Build(
    int jobs, const std::string& srcdir, const std::string& bindir,
    const std::string& projectName, const std::string& targetName,
    std::string& output, const std::string& makeProgram,
    const std::string& config, bool clean, bool fast, bool verbose,
    cmDuration timeout,
    cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE,
    std::vector<std::string> const& nativeOptions =
      std::vector<std::string>());
226

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

233 234 235 236
  struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand
  {
  };

237
  virtual void GenerateBuildCommand(
238
    GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
239
    const std::string& projectName, const std::string& projectDir,
240
    const std::string& targetName, const std::string& config, bool fast,
241
    int jobs, bool verbose,
242
    std::vector<std::string> const& makeOptions = std::vector<std::string>());
243

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

246
  /** Generate a "cmake --build" call for a given target and config.  */
247
  std::string GenerateCMakeBuildCommand(const std::string& target,
248
                                        const std::string& config,
249
                                        const std::string& native,
250
                                        bool ignoreErrors);
251

Ken Martin's avatar
Ken Martin committed
252
  ///! Get the CMake instance
253
  cmake* GetCMakeInstance() const { return this->CMakeInstance; }
254

Brad King's avatar
Brad King committed
255
  void SetConfiguredFilesPath(cmGlobalGenerator* gen);
256 257 258 259 260
  const std::vector<cmMakefile*>& GetMakefiles() const
  {
    return this->Makefiles;
  }
  const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
261
  {
262
    return this->LocalGenerators;
263
  }
264

265 266 267 268
  cmMakefile* GetCurrentMakefile() const
  {
    return this->CurrentConfigureMakefile;
  }
269

270 271 272 273
  void SetCurrentMakefile(cmMakefile* mf)
  {
    this->CurrentConfigureMakefile = mf;
  }
274

275
  void AddMakefile(cmMakefile* mf);
276

277 278
  ///! Set an generator for an "external makefile based project"
  void SetExternalMakefileProjectGenerator(
279
    cmExternalMakefileProjectGenerator* extraGenerator);
280

281
  std::string GetExtraGeneratorName() const;
282

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

285
  const std::set<std::string>* GetInstallComponents() const
286 287 288
  {
    return &this->InstallComponents;
  }
289

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

292 293
  const char* GetGlobalSetting(std::string const& name) const;
  bool GlobalSettingIsOn(std::string const& name) const;
294
  std::string GetSafeGlobalSetting(std::string const& name) const;
295

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

299
  void EnableInstallTarget();
300

301
  cmDuration TryCompileTimeout;
302

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

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

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

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

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

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

329 330 331
  /*
   * Determine what program to use for building the project.
   */
332
  virtual bool FindMakeProgram(cmMakefile*);
333

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

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

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

343 344
  /** Determine if a name resolves to a framework on disk or a built target
      that is a framework. */
345
  bool NameResolvesToFramework(const std::string& libname) const;
346

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

350 351 352
  /** 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.  */
353
  virtual void AppendDirectoryForConfig(const std::string& prefix,
354
                                        const std::string& config,
355
                                        const std::string& suffix,
356
                                        std::string& dir);
357

358 359 360
  /** 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
361
      they do not yet exist.  */
362
  std::set<std::string> const& GetDirectoryContent(std::string const& dir,
363
                                                   bool needDisk = true);
364

365
  void IndexTarget(cmTarget* t);
366
  void IndexGeneratorTarget(cmGeneratorTarget* gt);
367

368 369 370 371
  // 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);

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

374 375
  virtual const char* GetAllTargetName() const { return "ALL_BUILD"; }
  virtual const char* GetInstallTargetName() const { return "INSTALL"; }
Daniel Pfeifer's avatar
Daniel Pfeifer committed
376 377 378
  virtual const char* GetInstallLocalTargetName() const { return nullptr; }
  virtual const char* GetInstallStripTargetName() const { return nullptr; }
  virtual const char* GetPreinstallTargetName() const { return nullptr; }
379 380
  virtual const char* GetTestTargetName() const { return "RUN_TESTS"; }
  virtual const char* GetPackageTargetName() const { return "PACKAGE"; }
Daniel Pfeifer's avatar
Daniel Pfeifer committed
381 382 383 384
  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; }
385

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

389
  // Class to track a set of dependencies.
390
  typedef cmTargetDependSet TargetDependSet;
391

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

397
  const std::map<std::string, std::vector<cmLocalGenerator*>>& GetProjectMap()
398 399 400 401
    const
  {
    return this->ProjectMap;
  }
402 403 404 405 406

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

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

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

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

420 421
  virtual bool IsXcode() const { return false; }

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

427 428
  virtual bool UseFolderProperty() const;

429 430
  virtual bool IsIPOSupported() const { return false; }

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

435 436 437 438
  /** 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; }

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

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

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

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

450 451
  void ProcessEvaluationFiles();

452
  std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
453 454 455
  {
    return this->BuildExportSets;
  }
456
  void AddBuildExportSet(cmExportBuildFileGenerator*);
457
  void AddBuildExportExportSet(cmExportBuildFileGenerator*);
458 459 460 461
  bool IsExportedTargetsFile(const std::string& filename) const;
  bool GenerateImportFile(const std::string& file);
  cmExportBuildFileGenerator* GetExportedTargetsFile(
    const std::string& filename) const;
462
  void AddCMP0042WarnTarget(const std::string& target);
463
  void AddCMP0068WarnTarget(const std::string& target);
464

465 466
  virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;

467 468
  bool GenerateCPackPropertiesFile();

469 470
  void CreateEvaluationSourceFiles(std::string const& config) const;

471 472
  void SetFilenameTargetDepends(
    cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts);
473 474
  const std::set<const cmGeneratorTarget*>& GetFilenameTargetDepends(
    cmSourceFile* sf) const;
475

476 477 478 479
#if defined(CMAKE_BUILD_WITH_CMAKE)
  cmFileLockPool& GetFileLockPool() { return FileLockPool; }
#endif

480
  bool GetConfigureDoneCMP0026() const
481 482 483
  {
    return this->ConfigureDoneCMP0026AndCMP0024;
  }
484

485
  std::string MakeSilentFlag;
486

Ken Martin's avatar
Ken Martin committed
487
protected:
488
  typedef std::vector<cmLocalGenerator*> GeneratorVector;
489 490
  // for a project collect all its targets by following depend
  // information, and also collect all the targets
491
  void GetTargetSets(TargetDependSet& projectTargets,
492 493
                     TargetDependSet& originalTargets, cmLocalGenerator* root,
                     GeneratorVector const&);
494
  bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
495
  void AddTargetDepends(const cmGeneratorTarget* target,
496
                        TargetDependSet& projectTargets);
497 498 499
  void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf);
  void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf);
  void FillExtensionToLanguageMap(const std::string& l, cmMakefile* mf);
500 501
  virtual bool CheckLanguages(std::vector<std::string> const& languages,
                              cmMakefile* mf) const;
502 503
  virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
                                   const char* envVar) const;
504

505 506
  virtual bool ComputeTargetDepends();

507
  virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
508

509 510 511
  /// @brief Qt AUTOMOC/UIC/RCC target generation
  /// @return true on success
  bool QtAutoGen();
512

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

516
  // Fill the ProjectMap, this must be called after LocalGenerators
Bill Hoffman's avatar
Bill Hoffman committed
517
  // has been populated.
518
  void FillProjectMap();
519
  void CheckTargetProperties();
520 521
  bool IsExcluded(cmStateSnapshot const& root,
                  cmStateSnapshot const& snp) const;
522
  bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
523
  bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
524
  virtual void InitializeProgressMarks() {}
525 526 527 528 529 530 531 532

  struct GlobalTargetInfo
  {
    std::string Name;
    std::string Message;
    cmCustomCommandLines CommandLines;
    std::vector<std::string> Depends;
    std::string WorkingDir;
533 534
    bool UsesTerminal = false;
    GlobalTargetInfo() {}
535 536 537 538 539 540 541 542 543 544 545
  };

  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);
  void AddGlobalTarget_RebuildCache(std::vector<GlobalTargetInfo>& targets);
  void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
  cmTarget CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
546

547 548
  std::string FindMakeProgramFile;
  std::string ConfiguredFilesPath;
549
  cmake* CMakeInstance;
550
  std::vector<cmMakefile*> Makefiles;
551
  std::vector<cmLocalGenerator*> LocalGenerators;
552
  cmMakefile* CurrentConfigureMakefile;
553
  // map from project name to vector of local generators in that project
554
  std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
Ken Martin's avatar
Ken Martin committed
555

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

563
  std::map<std::string, std::string> AliasTargets;
564 565

  cmTarget* FindTargetImpl(std::string const& name) const;
Brad King's avatar
Brad King committed
566

567
  cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
568 569
  cmGeneratorTarget* FindImportedGeneratorTargetImpl(
    std::string const& name) const;
570

571
  const char* GetPredefinedTargetsFolder();
572

Ken Martin's avatar
Ken Martin committed
573
private:
574 575 576 577
  typedef std::unordered_map<std::string, cmTarget*> TargetMap;
  typedef std::unordered_map<std::string, cmGeneratorTarget*>
    GeneratorTargetMap;
  typedef std::unordered_map<std::string, cmMakefile*> MakefileMap;
578
  typedef std::unordered_map<std::string, cmLocalGenerator*> LocalGeneratorMap;
579 580 581 582
  // 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;
583
  GeneratorTargetMap GeneratorTargetSearchIndex;
584

585 586 587 588 589
  // 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;

590 591 592 593 594
  // 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;

595
  cmMakefile* TryCompileOuterMakefile;
596
  // If you add a new map here, make sure it is copied
597
  // in EnableLanguagesFromGenerator
598 599
  std::map<std::string, bool> IgnoreExtensions;
  std::set<std::string> LanguagesReady; // Ready for try_compile
600
  std::set<std::string> LanguagesInProgress;
601 602 603 604 605
  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;
606

607
  // Record hashes for rules and outputs.
608 609 610 611
  struct RuleHash
  {
    char Data[32];
  };
612
  std::map<std::string, RuleHash> RuleHashes;
613
  void CheckRuleHashes();
614 615
  void CheckRuleHashes(std::string const& pfile, std::string const& home);
  void WriteRuleHashes(std::string const& pfile);
616

617
  void WriteSummary();
618
  void WriteSummary(cmGeneratorTarget* target);
619
  void FinalizeTargetCompileInfo();
620

621 622
  virtual void ForceLinkerLanguages();

623 624
  bool CheckTargetsForMissingSources() const;

625 626
  void CreateLocalGenerators();

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

630 631
  void ComputeBuildFileGenerators();

632
  cmExternalMakefileProjectGenerator* ExtraGenerator;
633 634 635

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

637
  // Store computed inter-target dependencies.
638
  typedef std::map<cmGeneratorTarget const*, TargetDependSet> TargetDependMap;
639
  TargetDependMap TargetDependencies;
640

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

647 648
  void ClearGeneratorMembers();

649 650 651
  bool CheckCMP0037(std::string const& targetName,
                    std::string const& reason) const;

652
  void IndexMakefile(cmMakefile* mf);
653
  void IndexLocalGenerator(cmLocalGenerator* lg);
654

Daniel Pfeifer's avatar
Daniel Pfeifer committed
655
  virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }
656

657
  // Cache directory content and target files to be built.
658
  struct DirectoryContent
659
  {
660
    long LastDiskTime = -1;
661 662
    std::set<std::string> All;
    std::set<std::string> Generated;
663
    DirectoryContent() {}
664
  };
665
  std::map<std::string, DirectoryContent> DirectoryContentMap;
666 667

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

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

675
  mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
676
    FilenameTargetDepends;
677 678 679 680 681

#if defined(CMAKE_BUILD_WITH_CMAKE)
  // Pool of file locks
  cmFileLockPool FileLockPool;
#endif
682 683 684 685 686 687 688 689

protected:
  float FirstTimeProgress;
  bool NeedSymbolicMark;
  bool UseLinkScript;
  bool ForceUnixPaths;
  bool ToolSupportsColor;
  bool InstallTargetEnabled;
690
  bool ConfigureDoneCMP0026AndCMP0024;
Ken Martin's avatar
Ken Martin committed
691 692 693
};

#endif