[CMake] add_custom_target always runs?

Hugo Heden hugoheden at gmail.com
Thu Dec 18 05:39:50 EST 2008


2008/12/16 Tyler Roscoe <tyler at cryptio.net>:
> I am using what I think is a common pattern to create some headers.
> Following the example at
> http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_generate_an_executable.2C_then_use_the_executable_to_generate_a_file.3F,
> I have an add_custom_command which calls a script (generateheader.py):
>
> add_custom_command (
>    DEPENDS generateheader.py
>    OUTPUT  results/header.h
>    COMMAND ${PYTHON_EXECUTABLE}
>    ARGS generateheader.py --infile=src/header.in.h --outfile=results/header.h
> )
>
> And then I have an add_custom_target to wrap the command in a target:
>
> add_custom_target (
>    generateheader ALL
>    DEPENDS results/header.h
> )
>
> This seems to mostly do what it's supposed to do. When I run "make all",
> the generateheader target runs and results/header.h is created. When I
> run "make generateheader", same thing.
>
> So now the problem.
>
> When I do "make all", the generateheader target *always* runs, even if
> results/header.h and generateheader.py are up-to-date.
>
> This is a problem because other targets depend on generateheader, so
> when generateheader runs, all the dependent targets also run. This makes
> it impossible for me to do a delta build.
>
> Some closer reading of the manual suggests that this is by design. From
> http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_custom_target:
>
> "Adds a target with the given name that executes the given commands. The
> target has no output file and is ALWAYS CONSIDERED OUT OF DATE even if
> the commands try to create a file with the name of the target."
>

I just want to clarify that what you have been doing looks correct,
and it should do exactly what you want.

Yes, the target from ADD_CUSTOM_TARGET is always out-of-date so it
will be invoked every time. That means that if you would have a
COMMAND in the target (which you don't), that command would be run
every time, like the command "blablabla" below:

 add_custom_target (
    generateheader ALL
    DEPENDS results/header.h
    COMMAND blablabla
 )


*And* this implies that all dependencies are *checked* as well, like
for example "results/header.h" above, which "connects" to the OUTPUT
of the ADD_CUSTOM_COMMAND:

add_custom_command (
   DEPENDS generateheader.py
   OUTPUT  results/header.h
   COMMAND ${PYTHON_EXECUTABLE}
   ARGS generateheader.py --infile=src/header.in.h --outfile=results/header.h
)


*But* that does not mean that the dependencies needs to be actually
*rebuilt* every time. They shouldn't. So there should be no problem
marking the target with "ALL".

Now, the reason that the dependency in your case is rebuilt every time
is not clear from your post; but do double-check that the DEPENDS of
the target is actually satisfied the second target is invoked -- are
you absolutely sure that "results/header.h" exists (the second time
the target is invoked)? As someone suggested, do try using an absolute
path instead of a relative one, to make any errors easier to spot.

Best regards

Hugo Heden

> Ok, so is it simply impossible to do delta builds if my build process
> needs add_custom_command/add_custom_target invocations? Is there some
> better way to have CMake create the headers for me? Does this behavior
> of add_custom_target only occur when I add a new target dependent on
> ALL?
>
>
> Thanks,
> tyler
> _______________________________________________
> CMake mailing list
> CMake at cmake.org
> http://www.cmake.org/mailman/listinfo/cmake
>


More information about the CMake mailing list