[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