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:
Brad King 2015-11-19 15:13:11 -05:00
parent 7d64a0598d
commit 3477b26ff6
3 changed files with 37 additions and 1 deletions

View File

@ -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);

View File

@ -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\"
)
")

View File

@ -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)