ninja object compilation with custom command not decoupled from target's dependencies' link steps
From the cmake 3.9 release notes:
The Ninja generator has loosened the dependencies of object compilation. Object compilation now depends only on custom targets and custom commands associated with libraries on which the object’s target depends and no longer depends on the libraries themselves. Source files in dependent targets may now compile without waiting for their targets’ dependencies to link.
I was testing this recently and ran across some behavior I can't quite explain, and I believe is a bug in the way the ninja generator is able to decouple object file dependencies from the link steps of its target's dependencies. Let me demonstrate:
project(test C)
add_library(LibA SHARED a.c)
add_custom_command(
OUTPUT output.c
COMMAND cmake -E echo "void a() {}" > output.c
VERBATIM
)
add_library(LibCustom SHARED custom.c output.c)
target_link_libraries(LibCustom LibA)
With the above cmake file, ninja generates a build file where custom.c
and output.c
both require LibA
having been fully built and linked before the custom command is run and the file is built. I would expect that LibCustom
's object files would only need the custom command to run and not for LibA
to be fully built and linked first.
In fact, this is exactly what ninja generates if the following is added to the above file:
add_custom_target(codegen
DEPENDS output.c
)
When the custom target is added, the dependencies for the object file are properly decoupled, even though nothing directly uses this target at all. I am unable to explain why adding this custom target causes the desired behavior, but was hoping I could either figure out why I'm wrong or bring this to your attention.