[CMake] Output of ADD_CUSTOM_COMMAND generated multiple times
Brad King
brad.king at kitware.com
Wed Oct 8 08:47:44 EDT 2008
Martin Apel wrote:
> Alan W. Irwin wrote:
>> On 2008-10-07 16:09-0400 Brad King wrote:
>>
>>> Now targets b and c and build in parallel, but neither will build until
>>> 'a' is generated.
>> Thanks, Brad, for your further explanation and example. My method
>> (which I
>> started to use as a result of misinterpreting something you said on this
>> topic before) appears to work, but yours is certainly more logical and
>> will
>> most likely result in faster parallel builds (because of the
>> serialization
>> used by my method). If your example isn't in the wiki, it should be.
>
> The only unfortunate side effect of this approach of defining a separate
> target for each custom command is that
> I start drowning in the make output "Build target x", because I have
> lots of these dependencies.
We've built huge projects with thousands of custom build rules while
still only having a few custom targets. Your original example can be
written like this:
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_BINARY_DIR}/a
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/a
)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_BINARY_DIR}/b
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/b
DEPENDS ${CMAKE_BINARY_DIR}/a
)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_BINARY_DIR}/c
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/c
DEPENDS ${CMAKE_BINARY_DIR}/a
)
ADD_CUSTOM_TARGET(world
DEPENDS ${CMAKE_BINARY_DIR}/b ${CMAKE_BINARY_DIR}/c
)
Now the 'world' target contains all the rules and will build 'a' first,
then 'b' and 'c' in parallel.
> I think CMake should be smart enough to handle this without the extra
> targets, at least as long as all of them are in
> the same directory. That is what the "generated" attribute of a source
> file is about, isn't it.
> But for now, I will modify my CMakeLists.txt to contain the extra targets.
There is a feature request here:
http://www.cmake.org/Bug/view.php?id=6285
However, the solution I have in mind for it will still not handle your
case. You're basically telling two different targets how to build a
file, and not adding any other dependencies to control the order.
Each target gets built with its own make process. It is at this stage
that file-level dependencies are evaluated by the build system. A
higher-level make process considers only inter-target dependencies with
symbolic (phony) targets.
-Brad
More information about the CMake
mailing list