1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
|
/* 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 <iosfwd>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cm/optional>
#include "cm_codecvt_Encoding.hxx"
#include "cmBuildOptions.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmNinjaTypes.h"
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmTransformDepfile.h"
class cmCustomCommand;
class cmGeneratorTarget;
class cmLinkLineComputer;
class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
class cmStateDirectory;
class cmake;
struct cmCxxModuleExportInfo;
/**
* \class cmGlobalNinjaGenerator
* \brief Write a build.ninja file.
*
* The main differences between this generator and the UnixMakefile
* generator family are:
* - We don't care about VERBOSE variable or RULE_MESSAGES property since
* it is handle by Ninja's -v option.
* - We don't care about computing any progress status since Ninja manages
* it itself.
* - We generate one build.ninja and one rules.ninja per project.
* - We try to minimize the number of generated rules: one per target and
* language.
* - We use Ninja special variable $in and $out to produce nice output.
* - We extensively use Ninja variable overloading system to minimize the
* number of generated rules.
*/
class cmGlobalNinjaGenerator : public cmGlobalCommonGenerator
{
public:
/// The default name of Ninja's build file. Typically: build.ninja.
static const char* NINJA_BUILD_FILE;
/// The default name of Ninja's rules file. Typically: rules.ninja.
/// It is included in the main build.ninja file.
static const char* NINJA_RULES_FILE;
/// The indentation string used when generating Ninja's build file.
static const char* INDENT;
/// The shell command used for a no-op.
static std::string const SHELL_NOOP;
/// Write @a count times INDENT level to output stream @a os.
static void Indent(std::ostream& os, int count);
/// Write a divider in the given output stream @a os.
static void WriteDivider(std::ostream& os);
static std::string EncodeRuleName(std::string const& name);
std::string& EncodeLiteral(std::string& lit) override;
std::string GetEncodedLiteral(const std::string& lit);
std::string EncodePath(const std::string& path);
std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const override;
/**
* Write the given @a comment to the output stream @a os. It
* handles new line character properly.
*/
static void WriteComment(std::ostream& os, const std::string& comment);
/**
* Utilized by the generator factory to determine if this generator
* supports toolsets.
*/
static bool SupportsToolset() { return false; }
/**
* Utilized by the generator factory to determine if this generator
* supports platforms.
*/
static bool SupportsPlatform() { return false; }
bool IsIPOSupported() const override { return true; }
/**
* Write a build statement @a build to @a os.
* @warning no escaping of any kind is done here.
*/
void WriteBuild(std::ostream& os, cmNinjaBuild const& build,
int cmdLineLimit = 0, bool* usedResponseFile = nullptr);
class CCOutputs
{
cmGlobalNinjaGenerator* GG;
public:
CCOutputs(cmGlobalNinjaGenerator* gg)
: GG(gg)
{
}
void Add(std::vector<std::string> const& outputs);
cmNinjaDeps ExplicitOuts;
cmNinjaDeps WorkDirOuts;
};
void WriteCustomCommandBuild(std::string const& command,
std::string const& description,
std::string const& comment,
std::string const& depfile,
std::string const& pool, bool uses_terminal,
bool restat, std::string const& config,
CCOutputs outputs,
cmNinjaDeps explicitDeps = cmNinjaDeps(),
cmNinjaDeps orderOnlyDeps = cmNinjaDeps());
void WriteMacOSXContentBuild(std::string input, std::string output,
const std::string& config);
/**
* Write a rule statement to @a os.
* @warning no escaping of any kind is done here.
*/
static void WriteRule(std::ostream& os, cmNinjaRule const& rule);
/**
* Write a variable named @a name to @a os with value @a value and an
* optional @a comment. An @a indent level can be specified.
* @warning no escaping of any kind is done here.
*/
static void WriteVariable(std::ostream& os, const std::string& name,
const std::string& value,
const std::string& comment = "", int indent = 0);
/**
* Write an include statement including @a filename with an optional
* @a comment to the @a os stream.
*/
static void WriteInclude(std::ostream& os, const std::string& filename,
const std::string& comment = "");
/**
* Write a default target statement specifying @a targets as
* the default targets.
*/
static void WriteDefault(std::ostream& os, const cmNinjaDeps& targets,
const std::string& comment = "");
bool IsGCCOnWindows() const { return this->UsingGCCOnWindows; }
void MarkAsGCCOnWindows() { this->UsingGCCOnWindows = true; }
cmGlobalNinjaGenerator(cmake* cm);
static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
return std::unique_ptr<cmGlobalGeneratorFactory>(
new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>());
}
std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
cmMakefile* mf) override;
std::string GetName() const override
{
return cmGlobalNinjaGenerator::GetActualName();
}
static std::string GetActualName() { return "Ninja"; }
bool IsNinja() const override { return true; }
/** Get encoding used by generator for ninja files */
codecvt_Encoding GetMakefileEncoding() const override;
static cmDocumentationEntry GetDocumentation();
void EnableLanguage(std::vector<std::string> const& languages,
cmMakefile* mf, bool optional) override;
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>()) override;
// Setup target names
const char* GetAllTargetName() const override { return "all"; }
const char* GetInstallTargetName() const override { return "install"; }
const char* GetInstallLocalTargetName() const override
{
return "install/local";
}
const char* GetInstallStripTargetName() const override
{
return "install/strip";
}
const char* GetInstallParallelTargetName() const
{
return "install/parallel";
}
const char* GetTestTargetName() const override { return "test"; }
const char* GetPackageTargetName() const override { return "package"; }
const char* GetPackageSourceTargetName() const override
{
return "package_source";
}
const char* GetRebuildCacheTargetName() const override
{
return "rebuild_cache";
}
const char* GetCleanTargetName() const override { return "clean"; }
bool SupportsCustomCommandDepfile() const override { return true; }
cm::optional<cmDepfileFormat> DepfileFormat() const override
{
return cmDepfileFormat::GccDepfile;
}
bool SupportsLinkerDependencyFile() const override { return true; }
virtual cmGeneratedFileStream* GetImplFileStream(
const std::string& /*config*/) const
{
return this->BuildFileStream.get();
}
virtual cmGeneratedFileStream* GetConfigFileStream(
const std::string& /*config*/) const
{
return this->BuildFileStream.get();
}
virtual cmGeneratedFileStream* GetDefaultFileStream() const
{
return this->BuildFileStream.get();
}
virtual cmGeneratedFileStream* GetCommonFileStream() const
{
return this->BuildFileStream.get();
}
cmGeneratedFileStream* GetRulesFileStream() const
{
return this->RulesFileStream.get();
}
std::string const& ConvertToNinjaPath(const std::string& path) const;
std::string ConvertToNinjaAbsPath(std::string path) const;
struct MapToNinjaPathImpl
{
cmGlobalNinjaGenerator* GG;
MapToNinjaPathImpl(cmGlobalNinjaGenerator* gg)
: GG(gg)
{
}
std::string operator()(std::string const& path) const
{
return this->GG->ConvertToNinjaPath(path);
}
};
MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
#ifdef _WIN32
std::string const& GetComspec() const { return this->Comspec; }
#endif
// -- Additional clean files
void AddAdditionalCleanFile(std::string fileName, const std::string& config);
const char* GetAdditionalCleanTargetName() const
{
return "CMakeFiles/clean.additional";
}
static const char* GetByproductsForCleanTargetName()
{
return "CMakeFiles/cmake_byproducts_for_clean_target";
}
void AddCXXCompileCommand(const std::string& commandLine,
const std::string& sourceFile,
const std::string& objPath);
/**
* Add a rule to the generated build system.
* Call WriteRule() behind the scene but perform some check before like:
* - Do not add twice the same rule.
*/
void AddRule(cmNinjaRule const& rule);
bool HasRule(const std::string& name);
void AddCustomCommandRule();
void AddMacOSXContentRule();
bool HasCustomCommandOutput(const std::string& output)
{
return this->CustomCommandOutputs.find(output) !=
this->CustomCommandOutputs.end();
}
/// Called when we have seen the given custom command. Returns true
/// if we has seen it before.
bool SeenCustomCommand(cmCustomCommand const* cc, const std::string& config)
{
return !this->Configs[config].CustomCommands.insert(cc).second;
}
/// Called when we have seen the given custom command output.
void SeenCustomCommandOutput(const std::string& output)
{
this->CustomCommandOutputs.insert(output);
// We don't need the assumed dependencies anymore, because we have
// an output.
this->AssumedSourceDependencies.erase(output);
}
void AddAssumedSourceDependencies(const std::string& source,
const cmNinjaDeps& deps)
{
std::set<std::string>& ASD = this->AssumedSourceDependencies[source];
// Because we may see the same source file multiple times (same source
// specified in multiple targets), compute the union of any assumed
// dependencies.
ASD.insert(deps.begin(), deps.end());
}
virtual std::string OrderDependsTargetForTarget(
cmGeneratorTarget const* target, const std::string& config) const;
std::string OrderDependsTargetForTargetPrivate(
cmGeneratorTarget const* target, const std::string& config) const;
void AppendTargetOutputs(cmGeneratorTarget const* target,
cmNinjaDeps& outputs, const std::string& config,
cmNinjaTargetDepends depends) const;
void AppendTargetDepends(cmGeneratorTarget const* target,
cmNinjaDeps& outputs, const std::string& config,
const std::string& fileConfig,
cmNinjaTargetDepends depends);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
std::unordered_set<std::string>& outputs,
const std::string& config,
const std::string& fileConfig,
bool genexOutput, bool omit_self = true);
void AppendDirectoryForConfig(const std::string& prefix,
const std::string& config,
const std::string& suffix,
std::string& dir) override;
virtual void AppendNinjaFileArgument(GeneratedMakeCommand& /*command*/,
const std::string& /*config*/) const
{
}
virtual void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const
{
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
}
int GetRuleCmdLength(const std::string& name)
{
return this->RuleCmdLength[name];
}
void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target,
const std::string& config);
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
// Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
static std::string RequiredNinjaVersion() { return "1.3"; }
static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
static std::string RequiredNinjaVersionForImplicitOuts() { return "1.7"; }
static std::string RequiredNinjaVersionForManifestRestat() { return "1.8"; }
static std::string RequiredNinjaVersionForMultilineDepfile()
{
return "1.9";
}
static std::string RequiredNinjaVersionForDyndepsCxx() { return "1.11"; }
static std::string RequiredNinjaVersionForDyndepsFortran() { return "1.10"; }
static std::string RequiredNinjaVersionForRestatTool() { return "1.10"; }
static std::string RequiredNinjaVersionForUnconditionalRecompactTool()
{
return "1.10";
}
static std::string RequiredNinjaVersionForMultipleOutputs()
{
return "1.10";
}
static std::string RequiredNinjaVersionForMetadataOnRegeneration()
{
return "1.10.2";
}
static std::string RequiredNinjaVersionForCodePage() { return "1.11"; }
static std::string RequiredNinjaVersionForCWDDepend() { return "1.7"; }
bool SupportsDirectConsole() const override;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
bool SupportsMultilineDepfile() const;
bool SupportsCWDDepend() const;
std::string NinjaOutputPath(std::string const& path) const;
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
bool WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
std::string const& dir_cur_src, std::string const& dir_cur_bld,
std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
std::vector<std::string> const& forward_modules_from_target_dirs,
std::string const& arg_lang, std::string const& arg_modmapfmt,
cmCxxModuleExportInfo const& export_info);
virtual std::string BuildAlias(const std::string& alias,
const std::string& /*config*/) const
{
return alias;
}
virtual std::string ConfigDirectory(const std::string& /*config*/) const
{
return "";
}
cmNinjaDeps& GetByproductsForCleanTarget()
{
return this->ByproductsForCleanTarget;
}
cmNinjaDeps& GetByproductsForCleanTarget(const std::string& config)
{
return this->Configs[config].ByproductsForCleanTarget;
}
bool EnableCrossConfigBuild() const;
std::set<std::string> GetCrossConfigs(const std::string& config) const;
const std::set<std::string>& GetDefaultConfigs() const
{
return this->DefaultConfigs;
}
const std::set<std::string>& GetPerConfigUtilityTargets() const
{
return this->PerConfigUtilityTargets;
}
void AddPerConfigUtilityTarget(const std::string& name)
{
this->PerConfigUtilityTargets.insert(name);
}
bool IsSingleConfigUtility(cmGeneratorTarget const* target) const;
bool CheckCxxModuleSupport(CxxModuleSupportQuery query) override;
bool SupportsBuildDatabase() const override { return true; }
std::string ConvertToOutputPath(std::string path) const override;
protected:
std::vector<std::string> const& GetConfigNames() const;
void Generate() override;
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
virtual bool OpenBuildFileStreams();
virtual void CloseBuildFileStreams();
bool OpenFileStream(std::unique_ptr<cmGeneratedFileStream>& stream,
const std::string& name);
static cm::optional<std::set<std::string>> ListSubsetWithAll(
const std::set<std::string>& all, const std::set<std::string>& defaults,
const std::vector<std::string>& items);
std::set<std::string> CrossConfigs;
std::set<std::string> DefaultConfigs;
std::string DefaultFileConfig;
private:
bool FindMakeProgram(cmMakefile* mf) override;
void CheckNinjaFeatures();
void CheckNinjaCodePage();
bool CheckLanguages(std::vector<std::string> const& languages,
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
bool CheckISPC(cmMakefile* mf) const;
void CloseCompileCommandsStream();
bool OpenRulesFileStream();
void CloseRulesFileStream();
void CleanMetaData();
/// Write the common disclaimer text at the top of each build file.
void WriteDisclaimer(std::ostream& os) const;
void WriteAssumedSourceDependencies();
void WriteTargetAliases(std::ostream& os);
void WriteFolderTargets(std::ostream& os);
void WriteUnknownExplicitDependencies(std::ostream& os);
void WriteBuiltinTargets(std::ostream& os);
void WriteTargetDefault(std::ostream& os);
void WriteTargetRebuildManifest(std::ostream& os);
bool WriteTargetCleanAdditional(std::ostream& os);
void WriteTargetClean(std::ostream& os);
void WriteTargetHelp(std::ostream& os);
void ComputeTargetDependsClosure(
cmGeneratorTarget const* target,
std::set<cmGeneratorTarget const*>& depends);
std::string CMakeCmd() const;
std::string NinjaCmd() const;
/// The file containing the build statement. (the relationship of the
/// compilation DAG).
std::unique_ptr<cmGeneratedFileStream> BuildFileStream;
/// The file containing the rule statements. (The action attached to each
/// edge of the compilation DAG).
std::unique_ptr<cmGeneratedFileStream> RulesFileStream;
std::unique_ptr<cmGeneratedFileStream> CompileCommandsStream;
/// The set of rules added to the generated build system.
std::unordered_set<std::string> Rules;
/// Length of rule command, used by rsp file evaluation
std::unordered_map<std::string, int> RuleCmdLength;
bool UsingGCCOnWindows = false;
/// The set of custom command outputs we have seen.
std::set<std::string> CustomCommandOutputs;
/// Whether we are collecting known build outputs and needed
/// dependencies to determine unknown dependencies.
bool ComputingUnknownDependencies = false;
cmPolicies::PolicyStatus PolicyCMP0058 = cmPolicies::WARN;
/// The combined explicit dependencies of custom build commands
std::set<std::string> CombinedCustomCommandExplicitDependencies;
/// When combined with CombinedCustomCommandExplicitDependencies it allows
/// us to detect the set of explicit dependencies that have
std::set<std::string> CombinedBuildOutputs;
/// The mapping from source file to assumed dependencies.
std::map<std::string, std::set<std::string>> AssumedSourceDependencies;
/// Utility targets which have per-config outputs
std::set<std::string> PerConfigUtilityTargets;
struct TargetAlias
{
cmGeneratorTarget* GeneratorTarget;
std::string Config;
};
using TargetAliasMap = std::map<std::string, TargetAlias>;
TargetAliasMap TargetAliases;
TargetAliasMap DefaultTargetAliases;
/// the local cache for calls to ConvertToNinjaPath
mutable std::unordered_map<std::string, std::string> ConvertToNinjaPathCache;
std::string NinjaCommand;
std::string NinjaVersion;
bool NinjaSupportsConsolePool = false;
bool NinjaSupportsImplicitOuts = false;
bool NinjaSupportsManifestRestat = false;
bool NinjaSupportsMultilineDepfile = false;
bool NinjaSupportsDyndepsCxx = false;
bool NinjaSupportsDyndepsFortran = false;
bool NinjaSupportsRestatTool = false;
bool NinjaSupportsUnconditionalRecompactTool = false;
bool NinjaSupportsMultipleOutputs = false;
bool NinjaSupportsMetadataOnRegeneration = false;
bool NinjaSupportsCodePage = false;
bool NinjaSupportsCWDDepend = false;
codecvt_Encoding NinjaExpectedEncoding = codecvt_Encoding::None;
#ifdef _WIN32
// Windows Command shell.
std::string Comspec;
#endif
bool DiagnosedCxxModuleNinjaSupport = false;
void InitOutputPathPrefix();
std::string OutputPathPrefix;
std::string TargetAll;
std::string CMakeCacheFile;
struct ByConfig
{
std::set<std::string> AdditionalCleanFiles;
/// The set of custom commands we have seen.
std::set<cmCustomCommand const*> CustomCommands;
struct TargetDependsClosureKey
{
cmGeneratorTarget const* Target;
std::string Config;
bool GenexOutput;
};
std::map<TargetDependsClosureKey, std::unordered_set<std::string>>
TargetDependsClosures;
TargetAliasMap TargetAliases;
cmNinjaDeps ByproductsForCleanTarget;
};
std::map<std::string, ByConfig> Configs;
cmNinjaDeps ByproductsForCleanTarget;
friend bool operator==(const ByConfig::TargetDependsClosureKey& lhs,
const ByConfig::TargetDependsClosureKey& rhs);
friend bool operator!=(const ByConfig::TargetDependsClosureKey& lhs,
const ByConfig::TargetDependsClosureKey& rhs);
friend bool operator<(const ByConfig::TargetDependsClosureKey& lhs,
const ByConfig::TargetDependsClosureKey& rhs);
friend bool operator>(const ByConfig::TargetDependsClosureKey& lhs,
const ByConfig::TargetDependsClosureKey& rhs);
friend bool operator<=(const ByConfig::TargetDependsClosureKey& lhs,
const ByConfig::TargetDependsClosureKey& rhs);
friend bool operator>=(const ByConfig::TargetDependsClosureKey& lhs,
const ByConfig::TargetDependsClosureKey& rhs);
};
class cmGlobalNinjaMultiGenerator : public cmGlobalNinjaGenerator
{
public:
/// The default name of Ninja's common file. Typically: common.ninja.
static const char* NINJA_COMMON_FILE;
/// The default file extension to use for per-config Ninja files.
static const char* NINJA_FILE_EXTENSION;
cmGlobalNinjaMultiGenerator(cmake* cm);
bool IsMultiConfig() const override { return true; }
static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
return std::unique_ptr<cmGlobalGeneratorFactory>(
new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaMultiGenerator>());
}
static cmDocumentationEntry GetDocumentation();
std::string GetName() const override
{
return cmGlobalNinjaMultiGenerator::GetActualName();
}
static std::string GetActualName() { return "Ninja Multi-Config"; }
std::string BuildAlias(const std::string& alias,
const std::string& config) const override
{
if (config.empty()) {
return alias;
}
return cmStrCat(alias, ":", config);
}
std::string ConfigDirectory(const std::string& config) const override
{
if (!config.empty()) {
return cmStrCat('/', config);
}
return "";
}
const char* GetCMakeCFGIntDir() const override { return "${CONFIGURATION}"; }
std::string ExpandCFGIntDir(const std::string& str,
const std::string& config) const override;
cmGeneratedFileStream* GetImplFileStream(
const std::string& config) const override
{
return this->ImplFileStreams.at(config).get();
}
cmGeneratedFileStream* GetConfigFileStream(
const std::string& config) const override
{
return this->ConfigFileStreams.at(config).get();
}
cmGeneratedFileStream* GetDefaultFileStream() const override
{
return this->DefaultFileStream.get();
}
cmGeneratedFileStream* GetCommonFileStream() const override
{
return this->CommonFileStream.get();
}
void AppendNinjaFileArgument(GeneratedMakeCommand& command,
const std::string& config) const override;
static std::string GetNinjaImplFilename(const std::string& config);
static std::string GetNinjaConfigFilename(const std::string& config);
void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const override;
void GetQtAutoGenConfigs(std::vector<std::string>& configs) const override;
bool InspectConfigTypeVariables() override;
std::string GetDefaultBuildConfig() const override;
bool SupportsDefaultBuildType() const override { return true; }
bool SupportsCrossConfigs() const override { return true; }
bool SupportsDefaultConfigs() const override { return true; }
std::string OrderDependsTargetForTarget(
cmGeneratorTarget const* target, const std::string& config) const override;
protected:
bool OpenBuildFileStreams() override;
void CloseBuildFileStreams() override;
private:
std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
ImplFileStreams;
std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
ConfigFileStreams;
std::unique_ptr<cmGeneratedFileStream> CommonFileStream;
std::unique_ptr<cmGeneratedFileStream> DefaultFileStream;
};
|