[CMake] Adding non-file dependencies to a custom target

Giampiero Salvi giampi at kth.se
Tue Oct 21 16:28:33 EDT 2008


Alexander Neundorf wrote:
> On Tuesday 21 October 2008, Giampiero Salvi wrote:
>> Alexander Neundorf wrote:
> ...
>>> Doesn't the custom target foo create some file ?
>> In reality the foo target (or rather targets because I have many like
>> that) crates many files that the "real" bar2 target wraps into one
>> executable using tclkit and sdx (http://www.equi4.com/starkit/sdx.html).
>> For each foo target there is usually a library (.so or .dll) and a
>> number of tcl files. 
> 
> If you can make the add_custom_command() depend on the library target this 
> should work. If the library is rebuilt, the add_custom_command() should run 
> again.
> 
> Alternatively, could you make the add_custom_command() depend on a file like 
> foo_dummy, which is generated every time the custom target is built just for 
> the purpose that the add_custom_command can depend on it ?

I think I start to understand, sorry if I'm slow: in my previous 
example, the custom target bar2 *is* actually rebuilt when the target 
foo changes, but the file ${CMAKE_SOURCE_DIR}/bar2.txt is not 
regenerated because it is only another dependency of the target bar2, in 
other words, the dependency goes the wrong way.

The reason why I find this confusing is that there seems to be a slight 
inconsistency between targets generated by ADD_LIBRARY/ADD_EXECUTABLE 
and by ADD_CUSTOM_TARGET. For example it seems to me that with:

ADD_LIBRARY(boo SHARED boo-1.c boo-2.c boo-3.c ...)

the non-file target "boo" and the file target, say "lib/boo.so", 
generated by it are equivalent, in the sense that, if I add a dependency 
to boo with
ADD_DEPENDENCY(boo foo)
every time foo is rebuilt, the boo target will be rebuilt and therefore 
the lib/boo.so file regenerated.

This doesn't seem to be possible with ADD_CUSTOM_TARGET. In fact the 
only way to create a target that is only built when necessary is to 
create a custom command and then a target dependent on the command's 
output like this:

ADD_CUSTOM_COMMAND(
    OUTPUT boo.someextension
    COMMAND somecommand
)
ADD_CUSTOM_TARGET(boo DEPENDS boo.someextension)

But if I add a dependency between boo and foo, I fall in the same 
mistake as in the beginning, while there is no elegant way, as far as I 
understand, to add a dependency between boo.someextension and foo.

Now the question is: is there a reason why I can only assign *file* 
dependencies to a custom command? Allowing non-file dependencies would, 
in my opinion, make the use of ADD_LIBRARY/ADD_EXECUTABLE and 
ADD_CUSTOM_COMMAND/ADD_CUSTOM_TARGET more consistent.

In my case, if it was possible to write something like

ADD_CUSTOM_COMMAND(
    OUTPUT ${CMAKE_SOURCE_DIR}/bar2.txt
    COMMAND echo bar2 > ${CMAKE_SOURCE_DIR}/bar2.txt
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    DEPENDS foo
)

That would solve my problem in a much more elegant way than either 
generating a dummy file or collecting a list of files that foo generates 
into a variable that I have to put into the cache to be visible to the 
main CMakeLists.txt...

Thanks again for you patience.
Giampiero


More information about the CMake mailing list