CMake / Ninja dependency tracking broken
Hello,
I stumbled upon the bug while looking for the reason of a complete rebuild for a ninja install after a successful ninja build. The added Ninja arguments -nd explain brought up some clues:
[2021-01-20T15:54:45.259Z] ninja: Entering directory `C:/c/ws/9u79z9j/_build'
[2021-01-20T15:54:45.259Z] ninja explain: output ../../6278eg5/modules/asyncly/Include/asyncly/executor/CurrentExecutor.h of phony edge with no inputs doesn't exist
[2021-01-20T15:54:45.259Z] ninja explain: output ../../11d131w/modules/asyncly/Include/asyncly/ExecutorTypes.h of phony edge with no inputs doesn't exist
[2021-01-20T15:54:45.259Z] ninja explain: output ../../11d131w/modules/asyncly/Include/asyncly/executor/AsioExecutorController.h of phony edge with no inputs doesn't exist
Here 9u79z9j, 6278eg5, and 11d131w are workspace directories. So somehow Ninja expects some headers in the wrong workspace to be present. Reading through the CMake source it became clear what happens:
- The CMake Ninja Generator adds the
/showIncludestocl.exeinvocations. - This output is converted by a CMake helper to a GCC compatible dependency info file
- That dependency file is fed into the ninja dependency database
So right now the cached compiler output presented at a cache hit shows the wrong files:
D:\Git\Experimental\buildcache-includes\aaa>D:\bin\buildcache.exe cl /c foo.cpp /Fo:foo.obj /showIncludes /nologo
foo.cpp
Note: including file: D:\Git\Experimental\buildcache-includes\aaa\foo.h
D:\Git\Experimental\buildcache-includes\aaa>cd ..\bbb
D:\Git\Experimental\buildcache-includes\bbb>D:\bin\buildcache.exe cl /c foo.cpp /Fo:foo.obj /showIncludes /nologo
foo.cpp
Note: including file: D:\Git\Experimental\buildcache-includes\aaa\foo.h
Here in the second run a buildcache hit presents the wrong include paths and things start going wrong.'
To fix the issue buildcache needs some form of ccache's base_dir which rewrites paths.
Thanks, Gregor
Does this happen when BUILDCACHE_ACCURACY=STRICT?
(Quick train out thought...) I guess we could:
- Detect the presence of
/showIncludesand force the use of full path names in the preprocessor output in that case (should solve the bug, but would reduce the number of cache hits). - Look into a BASE_DIR solution to increase the number of cache hits (when paths have changed).
Thoughts?