<div dir="ltr">Hi, Esben.<br>Thank you very much for helpful pointers.<br><br>>> project(FOO)<br>>> add_custom_target(generate ALL DEPENDS ${FOO_BINARY_DIR}/generated.h)<br>>> add_custom_command(OUTPUT ${FOO_BINARY_DIR}/generated.h COMMAND ...)<br>
>> include_directories(${FOO_BINARY_DIR})<br>>> add_library(foo foo.c) # foo.c includes generated.h<br>>> add_library(bar bar.c) # bar.c includes generated.h as well<br>>><br>>> Finally, how do I control targets ordering during build? I have<br>
>> 'generate' target that generates 'generated.h'.<br>>> I have 'foo' and 'bar' targets that use 'generated.h'. How can I force<br>>> 'generate' to be build before 'foo' and 'bar'?<br>
><br>> That is what dependency tracking is for. And that should be handled<br>> automatically by the add_custom_target.<br><br>My experience contradicts your statement. <br>For instance if I remove 'ALL' token from my ADD_CUSTOM_TARGET, <br>
'generate' target is not built at all. If I move 'generate' target declaration<br>below 'foo' and 'bar', CMake attempts to build targets in wrong order:<br>(1)foo, (2)bar, (3)generate.<br><br>
Is dependencies tracking actually two level - <br>(1)file-level dependencies, and<br>(2)target-level dependencies?<br><br>I mean, within a target file-to-file dependencies are tracked. If any file<br>is updated, everything depending on that file within the target is rebuilt. <br>
Compiler, linker or random utility hooked in by ADD_CUSTOM_COMMAND<br>runs.<br><br>Additionally there are target-to-target dependencies. Some targets get<br>the timestamp from associated output file (like ADD_LIBRARY or<br>
ADD_EXECUTABLE does). Other ones (like ADD_CUSTOM_TARGET)<br>are always considered out of date. Inter-target dependencies are<br>created either explicitly with ADD_DEPENDENCIES or implicitly<br>as side effect of another command like TARGET_LINK_LIBRARIES.<br>
<br>It looks like file-to-file dependencies do not span target boundaries.<br>Consider the following dependency graph:<br><br>random_data -> generated.h -> foo.c<br><br>It appears to me that this graph actually breaks into two parts<br>
without contributing to targets relative ordering:<br><br>generated [random_data -> generated.h]<br>foo [generated.h -> foo.c]<br><br>Please correct my guesswork if I was wrong.<br><br>If formal model behind CMake was written down, and availible<br>
online alongside with already perfect per-command help it will <br>be so nice!<br><br>WBR, Mejedi<br><br>> Date: Mon, 15 Sep 2008 09:15:44 +0200<br>> From: Esben Mose Hansen <<a href="mailto:kde@mosehansen.dk">kde@mosehansen.dk</a>><br>
> Subject: Re: [CMake] Generated source files and dependencies(+)<br>> To: <a href="mailto:cmake@cmake.org">cmake@cmake.org</a><br>> Message-ID: <<a href="mailto:200809150915.45723.kde@mosehansen.dk">200809150915.45723.kde@mosehansen.dk</a>><br>
> Content-Type: text/plain; charset="iso-8859-1"<br>><br>> On Sunday 14 September 2008 15:14:15 ZNV wrote:<br>>> Hi!<br>>><br>>> I am generating header file for subsequent use by multiple<br>
>> libraries/executables in CMake-controlled build.<br>>> My preliminary solution which happens to work is the following; I<br>>> wonder if it is correct.<br>><br>> If you look at my google protocols buffer module (which I submitted a little<br>
> above), it uses the same strategy<br>><br>>><br>>> project(FOO)<br>>> add_custom_target(generate ALL DEPENDS ${FOO_BINARY_DIR}/generated.h)<br>>> add_custom_command(OUTPUT ${FOO_BINARY_DIR}/generated.h COMMAND ...)<br>
>> include_directories(${FOO_BINARY_DIR})<br>>> add_library(foo foo.c) # foo.c includes generated.h<br>>> add_library(bar bar.c) # bar.c includes generated.h as well<br>>><br>>> The first question is, does CMake detect that 'foo' library depends on<br>
>> 'generated.h' automaticly?<br>><br>> Since it includes the generate.h, that should not be a problem.<br>><br>>><br>>> The second question is, when are source/header files dependencies<br>
>> scanned? Does it happen<br>>> during configure stage (ie when CMake runs)? Does it happen during<br>>> build stage (when CMake-<br>>> generated Makefile/whatever runs)?<br>><br>> In big projects, you can actually see CMake writing "scanning dependencies<br>
> for". I think it does it before building each target.<br>><br>>> Anyway, I do not understand, how #include dependencies created by<br>>> generated files are handled.<br>><br>> Same way. The dependencies are scanned before the target that depends on<br>
> generated.h is compiled. It would seem to me that this means scanning the<br>> dependencies for libfoo twice, but I'm no expect in this.<br>><br>>> Assume 'foobar.c' is generated. For sure it includes something. During<br>
>> configure stage there is<br>>> no 'foobar.c'. Do I have to manually enlist 'foobar.c' dependencies<br>>> via OBJECT_DEPENDS property?<br>>> Or may be 'foobar.c' is scanned on build stage, and everything just works<br>
>> fine?<br>><br>> The latter. It works fine with the protocols buffer this way, and also the<br>> FindQt.cmake seems to work like this (that include is somewhat involved,<br>> though)<br>><br>>><br>
>> Finally, how do I control targets ordering during build? I have<br>>> 'generate' target that generates 'generated.h'.<br>>> I have 'foo' and 'bar' targets that use 'generated.h'. How can I force<br>
>> 'generate' to be build before 'foo' and 'bar'?<br>><br>>> Is ADD_DEPENDENCIES the only option? Maybe a clever hack exists to<br>>> built the given target *before* all<br>>> other project's targets?<br>
><br>> That is what dependency tracking is for. And that should be handled<br>> automatically by the add_custom_target.<br>><br>> --<br>> kind regards, Esben<br><br></div>