diff options
author | Charles Huet <charles.huet@gmail.com> | 2016-03-11 15:26:29 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-03-18 14:59:01 (GMT) |
commit | ca575fe9355a2be2b9fadcc84b05bcfa095c5e64 (patch) | |
tree | 77457921fa1646f190a7b2012a850e7f7a37a7e1 /Source/cmGlobalNinjaGenerator.cxx | |
parent | 9cdb37e9175b2e3c6367bc4863fda0404cb1c3a2 (diff) | |
download | CMake-ca575fe9355a2be2b9fadcc84b05bcfa095c5e64.zip CMake-ca575fe9355a2be2b9fadcc84b05bcfa095c5e64.tar.gz CMake-ca575fe9355a2be2b9fadcc84b05bcfa095c5e64.tar.bz2 |
Ninja: Add `$subdir/all` targets
With the Makefile generator one can use `cd $subdir; make all` to build
all targets associated with a given subdirectory. This is not possible
to do with the Ninja generator since there is only one `build.ninja`
file at the top of the build tree. However, we can approximate it by
allowing one to run `ninja $subdir/all` at the top of the tree to build
the targets in the corresponding subdirectory.
Port logic from cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2 to
cmGlobalNinjaGenerator in order to produce equivalent directory-level
targets.
Diffstat (limited to 'Source/cmGlobalNinjaGenerator.cxx')
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 83422b7..f12396f 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -577,6 +577,7 @@ void cmGlobalNinjaGenerator::Generate() this->WriteAssumedSourceDependencies(); this->WriteTargetAliases(*this->BuildFileStream); + this->WriteFolderTargets(*this->BuildFileStream); this->WriteUnknownExplicitDependencies(*this->BuildFileStream); this->WriteBuiltinTargets(*this->BuildFileStream); @@ -848,6 +849,18 @@ std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path) return convPath; } +std::string +cmGlobalNinjaGenerator::ConvertToNinjaFolderRule(const std::string& path) +{ + cmLocalNinjaGenerator *ng = + static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]); + std::string convPath = ng->Convert(path+"/all", cmOutputConverter::HOME); +#ifdef _WIN32 + cmSystemTools::ReplaceString(convPath, "/", "\\"); +#endif + return convPath; +} + void cmGlobalNinjaGenerator::AddCXXCompileCommand( const std::string &commandLine, const std::string &sourceFile) @@ -1044,6 +1057,75 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) } } +void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + os << "# Folder targets.\n\n"; + + std::map<std::string, cmNinjaDeps> targetsPerFolder; + for (std::vector<cmLocalGenerator *>::const_iterator + lgi = this->LocalGenerators.begin(); + lgi != this->LocalGenerators.end(); ++lgi) + { + cmLocalGenerator const* lg = *lgi; + const std::string currentSourceFolder( + lg->GetStateSnapshot().GetDirectory().GetCurrentSource()); + // The directory-level rule should depend on the target-level rules + // for all targets in the directory. + targetsPerFolder[currentSourceFolder] = cmNinjaDeps(); + for (std::vector<cmGeneratorTarget*>::const_iterator + ti = lg->GetGeneratorTargets().begin(); + ti != lg->GetGeneratorTargets().end(); ++ti) + { + cmGeneratorTarget const* gt = *ti; + cmState::TargetType const type = gt->GetType(); + if((type == cmState::EXECUTABLE || + type == cmState::STATIC_LIBRARY || + type == cmState::SHARED_LIBRARY || + type == cmState::MODULE_LIBRARY || + type == cmState::OBJECT_LIBRARY || + type == cmState::UTILITY) && + !gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) + { + targetsPerFolder[currentSourceFolder].push_back(gt->GetName()); + } + } + + // The directory-level rule should depend on the directory-level + // rules of the subdirectories. + std::vector<cmState::Snapshot> const& children = + lg->GetStateSnapshot().GetChildren(); + for(std::vector<cmState::Snapshot>::const_iterator + stateIt = children.begin(); stateIt != children.end(); ++stateIt) + { + targetsPerFolder[currentSourceFolder].push_back( + this->ConvertToNinjaFolderRule( + stateIt->GetDirectory().GetCurrentSource())); + } + } + + std::string const rootSourceDir = + this->LocalGenerators[0]->GetSourceDirectory(); + for (std::map<std::string, cmNinjaDeps >::const_iterator it = + targetsPerFolder.begin(); it != targetsPerFolder.end(); ++it) + { + cmGlobalNinjaGenerator::WriteDivider( os ); + std::string const& currentSourceDir = it->first; + + // Do not generate a rule for the root source dir. + if (rootSourceDir.length() >= currentSourceDir.length()) + { + continue; + } + + std::string const comment = "Folder: " + currentSourceDir; + cmNinjaDeps output(1); + output.push_back(this->ConvertToNinjaFolderRule(currentSourceDir)); + + this->WritePhonyBuild(os, comment, output, it->second); + } +} + void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) { if (!this->ComputingUnknownDependencies) |