Ninja: cmake_transform_depfile doesn't account for CMAKE_NINJA_OUTPUT_PATH_PREFIX
The relative paths produced by cmake_transform_depfile
are not prefixed by CMAKE_NINJA_OUTPUT_PATH_PREFIX
when present, causing the outputs using that depfile to be rebuilt on every build.
The following is a (hopefully minimal) example of the behavior. Given this CMakeLists.txt file:
cmake_minimum_required(VERSION 3.20)
project(hello LANGUAGES)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dep.txt "")
file(CONFIGURE OUTPUT hello.txt.d CONTENT [[
${CMAKE_CURRENT_BINARY_DIR}/hello.txt: ${CMAKE_CURRENT_BINARY_DIR}/dep.txt
]])
add_custom_command(
OUTPUT hello.txt
COMMAND ${CMAKE_COMMAND} -E touch hello.txt
COMMAND ${CMAKE_COMMAND} -E touch_nocreate hello.txt.d
DEPFILE hello.txt.d
)
add_custom_target(hello DEPENDS hello.txt)
and this build.ninja file:
subninja b/build.ninja
and a build system generated thusly:
cmake -B b -G Ninja -DCMAKE_NINJA_OUTPUT_PATH_PREFIX=b/
The first build works as expected:
$ ninja -d explain b/hello
ninja explain: depfile '/home/vscode/b/CMakeFiles/d/9191569e8267d24c4fff2748c58b94d12d14abdf677b16d74cfa2a0ce141b9ff.d' is missing
ninja explain: b/hello.txt is dirty
ninja explain: b/CMakeFiles/hello is dirty
ninja explain: b/hello.txt is dirty
[1/1] Generating hello.txt
Here are the contents of the transformed depfile:
hello.txt: \
dep.txt
These paths do not include CMAKE_NINJA_OUTPUT_PATH_PREFIX
and thus ninja gets cranky on subsequent builds:
$ ninja -d explain b/hello
ninja explain: expected depfile '/home/vscode/b/CMakeFiles/d/9191569e8267d24c4fff2748c58b94d12d14abdf677b16d74cfa2a0ce141b9ff.d' to mention 'b/hello.txt', got 'hello.txt'
ninja explain: b/hello.txt is dirty
ninja explain: b/CMakeFiles/hello is dirty
ninja explain: b/hello.txt is dirty
[1/1] Generating hello.txt