| /* 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; |
| }; |