buildcache icon indicating copy to clipboard operation
buildcache copied to clipboard

CMake / Ninja dependency tracking broken

Open gjasny opened this issue 4 years ago • 1 comments

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:

  1. The CMake Ninja Generator adds the /showIncludes to cl.exe invocations.
  2. This output is converted by a CMake helper to a GCC compatible dependency info file
  3. 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

gjasny avatar Jan 22 '21 12:01 gjasny

Does this happen when BUILDCACHE_ACCURACY=STRICT?

(Quick train out thought...) I guess we could:

  1. Detect the presence of /showIncludes and 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).
  2. Look into a BASE_DIR solution to increase the number of cache hits (when paths have changed).

Thoughts?

mbitsnbites avatar Jan 23 '21 11:01 mbitsnbites