Ninja: Add `$subdir/{test,install,package}` targets
With the Makefile generator one can use `cd $subdir; make install` to build and install 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/install` at the top of the tree to build the targets in the corresponding subdirectory and install them. This also makes sense for `test`, `package`, and other GLOBAL_TARGET targets. It was already done for `all` by commit v3.6.0-rc1~240^2~2 (Ninja: Add `$subdir/all` targets, 2016-03-11).
This commit is contained in:
parent
a88c99f1bc
commit
0278989405
|
@ -7,6 +7,17 @@ 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
|
For each subdirectory ``sub/dir`` of the project, additional targets
|
||||||
named ``sub/dir/all`` is generated that depends on all targets required
|
are generated:
|
||||||
by that subdirectory.
|
|
||||||
|
``sub/dir/all``
|
||||||
|
Depends on all targets required by the subdirectory.
|
||||||
|
|
||||||
|
``sub/dir/install``
|
||||||
|
Runs the install step in the subdirectory, if any.
|
||||||
|
|
||||||
|
``sub/dir/test``
|
||||||
|
Runs the test step in the subdirectory, if any.
|
||||||
|
|
||||||
|
``sub/dir/package``
|
||||||
|
Runs the package step in the subdirectory, if any.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
ninja-directory-targets
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* The :generator:`Ninja` generator learned to produce phony targets
|
||||||
|
of the form ``sub/dir/{test,install,package}`` to drive the build
|
||||||
|
of a subdirectory installation, test or packaging target.
|
||||||
|
This is equivalent to ``cd sub/dir; make {test,install,package}``
|
||||||
|
with :ref:`Makefile Generators`.
|
|
@ -885,10 +885,15 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
|
||||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs)
|
cmGeneratorTarget const* target, cmNinjaDeps& outputs)
|
||||||
{
|
{
|
||||||
if (target->GetType() == cmState::GLOBAL_TARGET) {
|
if (target->GetType() == cmState::GLOBAL_TARGET) {
|
||||||
// Global targets only depend on other utilities, which may not appear in
|
// These depend only on other CMake-provided targets, e.g. "all".
|
||||||
// the TargetDepends set (e.g. "all").
|
|
||||||
std::set<std::string> const& utils = target->GetUtilities();
|
std::set<std::string> const& utils = target->GetUtilities();
|
||||||
std::copy(utils.begin(), utils.end(), std::back_inserter(outputs));
|
for (std::set<std::string>::const_iterator i = utils.begin();
|
||||||
|
i != utils.end(); ++i) {
|
||||||
|
std::string d =
|
||||||
|
target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
|
||||||
|
std::string("/") + *i;
|
||||||
|
outputs.push_back(this->ConvertToNinjaPath(d));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cmNinjaDeps outs;
|
cmNinjaDeps outs;
|
||||||
cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(target);
|
cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(target);
|
||||||
|
|
|
@ -38,19 +38,8 @@ cmNinjaTargetGenerator* cmNinjaTargetGenerator::New(cmGeneratorTarget* target)
|
||||||
return new cmNinjaNormalTargetGenerator(target);
|
return new cmNinjaNormalTargetGenerator(target);
|
||||||
|
|
||||||
case cmState::UTILITY:
|
case cmState::UTILITY:
|
||||||
|
case cmState::GLOBAL_TARGET:
|
||||||
return new cmNinjaUtilityTargetGenerator(target);
|
return new cmNinjaUtilityTargetGenerator(target);
|
||||||
;
|
|
||||||
|
|
||||||
case cmState::GLOBAL_TARGET: {
|
|
||||||
// We only want to process global targets that live in the home
|
|
||||||
// (i.e. top-level) directory. CMake creates copies of these targets
|
|
||||||
// in every directory, which we don't need.
|
|
||||||
if (strcmp(target->GetLocalGenerator()->GetCurrentSourceDirectory(),
|
|
||||||
target->GetLocalGenerator()->GetSourceDirectory()) == 0) {
|
|
||||||
return new cmNinjaUtilityTargetGenerator(target);
|
|
||||||
}
|
|
||||||
// else fallthrough
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CM_NULLPTR;
|
return CM_NULLPTR;
|
||||||
|
|
|
@ -31,10 +31,12 @@ cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator()
|
||||||
|
|
||||||
void cmNinjaUtilityTargetGenerator::Generate()
|
void cmNinjaUtilityTargetGenerator::Generate()
|
||||||
{
|
{
|
||||||
std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
|
std::string utilCommandName =
|
||||||
|
this->GetLocalGenerator()->GetCurrentBinaryDirectory();
|
||||||
|
utilCommandName += cmake::GetCMakeFilesDirectory();
|
||||||
|
utilCommandName += "/";
|
||||||
utilCommandName += this->GetTargetName() + ".util";
|
utilCommandName += this->GetTargetName() + ".util";
|
||||||
utilCommandName =
|
utilCommandName = this->ConvertToNinjaPath(utilCommandName);
|
||||||
this->GetGlobalGenerator()->NinjaOutputPath(utilCommandName);
|
|
||||||
|
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName);
|
cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName);
|
||||||
|
@ -144,6 +146,11 @@ void cmNinjaUtilityTargetGenerator::Generate()
|
||||||
cmNinjaDeps(1, utilCommandName));
|
cmNinjaDeps(1, utilCommandName));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
|
// Add an alias for the logical target name regardless of what directory
|
||||||
this->GetGeneratorTarget());
|
// contains it. Skip this for GLOBAL_TARGET because they are meant to
|
||||||
|
// be per-directory and have one at the top-level anyway.
|
||||||
|
if (this->GetGeneratorTarget()->GetType() != cmState::GLOBAL_TARGET) {
|
||||||
|
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
|
||||||
|
this->GetGeneratorTarget());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,16 @@ function(run_SubDir)
|
||||||
run_cmake(SubDir)
|
run_cmake(SubDir)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(SubDir_all [[SubDir\all]])
|
set(SubDir_all [[SubDir\all]])
|
||||||
|
set(SubDir_test [[SubDir\test]])
|
||||||
|
set(SubDir_install [[SubDir\install]])
|
||||||
else()
|
else()
|
||||||
set(SubDir_all [[SubDir/all]])
|
set(SubDir_all [[SubDir/all]])
|
||||||
|
set(SubDir_test [[SubDir/test]])
|
||||||
|
set(SubDir_install [[SubDir/install]])
|
||||||
endif()
|
endif()
|
||||||
run_cmake_command(SubDir-build ${CMAKE_COMMAND} --build . --target ${SubDir_all})
|
run_cmake_command(SubDir-build ${CMAKE_COMMAND} --build . --target ${SubDir_all})
|
||||||
|
run_cmake_command(SubDir-test ${CMAKE_COMMAND} --build . --target ${SubDir_test})
|
||||||
|
run_cmake_command(SubDir-install ${CMAKE_COMMAND} --build . --target ${SubDir_install})
|
||||||
endfunction()
|
endfunction()
|
||||||
run_SubDir()
|
run_SubDir()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
-- Installing SubDir
|
|
@ -0,0 +1 @@
|
||||||
|
1/1 Test #1: SubDirTest
|
|
@ -1,2 +1,7 @@
|
||||||
|
include(CTest)
|
||||||
add_subdirectory(SubDir)
|
add_subdirectory(SubDir)
|
||||||
add_custom_target(TopFail ALL COMMAND does_not_exist)
|
add_custom_target(TopFail ALL COMMAND does_not_exist)
|
||||||
|
add_test(NAME TopTest COMMAND ${CMAKE_COMMAND} -E echo "Running TopTest")
|
||||||
|
install(CODE [[
|
||||||
|
message(FATAL_ERROR "Installing Top")
|
||||||
|
]])
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
add_custom_target(SubFail COMMAND does_not_exist)
|
add_custom_target(SubFail COMMAND does_not_exist)
|
||||||
add_custom_target(InAll ALL COMMAND ${CMAKE_COMMAND} -E echo "Building InAll")
|
add_custom_target(InAll ALL COMMAND ${CMAKE_COMMAND} -E echo "Building InAll")
|
||||||
|
add_test(NAME SubDirTest COMMAND ${CMAKE_COMMAND} -E echo "Running SubDirTest")
|
||||||
|
install(CODE [[
|
||||||
|
message(STATUS "Installing SubDir")
|
||||||
|
]])
|
||||||
|
|
Loading…
Reference in New Issue