View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015456CMake(No Category)public2015-03-18 12:382016-06-10 14:31
ReporterDaniel Dunbar 
Assigned ToKitware Robot 
PrioritynormalSeverityminorReproducibilityhave not tried
StatusclosedResolutionmoved 
PlatformOSOS Version
Product VersionCMake 3.2.1 
Target VersionFixed in Version 
Summary0015456: Ninja manifests for try_compile projects should not have RERUN_CMAKE steps
DescriptionThe Ninja manifests that CMake generates as part of its initial configuration (e.g., checking if the C compiler works) include the commands to rerun the generator, even though it would never make sense for the generator to automatically be rerun by Ninja in such a context.

This is wasteful of space/time in the manifest, but it also could be a serious problem if something ever causes Ninja to want to rerun the generator at that point. If it did, it could end up rerunning the same configuration checks (but under CMakeFiles/CMakeTmp), which would then trigger an infinite loop of configuration checks (in ever deepening CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/...).

--

The reason why I noticed this problem is that I was looking at Ninja's behavior w.r.t. skipping rerunning of command when it is newer than the inputs. Ninja will currently skip running a command when the output has the same timestamp as the newest input. On OS X, this is not particularly safe, as the HFS filesystem has a 1s resolution on the mod times, and so it is very easy for the input to be "newer" than (modified after) the output and still not get rebuilt by Ninja. I was curious if changing Ninja to use a strict newer-than check would work.

The way this relates to the aforementioned issue is that the RERUN_CMAKE command in the build.ninja files generated for the configuration checks depend on other .cmake files generated at the same time, and they are very likely to have the same timestamp on OS X. If Ninja did a more strict check here, it would cause it to rerun the generator as part of the configuration commands, and trigger an infinite loop... see steps to reproduce.

It seems like it would be safer and more efficient to avoid generating the RERUN_CMAKE rules into these build.ninja files in the first place.
Steps To ReproduceThere isn't a trivial way to see this problem, but if you build a custom version of Ninja that uses a stricter newer-than check for comparing outputs to inputs using the following patch (against 717619a260633ca0e7c9eb2366130fc06ebacfff):
--
diff --git a/src/graph.cc b/src/graph.cc
index 76c4e9a..4b45015 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -148,7 +148,7 @@ bool DependencyScan::RecomputeOutputDirty(Edge* edge,
   }
 
   // Dirty if the output is older than the input.
- if (most_recent_input && output->mtime() < most_recent_input->mtime()) {
+ if (most_recent_input && output->mtime() <= most_recent_input->mtime()) {
     TimeStamp output_mtime = output->mtime();
 
     // If this is a restat rule, we may have cleaned the output with a restat
@@ -162,7 +162,7 @@ bool DependencyScan::RecomputeOutputDirty(Edge* edge,
       used_restat = true;
     }
 
- if (output_mtime < most_recent_input->mtime()) {
+ if (output_mtime <= most_recent_input->mtime()) {
       EXPLAIN("%soutput %s older than most recent input %s "
               "(%d vs %d)",
               used_restat ? "restat of " : "", output->path().c_str(),
--

then you can reproduce the problem trivially with an empty CMakeLists.txt:

--

$ ls -la CMakeLists.txt
-rw-r--r-- 1 ddunbar staff 35 Mar 18 09:34 CMakeLists.txt
$ cmake -GNinja .
-- The C compiler identification is AppleClang 7.0.0.7000009
-- The CXX compiler identification is AppleClang 7.0.0.7000009
-- Check for working C compiler using: Ninja
  C-c C-c
$ find CMakeFiles | head -50
CMakeFiles
CMakeFiles/3.2.1
CMakeFiles/3.2.1/CMakeCCompiler.cmake
CMakeFiles/3.2.1/CMakeCXXCompiler.cmake
CMakeFiles/3.2.1/CMakeSystem.cmake
CMakeFiles/3.2.1/CompilerIdC
CMakeFiles/3.2.1/CompilerIdC/CMakeCCompilerId.c
CMakeFiles/3.2.1/CompilerIdC/a.out
CMakeFiles/3.2.1/CompilerIdCXX
CMakeFiles/3.2.1/CompilerIdCXX/CMakeCXXCompilerId.cpp
CMakeFiles/3.2.1/CompilerIdCXX/a.out
CMakeFiles/CMakeOutput.log
CMakeFiles/CMakeTmp
CMakeFiles/CMakeTmp/.ninja_deps
CMakeFiles/CMakeTmp/.ninja_log
CMakeFiles/CMakeTmp/CMakeCache.txt
CMakeFiles/CMakeTmp/CMakeFiles
CMakeFiles/CMakeTmp/CMakeFiles/3.2.1
CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CMakeCCompiler.cmake
CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CMakeSystem.cmake
CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC
CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC/CMakeCCompilerId.c
CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC/a.out
CMakeFiles/CMakeTmp/CMakeFiles/CMakeOutput.log
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/.ninja_deps
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/.ninja_log
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeCache.txt
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CMakeCCompiler.cmake
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CMakeSystem.cmake
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC/CMakeCCompilerId.c
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC/a.out
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeOutput.log
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/.ninja_deps
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/.ninja_log
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeCache.txt
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CMakeCCompiler.cmake
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CMakeSystem.cmake
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC/CMakeCCompilerId.c
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/3.2.1/CompilerIdC/a.out
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeOutput.log
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp
CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/CMakeFiles/CMakeTmp/.ninja_deps
$
--
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0038238)
Brad King (manager)
2015-03-18 13:29

Thanks. I revised the description a bit.
(0038239)
Brad King (manager)
2015-03-18 13:35

When try_compile generates a test project it sets CMAKE_SUPPRESS_REGENERATION:

 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmCoreTryCompile.cxx;hb=v3.2.1#l371 [^]

The Ninja generator should be taught to honor this by not adding the RERUN_CMAKE rule.
(0042735)
Kitware Robot (administrator)
2016-06-10 14:29

Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2015-03-18 12:38 Daniel Dunbar New Issue
2015-03-18 13:18 Brad King Summary Ninja manifests generated for CMake configuration steps should probably not have RERUN_CMAKE steps => Ninja manifests for try_compile projects should not have RERUN_CMAKE steps
2015-03-18 13:29 Brad King Note Added: 0038238
2015-03-18 13:35 Brad King Note Added: 0038239
2016-06-10 14:29 Kitware Robot Note Added: 0042735
2016-06-10 14:29 Kitware Robot Status new => resolved
2016-06-10 14:29 Kitware Robot Resolution open => moved
2016-06-10 14:29 Kitware Robot Assigned To => Kitware Robot
2016-06-10 14:31 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team