summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorNicolas Despres <nicolas.despres@gmail.com>2016-05-13 23:18:20 (GMT)
committerBrad King <brad.king@kitware.com>2016-05-17 13:34:12 (GMT)
commit8a862a4d4b852c9f61ae4ed7fc46042b00a83123 (patch)
tree591906a0300c9619e57394105455d93126dab939 /Source
parent038e7716e58e4cf79bda6ba72b92814a14978a8f (diff)
downloadCMake-8a862a4d4b852c9f61ae4ed7fc46042b00a83123.zip
CMake-8a862a4d4b852c9f61ae4ed7fc46042b00a83123.tar.gz
CMake-8a862a4d4b852c9f61ae4ed7fc46042b00a83123.tar.bz2
Ninja: Support embedding of CMake as subninja project
Add a `CMAKE_NINJA_OUTPUT_PATH_PREFIX` variable. When it is set, CMake generates a `build.ninja` file suitable for embedding into another ninja project potentially generated by an alien generator.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmAlgorithms.h15
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx47
-rw-r--r--Source/cmGlobalNinjaGenerator.h5
-rw-r--r--Source/cmNinjaTargetGenerator.cxx10
4 files changed, 70 insertions, 7 deletions
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index 76acaca..ee803c8 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -379,4 +379,19 @@ std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it)
return std::reverse_iterator<Iter>(it);
}
+inline bool cmHasSuffix(const std::string& str, const std::string& suffix)
+{
+ if (str.size() < suffix.size()) {
+ return false;
+ }
+ return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+inline void cmStripSuffixIfExists(std::string& str, const std::string& suffix)
+{
+ if (cmHasSuffix(str, suffix)) {
+ str.resize(str.size() - suffix.size());
+ }
+}
+
#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 3c5a8e3..d65b463 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -488,6 +488,7 @@ void cmGlobalNinjaGenerator::Generate()
this->OpenBuildFileStream();
this->OpenRulesFileStream();
+ this->InitOutputPathPrefix();
this->TargetAll = this->NinjaOutputPath("all");
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
@@ -717,6 +718,23 @@ void cmGlobalNinjaGenerator::CloseRulesFileStream()
}
}
+static void EnsureTrailingSlash(std::string& path)
+{
+ if (path.empty()) {
+ return;
+ }
+ std::string::value_type last = path[path.size() - 1];
+#ifdef _WIN32
+ if (last != '\\') {
+ path += '\\';
+ }
+#else
+ if (last != '/') {
+ path += '/';
+ }
+#endif
+}
+
std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
{
cmLocalNinjaGenerator* ng =
@@ -1136,8 +1154,10 @@ void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os)
this->WritePhonyBuild(os, "The main all target.", outputs,
this->AllDependencies);
- cmGlobalNinjaGenerator::WriteDefault(os, outputs,
- "Make the all target the default.");
+ if (!this->HasOutputPathPrefix()) {
+ cmGlobalNinjaGenerator::WriteDefault(os, outputs,
+ "Make the all target the default.");
+ }
}
void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
@@ -1251,7 +1271,28 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
/*variables=*/cmNinjaVars());
}
+void cmGlobalNinjaGenerator::InitOutputPathPrefix()
+{
+ this->OutputPathPrefix =
+ this->LocalGenerators[0]->GetMakefile()->GetSafeDefinition(
+ "CMAKE_NINJA_OUTPUT_PATH_PREFIX");
+ EnsureTrailingSlash(this->OutputPathPrefix);
+}
+
std::string cmGlobalNinjaGenerator::NinjaOutputPath(std::string const& path)
{
- return path;
+ if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) {
+ return path;
+ }
+ return this->OutputPathPrefix + path;
+}
+
+void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
+ std::string& path)
+{
+ if (path.empty()) {
+ return;
+ }
+ EnsureTrailingSlash(path);
+ cmStripSuffixIfExists(path, this->OutputPathPrefix);
}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 15c0f34..6d9bfe8 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -315,6 +315,8 @@ public:
bool SupportsConsolePool() const;
std::string NinjaOutputPath(std::string const& path);
+ bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
+ void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
protected:
virtual void Generate();
@@ -401,6 +403,9 @@ private:
std::string NinjaVersion;
private:
+ void InitOutputPathPrefix();
+
+ std::string OutputPathPrefix;
std::string TargetAll;
std::string CMakeCacheFile;
};
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 994daea..4d58242 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -669,10 +669,12 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists(
if (cmSystemTools::FileIsFullPath(path.c_str())) {
cmSystemTools::MakeDirectory(path.c_str());
} else {
- const std::string fullPath = std::string(this->GetGlobalGenerator()
- ->GetCMakeInstance()
- ->GetHomeOutputDirectory()) +
- "/" + path;
+ cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
+ std::string fullPath =
+ std::string(gg->GetCMakeInstance()->GetHomeOutputDirectory());
+ // Also ensures their is a trailing slash.
+ gg->StripNinjaOutputPathPrefixAsSuffix(fullPath);
+ fullPath += path;
cmSystemTools::MakeDirectory(fullPath.c_str());
}
}