Ninja: Always re-run custom commands that have symbolic dependencies
If a custom command has a SYMBOLIC output (that is never actually created) then do not mark the custom command build statement as 'restat'. Otherwise other custom commands that depend on the symbolic output may not always re-run because after running the first custom command Ninja 'restat' will detect that the output timestamp did not change and skip its dependents. This was observed with the ExternalProject BUILD_ALWAYS option where Ninja would not re-run the 'install' step each time 'build' re-runs.
This commit is contained in:
parent
7d64a0598d
commit
3477b26ff6
|
@ -398,6 +398,16 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
||||||
const std::vector<std::string> &byproducts = ccg.GetByproducts();
|
const std::vector<std::string> &byproducts = ccg.GetByproducts();
|
||||||
cmNinjaDeps ninjaOutputs(outputs.size()+byproducts.size()), ninjaDeps;
|
cmNinjaDeps ninjaOutputs(outputs.size()+byproducts.size()), ninjaDeps;
|
||||||
|
|
||||||
|
bool symbolic = false;
|
||||||
|
for (std::vector<std::string>::const_iterator o = outputs.begin();
|
||||||
|
o != outputs.end(); ++o)
|
||||||
|
{
|
||||||
|
if (cmSourceFile* sf = this->Makefile->GetSource(*o))
|
||||||
|
{
|
||||||
|
symbolic = sf->GetPropertyAsBool("SYMBOLIC");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#error TODO: Once CC in an ExternalProject target must provide the \
|
#error TODO: Once CC in an ExternalProject target must provide the \
|
||||||
file of each imported target that has an add_dependencies pointing \
|
file of each imported target that has an add_dependencies pointing \
|
||||||
|
@ -434,7 +444,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
||||||
this->ConstructComment(ccg),
|
this->ConstructComment(ccg),
|
||||||
"Custom command for " + ninjaOutputs[0],
|
"Custom command for " + ninjaOutputs[0],
|
||||||
cc->GetUsesTerminal(),
|
cc->GetUsesTerminal(),
|
||||||
/*restat*/true,
|
/*restat*/!symbolic,
|
||||||
ninjaOutputs,
|
ninjaOutputs,
|
||||||
ninjaDeps,
|
ninjaDeps,
|
||||||
orderOnlyDeps);
|
orderOnlyDeps);
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/before-always
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch before-always
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/always
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch always-updated
|
||||||
|
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/before-always
|
||||||
|
)
|
||||||
|
set_property(SOURCE always PROPERTY SYMBOLIC 1)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/after-always
|
||||||
|
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/always
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch after-always
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(drive ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/after-always)
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
|
||||||
|
set(check_pairs
|
||||||
|
\"${CMAKE_CURRENT_BINARY_DIR}/always-updated|${CMAKE_CURRENT_BINARY_DIR}/before-always\"
|
||||||
|
\"${CMAKE_CURRENT_BINARY_DIR}/after-always|${CMAKE_CURRENT_BINARY_DIR}/always-updated\"
|
||||||
|
)
|
||||||
|
")
|
|
@ -38,3 +38,5 @@ if(NOT RunCMake_GENERATOR MATCHES "Visual Studio [67]|Xcode")
|
||||||
run_BuildDepends(C-Exe-Manifest)
|
run_BuildDepends(C-Exe-Manifest)
|
||||||
unset(run_BuildDepends_skip_step_2)
|
unset(run_BuildDepends_skip_step_2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
run_BuildDepends(Custom-Always)
|
||||||
|
|
Loading…
Reference in New Issue