Merge topic 'ninja-directory-targets'
9ead71df
Help: Add notes for topic 'ninja-directory-targets'e9bf8ec8
Ninja: Add test for `$subdir/all` targetsca575fe9
Ninja: Add `$subdir/all` targets
This commit is contained in:
commit
2f9e6551c0
|
@ -6,3 +6,7 @@ Generates build.ninja files.
|
||||||
A build.ninja file is generated into the build tree. Recent versions
|
A build.ninja file is generated into the build tree. Recent versions
|
||||||
of the ninja program can build the project through the "all" target.
|
of the ninja program can build the project through the "all" target.
|
||||||
An "install" target is also provided.
|
An "install" target is also provided.
|
||||||
|
|
||||||
|
For each subdirectory ``sub/dir`` of the project an additional target
|
||||||
|
named ``sub/dir/all`` is generated that depends on all targets required
|
||||||
|
by that subdirectory.
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
ninja-directory-targets
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* The :generator:`Ninja` generator learned to produce phony targets
|
||||||
|
of the form ``sub/dir/all`` to drive the build of a subdirectory.
|
||||||
|
This is equivalent to ``cd sub/dir; make all`` with
|
||||||
|
:ref:`Makefile Generators`.
|
|
@ -577,6 +577,7 @@ void cmGlobalNinjaGenerator::Generate()
|
||||||
|
|
||||||
this->WriteAssumedSourceDependencies();
|
this->WriteAssumedSourceDependencies();
|
||||||
this->WriteTargetAliases(*this->BuildFileStream);
|
this->WriteTargetAliases(*this->BuildFileStream);
|
||||||
|
this->WriteFolderTargets(*this->BuildFileStream);
|
||||||
this->WriteUnknownExplicitDependencies(*this->BuildFileStream);
|
this->WriteUnknownExplicitDependencies(*this->BuildFileStream);
|
||||||
this->WriteBuiltinTargets(*this->BuildFileStream);
|
this->WriteBuiltinTargets(*this->BuildFileStream);
|
||||||
|
|
||||||
|
@ -848,6 +849,18 @@ std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
|
||||||
return convPath;
|
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(
|
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
|
||||||
const std::string &commandLine,
|
const std::string &commandLine,
|
||||||
const std::string &sourceFile)
|
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)
|
void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
|
||||||
{
|
{
|
||||||
if (!this->ComputingUnknownDependencies)
|
if (!this->ComputingUnknownDependencies)
|
||||||
|
|
|
@ -228,6 +228,8 @@ public:
|
||||||
return this->RulesFileStream; }
|
return this->RulesFileStream; }
|
||||||
|
|
||||||
std::string ConvertToNinjaPath(const std::string& path);
|
std::string ConvertToNinjaPath(const std::string& path);
|
||||||
|
std::string ConvertToNinjaFolderRule(const std::string& path);
|
||||||
|
|
||||||
|
|
||||||
struct MapToNinjaPathImpl {
|
struct MapToNinjaPathImpl {
|
||||||
cmGlobalNinjaGenerator* GG;
|
cmGlobalNinjaGenerator* GG;
|
||||||
|
@ -342,6 +344,7 @@ private:
|
||||||
void WriteAssumedSourceDependencies();
|
void WriteAssumedSourceDependencies();
|
||||||
|
|
||||||
void WriteTargetAliases(std::ostream& os);
|
void WriteTargetAliases(std::ostream& os);
|
||||||
|
void WriteFolderTargets(std::ostream& os);
|
||||||
void WriteUnknownExplicitDependencies(std::ostream& os);
|
void WriteUnknownExplicitDependencies(std::ostream& os);
|
||||||
|
|
||||||
void WriteBuiltinTargets(std::ostream& os);
|
void WriteBuiltinTargets(std::ostream& os);
|
||||||
|
|
|
@ -16,3 +16,19 @@ run_CMP0058(WARN-no)
|
||||||
run_CMP0058(WARN-by)
|
run_CMP0058(WARN-by)
|
||||||
run_CMP0058(NEW-no)
|
run_CMP0058(NEW-no)
|
||||||
run_CMP0058(NEW-by)
|
run_CMP0058(NEW-by)
|
||||||
|
|
||||||
|
function(run_SubDir)
|
||||||
|
# Use a single build tree for a few tests without cleaning.
|
||||||
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SubDir-build)
|
||||||
|
set(RunCMake_TEST_NO_CLEAN 1)
|
||||||
|
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||||
|
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||||
|
run_cmake(SubDir)
|
||||||
|
if(WIN32)
|
||||||
|
set(SubDir_all [[SubDir\all]])
|
||||||
|
else()
|
||||||
|
set(SubDir_all [[SubDir/all]])
|
||||||
|
endif()
|
||||||
|
run_cmake_command(SubDir-build ${CMAKE_COMMAND} --build . --target ${SubDir_all})
|
||||||
|
endfunction()
|
||||||
|
run_SubDir()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Building InAll
|
|
@ -0,0 +1,2 @@
|
||||||
|
add_subdirectory(SubDir)
|
||||||
|
add_custom_target(TopFail ALL COMMAND does_not_exist)
|
|
@ -0,0 +1,2 @@
|
||||||
|
add_custom_target(SubFail COMMAND does_not_exist)
|
||||||
|
add_custom_target(InAll ALL COMMAND ${CMAKE_COMMAND} -E echo "Building InAll")
|
Loading…
Reference in New Issue