summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-11-19 20:13:11 (GMT)
committerBrad King <brad.king@kitware.com>2015-11-19 20:47:41 (GMT)
commit3477b26ff6c455b64421bf19000d7203acdd6024 (patch)
tree91bcf0bb910e3cf1621481b5d88e20db13c8d1d1
parent7d64a0598db5da2c4c1874f9fe8726fd6c9b18a7 (diff)
downloadCMake-3477b26ff6c455b64421bf19000d7203acdd6024.zip
CMake-3477b26ff6c455b64421bf19000d7203acdd6024.tar.gz
CMake-3477b26ff6c455b64421bf19000d7203acdd6024.tar.bz2
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.
-rw-r--r--Source/cmLocalNinjaGenerator.cxx12
-rw-r--r--Tests/RunCMake/BuildDepends/Custom-Always.cmake24
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake2
3 files changed, 37 insertions, 1 deletions
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index d9517d8..b2927a9 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -398,6 +398,16 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
const std::vector<std::string> &byproducts = ccg.GetByproducts();
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
#error TODO: Once CC in an ExternalProject target must provide the \
file of each imported target that has an add_dependencies pointing \
@@ -434,7 +444,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
this->ConstructComment(ccg),
"Custom command for " + ninjaOutputs[0],
cc->GetUsesTerminal(),
- /*restat*/true,
+ /*restat*/!symbolic,
ninjaOutputs,
ninjaDeps,
orderOnlyDeps);
diff --git a/Tests/RunCMake/BuildDepends/Custom-Always.cmake b/Tests/RunCMake/BuildDepends/Custom-Always.cmake
new file mode 100644
index 0000000..d412708
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/Custom-Always.cmake
@@ -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\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index a578408..31c72fb 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -38,3 +38,5 @@ if(NOT RunCMake_GENERATOR MATCHES "Visual Studio [67]|Xcode")
run_BuildDepends(C-Exe-Manifest)
unset(run_BuildDepends_skip_step_2)
endif()
+
+run_BuildDepends(Custom-Always)