summaryrefslogtreecommitdiff
path: root/Source/cmGlobalNinjaGenerator.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalNinjaGenerator.h')
-rw-r--r--Source/cmGlobalNinjaGenerator.h371
1 files changed, 232 insertions, 139 deletions
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index e046c7c96..b0008f74a 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -1,27 +1,34 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
- Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com>
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmGlobalNinjaGenerator_h
-# define cmGlobalNinjaGenerator_h
+#define cmGlobalNinjaGenerator_h
-# include "cmGlobalGenerator.h"
-# include "cmGlobalGeneratorFactory.h"
-# include "cmNinjaTypes.h"
+#include "cmConfigure.h"
-//#define NINJA_GEN_VERBOSE_FILES
+#include <iosfwd>
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
-class cmLocalGenerator;
+#include "cmGlobalCommonGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmGlobalGeneratorFactory.h"
+#include "cmNinjaTypes.h"
+#include "cmPolicies.h"
+#include "cm_codecvt.hxx"
+
+class cmCustomCommand;
class cmGeneratedFileStream;
class cmGeneratorTarget;
+class cmLinkLineComputer;
+class cmLocalGenerator;
+class cmMakefile;
+class cmOutputConverter;
+class cmStateDirectory;
+class cmake;
+struct cmDocumentationEntry;
/**
* \class cmGlobalNinjaGenerator
@@ -42,7 +49,7 @@ class cmGeneratorTarget;
* - We extensively use Ninja variable overloading system to minimize the
* number of generated rules.
*/
-class cmGlobalNinjaGenerator : public cmGlobalGenerator
+class cmGlobalNinjaGenerator : public cmGlobalCommonGenerator
{
public:
/// The default name of Ninja's build file. Typically: build.ninja.
@@ -55,15 +62,23 @@ public:
/// 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 EncodeIdent(const std::string &ident, std::ostream &vars);
- static std::string EncodeLiteral(const std::string &lit);
- static std::string EncodePath(const std::string &path);
+ static std::string EncodeRuleName(std::string const& name);
+ static std::string EncodeIdent(const std::string& ident, std::ostream& vars);
+ static std::string EncodeLiteral(const std::string& lit);
+ std::string EncodePath(const std::string& path);
+
+ cmLinkLineComputer* CreateLinkLineComputer(
+ cmOutputConverter* outputConverter,
+ cmStateDirectory const& stateDir) const CM_OVERRIDE;
/**
* Write the given @a comment to the output stream @a os. It
@@ -72,27 +87,39 @@ public:
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 CM_OVERRIDE { return true; }
+
+ /**
* Write a build statement to @a os with the @a comment using
* the @a rule the list of @a outputs files and inputs.
* It also writes the variables bound to this build statement.
* @warning no escaping of any kind is done here.
*/
- void WriteBuild(std::ostream& os,
- const std::string& comment,
- const std::string& rule,
- const cmNinjaDeps& outputs,
+ void WriteBuild(std::ostream& os, const std::string& comment,
+ const std::string& rule, const cmNinjaDeps& outputs,
+ const cmNinjaDeps& implicitOuts,
const cmNinjaDeps& explicitDeps,
const cmNinjaDeps& implicitDeps,
const cmNinjaDeps& orderOnlyDeps,
const cmNinjaVars& variables,
const std::string& rspfile = std::string(),
- int cmdLineLimit = -1);
+ int cmdLineLimit = 0, bool* usedResponseFile = CM_NULLPTR);
/**
* Helper to write a build statement with the special 'phony' rule.
*/
- void WritePhonyBuild(std::ostream& os,
- const std::string& comment,
+ void WritePhonyBuild(std::ostream& os, const std::string& comment,
const cmNinjaDeps& outputs,
const cmNinjaDeps& explicitDeps,
const cmNinjaDeps& implicitDeps = cmNinjaDeps(),
@@ -102,9 +129,10 @@ public:
void WriteCustomCommandBuild(const std::string& command,
const std::string& description,
const std::string& comment,
- const cmNinjaDeps& outputs,
+ const std::string& depfile, bool uses_terminal,
+ bool restat, const cmNinjaDeps& outputs,
const cmNinjaDeps& deps = cmNinjaDeps(),
- const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
+ const cmNinjaDeps& orderOnly = cmNinjaDeps());
void WriteMacOSXContentBuild(const std::string& input,
const std::string& output);
@@ -114,198 +142,238 @@ public:
* It also writes the variables bound to this rule statement.
* @warning no escaping of any kind is done here.
*/
- static void WriteRule(std::ostream& os,
- const std::string& name,
+ static void WriteRule(std::ostream& os, const std::string& name,
const std::string& command,
const std::string& description,
- const std::string& comment,
- const std::string& depfile,
- const std::string& rspfile,
+ const std::string& comment, const std::string& depfile,
+ const std::string& deptype, const std::string& rspfile,
const std::string& rspcontent,
- bool restat,
- bool generator);
+ const std::string& restat, bool generator);
/**
* 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,
+ static void WriteVariable(std::ostream& os, const std::string& name,
const std::string& value,
- const std::string& comment = "",
- int indent = 0);
+ 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,
+ 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,
+ static void WriteDefault(std::ostream& os, const cmNinjaDeps& targets,
const std::string& comment = "");
-
- static bool IsMinGW() { return UsingMinGW; }
-
+ bool IsGCCOnWindows() const { return UsingGCCOnWindows; }
public:
- /// Default constructor.
- cmGlobalNinjaGenerator();
+ cmGlobalNinjaGenerator(cmake* cm);
- /// Convenience method for creating an instance of this class.
- static cmGlobalGeneratorFactory* NewFactory() {
- return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>(); }
+ static cmGlobalGeneratorFactory* NewFactory()
+ {
+ return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>();
+ }
+
+ ~cmGlobalNinjaGenerator() CM_OVERRIDE {}
- /// Destructor.
- virtual ~cmGlobalNinjaGenerator() { }
+ cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) CM_OVERRIDE;
- /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator()
- virtual cmLocalGenerator* CreateLocalGenerator();
+ std::string GetName() const CM_OVERRIDE
+ {
+ return cmGlobalNinjaGenerator::GetActualName();
+ }
- /// Overloaded methods. @see cmGlobalGenerator::GetName().
- virtual const char* GetName() const {
- return cmGlobalNinjaGenerator::GetActualName(); }
+ static std::string GetActualName() { return "Ninja"; }
- /// @return the name of this generator.
- static const char* GetActualName() { return "Ninja"; }
+ /** Get encoding used by generator for ninja files */
+ codecvt::Encoding GetMakefileEncoding() const CM_OVERRIDE;
- /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
static void GetDocumentation(cmDocumentationEntry& entry);
- /// Overloaded methods. @see cmGlobalGenerator::Generate()
- virtual void Generate();
-
- /// Overloaded methods. @see cmGlobalGenerator::EnableLanguage()
- virtual void EnableLanguage(std::vector<std::string>const& languages,
- cmMakefile* mf,
- bool optional);
+ void EnableLanguage(std::vector<std::string> const& languages,
+ cmMakefile* mf, bool optional) CM_OVERRIDE;
- /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand()
- virtual std::string GenerateBuildCommand(const char* makeProgram,
- const char* projectName,
- const char* projectDir,
- const char* additionalOptions,
- const char* targetName,
- const char* config,
- bool ignoreErrors,
- bool fast);
+ void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config, bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions =
+ std::vector<std::string>()) CM_OVERRIDE;
// Setup target names
- virtual const char* GetAllTargetName() const { return "all"; }
- virtual const char* GetInstallTargetName() const { return "install"; }
- virtual const char* GetInstallLocalTargetName() const {
+ const char* GetAllTargetName() const CM_OVERRIDE { return "all"; }
+ const char* GetInstallTargetName() const CM_OVERRIDE { return "install"; }
+ const char* GetInstallLocalTargetName() const CM_OVERRIDE
+ {
return "install/local";
}
- virtual const char* GetInstallStripTargetName() const {
+ const char* GetInstallStripTargetName() const CM_OVERRIDE
+ {
return "install/strip";
}
- virtual const char* GetTestTargetName() const { return "test"; }
- virtual const char* GetPackageTargetName() const { return "package"; }
- virtual const char* GetPackageSourceTargetName() const {
+ const char* GetTestTargetName() const CM_OVERRIDE { return "test"; }
+ const char* GetPackageTargetName() const CM_OVERRIDE { return "package"; }
+ const char* GetPackageSourceTargetName() const CM_OVERRIDE
+ {
return "package_source";
}
- virtual const char* GetEditCacheTargetName() const {
+ const char* GetEditCacheTargetName() const CM_OVERRIDE
+ {
return "edit_cache";
}
- virtual const char* GetRebuildCacheTargetName() const {
+ const char* GetRebuildCacheTargetName() const CM_OVERRIDE
+ {
return "rebuild_cache";
}
- virtual const char* GetCleanTargetName() const { return "clean"; }
+ const char* GetCleanTargetName() const CM_OVERRIDE { return "clean"; }
+ cmGeneratedFileStream* GetBuildFileStream() const
+ {
+ return this->BuildFileStream;
+ }
- cmGeneratedFileStream* GetBuildFileStream() const {
- return this->BuildFileStream; }
-
- cmGeneratedFileStream* GetRulesFileStream() const {
- return this->RulesFileStream; }
+ cmGeneratedFileStream* GetRulesFileStream() const
+ {
+ return this->RulesFileStream;
+ }
- void AddCXXCompileCommand(const std::string &commandLine,
- const std::string &sourceFile);
+ std::string ConvertToNinjaPath(const std::string& path) const;
+
+ struct MapToNinjaPathImpl
+ {
+ cmGlobalNinjaGenerator* GG;
+ MapToNinjaPathImpl(cmGlobalNinjaGenerator* gg)
+ : GG(gg)
+ {
+ }
+ std::string operator()(std::string const& path)
+ {
+ return this->GG->ConvertToNinjaPath(path);
+ }
+ };
+ MapToNinjaPathImpl MapToNinjaPath() { return MapToNinjaPathImpl(this); }
+
+ void AddCXXCompileCommand(const std::string& commandLine,
+ const std::string& sourceFile);
/**
* 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(const std::string& name,
- const std::string& command,
- const std::string& description,
- const std::string& comment,
- const std::string& depfile = "",
- const std::string& rspfile = "",
- const std::string& rspcontent = "",
- bool restat = false,
- bool generator = false);
+ void AddRule(const std::string& name, const std::string& command,
+ const std::string& description, const std::string& comment,
+ const std::string& depfile, const std::string& deptype,
+ const std::string& rspfile, const std::string& rspcontent,
+ const std::string& restat, bool generator);
bool HasRule(const std::string& name);
void AddCustomCommandRule();
void AddMacOSXContentRule();
- bool HasCustomCommandOutput(const std::string &output) {
+ bool HasCustomCommandOutput(const std::string& output)
+ {
return this->CustomCommandOutputs.find(output) !=
- this->CustomCommandOutputs.end();
+ 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) {
+ bool SeenCustomCommand(cmCustomCommand const* cc)
+ {
return !this->CustomCommands.insert(cc).second;
}
/// Called when we have seen the given custom command output.
- void SeenCustomCommandOutput(const std::string &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];
+ 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());
}
- void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs);
- void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
- void AddDependencyToAll(cmTarget* target);
+ void AppendTargetOutputs(
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends = DependOnTargetArtifact);
+ void AppendTargetDepends(
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends = DependOnTargetArtifact);
+ void AppendTargetDependsClosure(cmGeneratorTarget const* target,
+ cmNinjaDeps& outputs);
+ void AddDependencyToAll(cmGeneratorTarget* target);
void AddDependencyToAll(const std::string& input);
- const std::vector<cmLocalGenerator*>& GetLocalGenerators() const {
- return LocalGenerators; }
+ const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
+ {
+ return LocalGenerators;
+ }
- bool IsExcluded(cmLocalGenerator* root, cmTarget& target) {
- return cmGlobalGenerator::IsExcluded(root, target); }
+ bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target)
+ {
+ return cmGlobalGenerator::IsExcluded(root, target);
+ }
- int GetRuleCmdLength(const std::string& name) {
- return RuleCmdLength[name]; }
+ int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
- void AddTargetAlias(const std::string& alias, cmTarget* target);
+ void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
+ void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const CM_OVERRIDE;
-protected:
+ // 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"; }
+ bool SupportsConsolePool() const;
+ bool SupportsImplicitOuts() const;
- /// Overloaded methods.
- /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
- virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
+ 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);
-private:
+protected:
+ void Generate() CM_OVERRIDE;
- /// @see cmGlobalGenerator::ComputeTargetObjects
- virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+ bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const CM_OVERRIDE { return true; }
+
+private:
+ std::string GetEditCacheCommand() const CM_OVERRIDE;
+ bool FindMakeProgram(cmMakefile* mf) CM_OVERRIDE;
+ void CheckNinjaFeatures();
+ bool CheckLanguages(std::vector<std::string> const& languages,
+ cmMakefile* mf) const CM_OVERRIDE;
+ bool CheckFortran(cmMakefile* mf) const;
void OpenBuildFileStream();
void CloseBuildFileStream();
@@ -321,6 +389,7 @@ private:
void WriteAssumedSourceDependencies();
void WriteTargetAliases(std::ostream& os);
+ void WriteFolderTargets(std::ostream& os);
void WriteUnknownExplicitDependencies(std::ostream& os);
void WriteBuiltinTargets(std::ostream& os);
@@ -329,10 +398,13 @@ private:
void WriteTargetClean(std::ostream& os);
void WriteTargetHelp(std::ostream& os);
- std::string ninjaCmd() const;
+ void ComputeTargetDependsClosure(
+ cmGeneratorTarget const* target,
+ std::set<cmGeneratorTarget const*>& depends);
+ std::string ninjaCmd() const;
- /// The file containing the build statement. (the relation ship of the
+ /// The file containing the build statement. (the relationship of the
/// compilation DAG).
cmGeneratedFileStream* BuildFileStream;
/// The file containing the rule statements. (The action attached to each
@@ -353,28 +425,49 @@ private:
/// The set of dependencies to add to the "all" target.
cmNinjaDeps AllDependencies;
+ bool UsingGCCOnWindows;
+
/// The set of custom commands we have seen.
std::set<cmCustomCommand const*> CustomCommands;
/// The set of custom command outputs we have seen.
std::set<std::string> CustomCommandOutputs;
- //The combined explicit dependencies of all build commands that the global
- //generator has issued. When combined with CombinedBuildOutputs it allows
- //us to detect the set of explicit dependencies that have
- std::set<std::string> CombinedBuildExplicitDependencies;
+ /// Whether we are collecting known build outputs and needed
+ /// dependencies to determine unknown dependencies.
+ bool ComputingUnknownDependencies;
+ cmPolicies::PolicyStatus PolicyCMP0058;
+
+ /// 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;
- typedef std::map<std::string, cmTarget*> TargetAliasMap;
+ typedef std::map<std::string, cmGeneratorTarget*> TargetAliasMap;
TargetAliasMap TargetAliases;
- static cmLocalGenerator* LocalGenerator;
+ typedef std::map<cmGeneratorTarget const*,
+ std::set<cmGeneratorTarget const*> >
+ TargetDependsClosureMap;
+ TargetDependsClosureMap TargetDependsClosures;
- static bool UsingMinGW;
+ std::string NinjaCommand;
+ std::string NinjaVersion;
+ bool NinjaSupportsConsolePool;
+ bool NinjaSupportsImplicitOuts;
+ unsigned long NinjaSupportsDyndeps;
+
+private:
+ void InitOutputPathPrefix();
+ std::string OutputPathPrefix;
+ std::string TargetAll;
+ std::string CMakeCacheFile;
};
#endif // ! cmGlobalNinjaGenerator_h