[cmake-developers] ninja enforces explicit dependencies before order-only
Matthew Woehlke
matthew.woehlke at kitware.com
Tue Apr 2 11:35:57 EDT 2013
On 2013-04-02 09:19, Brad King wrote:
> Hi Peter,
>
> We've come across a case where the Makefile, VS, and Xcode generators
> work but Ninja does not::
>
> cmake_minimum_required(VERSION 2.8.10)
> project(DependSideEffect C)
> add_library(A a.c)
> add_custom_command(
> TARGET A POST_BUILD
> COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/a.c a.txt
> )
> add_custom_command(
> OUTPUT b.txt
> DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/a.txt
> COMMAND cp a.txt b.txt
> )
> add_custom_target(B ALL DEPENDS b.txt)
> add_dependencies(B A)
>
> CMake's rule for target-level dependencies is that "A" must be up to
> date before the build system evaluates the rules of "B".
>
> Building with Ninja fails with::
>
> ninja: error: 'a.txt', needed by 'b.txt', missing and no known rule to make it
>
> Relevant portions of build.ninja::
>
> build libA.a: C_STATIC_LIBRARY_LINKER CMakeFiles/A.dir/a.c.o
> POST_BUILD = cd ".../build" && cp .../a.c a.txt
> ...
> build b.txt: CUSTOM_COMMAND a.txt || libA.a
> COMMAND = cd ".../build" && cp a.txt b.txt
> ...
>
> The rule for "b.txt" has an order-only dependency on "libA.a" and
> an explicit dependency on "a.txt". Ninja does not wait for the
> order-only dependencies to be up to date before complaining that
> the explicit dependency is missing.
>
> Can ninja be taught to wait for order-only dependencies to be up to
> date to see if they produce any of the explicit dependencies as
> a side effect? Is there another way to do this in CMake's Ninja gen?
Why are the rules set up like this and not such that b.txt depends on A?
I'm not convinced this is a bug; In the absence of a custom command
having an 'OUTPUT a.txt', there is no expression that the custom command
for b.txt depends on any build rule. IMHO what ninja is doing is
perfectly justifiable behavior for the build rules given above.
If I were to hand-write a Makefile from the above, I would come up with
something like:
a.o: a.c
<compile...>
A: a.o
<link...>
cp a.c ${build}/b.txt
b.txt: ${build}/a.txt
cp a.txt b.txt
B: A b.txt
Note that there is nothing in the dependency graph of the above which
requires that the build system must build A before b.txt.
--
Matthew
More information about the cmake-developers
mailing list