MantisBT - CMake
View Issue Details
0014747CMakeCMakepublic2014-02-10 13:112015-01-05 08:39
Daniel Levin 
 
highmajoralways
closedduplicate 
CMake 2.8.12.2 
 
0014747: Target dependencies do not trigget build on Ninja
Target dependencies output do not trigger build of target itself using Ninja generator. See attached archive for example.

Imaging next script:

add_custom_target(A DEPENDS somefile)
add_dependencies(A B)

Expected behavior: dependency checking of target A should be triggered AFTER target B was built. If file 'somefile' depends on output of target B, build of target A should be started. Works using make generator, does not work using ninja generator.
Create make build for attached project. Run make from command line continuously. If RandomTouch target has output (random=1) it does trigger Test target build, as expected. If RandomTouch target has no output (random=0) Test target not built, as expected.

Create ninja build and do the same. Test target build is running depending on PREVIOUS invocation of ninja command, not CURRENT. Because dependency scan of target Test is done before RandomTouch target finished running and make any output.
No tags attached.
related to 0014728closed Ben Boeckel [CMake/Ninja] add_dependencies() to objlib's user is ignored. 
related to 0014963closed Brad King Add explicit specification of custom command side effect outputs 
related to 0014771closed Kitware Robot Ninja generator does not always honor SYMBOLIC rules with no command 
tgz cmake-pre-build.tgz (10,240) 2014-02-10 13:11
https://public.kitware.com/Bug/file/5069/cmake-pre-build.tgz
Issue History
2014-02-10 13:11Daniel LevinNew Issue
2014-02-10 13:11Daniel LevinFile Added: cmake-pre-build.tgz
2014-02-10 13:40Brad KingRelationship addedrelated to 0014728
2014-02-10 13:41Brad KingNote Added: 0035085
2014-02-10 14:08Daniel LevinNote Added: 0035087
2014-02-10 14:18Brad KingNote Added: 0035088
2014-02-25 09:50Brad KingRelationship addedrelated to 0014771
2014-05-05 18:15Ben BoeckelNote Added: 0035819
2014-05-05 18:37Ben BoeckelNote Added: 0035821
2014-05-06 16:00Ben BoeckelNote Added: 0035830
2014-05-06 16:00Ben BoeckelAssigned To => Ben Boeckel
2014-05-06 16:00Ben BoeckelStatusnew => assigned
2014-06-11 08:35Brad KingRelationship addedrelated to 0014963
2014-07-01 09:32Brad KingNote Added: 0036295
2014-07-01 09:32Brad KingAssigned ToBen Boeckel =>
2014-07-01 09:32Brad KingStatusassigned => resolved
2014-07-01 09:32Brad KingResolutionopen => duplicate
2015-01-05 08:39Robert MaynardNote Added: 0037576
2015-01-05 08:39Robert MaynardStatusresolved => closed

Notes
(0035085)
Brad King   
2014-02-10 13:41   
This looks similar to issue 0014728 where the inter-target ordering dependencies, which are implemented on individual rules of each target, are perhaps missing from some of the individual rules.
(0035087)
Daniel Levin   
2014-02-10 14:08   
In my case dependency is there and always running normally before target. But resulting output from that dependency has no influence on target command itself, as it expected to be.

I would want to understand whether make generator behavior is actually correct and ninja generator behavior should replicate it.

It not what is the correct way to implement prebuild step that must be run always before target, affecting target DAC? Typical scenario: I want to create custom dependency check as a prebuild step.
(0035088)
Brad King   
2014-02-10 14:18   
Re 0014747:0035087: Your expectation and the Makefile generator behavior are correct. CMake intends to bring all rules in a given logical target up to date before considering any rules in dependent logical targets. This is a bug in the Ninja generator.
(0035819)
Ben Boeckel   
2014-05-05 18:15   
Hmm. I tried poking this and even poking the build.ninja by hand I was unable to get Ninja to Do The Right Thing(TM).

It looks like the problem is that the add_custom_target isn't declaring that the file "foo" is an output file and so marks it as phony. I don't know why Make is working in this case since it has no rule to build "foo" in the generated files. Can anyone confirm that it works with non-GNU make?

I was able to get things to work with:

add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/foo" "${CMAKE_CURRENT_BINARY_DIR}/foo.noexist"
        COMMAND echo "touching..."
        COMMAND ${CMAKE_COMMAND} -D FILE="${CMAKE_CURRENT_BINARY_DIR}/foo" -P "${CMAKE_CURRENT_SOURCE_DIR}/random-touch.cmake"
        COMMAND echo "touching... DONE"
)
add_custom_target(RandomTouch
        DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/foo"
)

The problem now is that Make *always* rebuilds bar because it doesn't check whether foo was actually modified or not as a part of the custom command.

I think this is probably hitting the corner where CMake has no concept of a custom_command which is both a part of a target *and* generates output and Ninja and Make just have different ways of interpreting dangling rules. So CMake *can* do this, but it probably needs something like:

add_custom_target(RandomTouch COMMAND ... OUTPUT foo)

or

add_custom_target(RandomTouch)
add_custom_command(OUTPUT foo TARGET RandomTouch COMMAND ...)
(0035821)
Ben Boeckel   
2014-05-05 18:37   
I ran it with bmake (NetBSD's make) and the attached tarball worked, so it's not just GNU make that works.
(0035830)
Ben Boeckel   
2014-05-06 16:00   
Since I can't get Ninja to do the right thing even with a hand-written build.ninja file, I've opened a bug against ninja: <https://github.com/martine/ninja/issues/760>. [^]
(0036295)
Brad King   
2014-07-01 09:32   
I'm resolving this as a duplicate of issue 0014963 which describes the larger problem. Either 0014963 needs to be resolved on the CMake side, or the Ninja issue linked in 0014747:0035830 needs to be resolved on the Ninja side. That will resolve this issue.
(0037576)
Robert Maynard   
2015-01-05 08:39   
Closing resolved issues that have not been updated in more than 4 months