<div dir="ltr">Hi, Esben.<br>Thank you very much for helpful pointers.<br><br>&gt;&gt; project(FOO)<br>&gt;&gt; add_custom_target(generate ALL DEPENDS ${FOO_BINARY_DIR}/generated.h)<br>&gt;&gt; add_custom_command(OUTPUT ${FOO_BINARY_DIR}/generated.h COMMAND ...)<br>
&gt;&gt; include_directories(${FOO_BINARY_DIR})<br>&gt;&gt; add_library(foo foo.c) # foo.c includes generated.h<br>&gt;&gt; add_library(bar bar.c) # bar.c includes generated.h as well<br>&gt;&gt;<br>&gt;&gt; Finally, how do I control targets ordering during build? I have<br>
&gt;&gt; &#39;generate&#39; target that generates &#39;generated.h&#39;.<br>&gt;&gt; I have &#39;foo&#39; and &#39;bar&#39; targets that use &#39;generated.h&#39;. How can I force<br>&gt;&gt; &#39;generate&#39; to be build before &#39;foo&#39; and &#39;bar&#39;?<br>
&gt;<br>&gt; That is what dependency tracking is for. And that should be handled<br>&gt; automatically by the add_custom_target.<br><br>My experience contradicts your statement. <br>For instance if I remove &#39;ALL&#39; token from my ADD_CUSTOM_TARGET, <br>
&#39;generate&#39; target is not built at all. If I move &#39;generate&#39; target declaration<br>below &#39;foo&#39; and &#39;bar&#39;, 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 -&gt; generated.h -&gt; 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 -&gt; generated.h]<br>foo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [generated.h -&gt; 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>&gt; Date: Mon, 15 Sep 2008 09:15:44 +0200<br>&gt; From: Esben Mose Hansen &lt;<a href="mailto:kde@mosehansen.dk">kde@mosehansen.dk</a>&gt;<br>
&gt; Subject: Re: [CMake] Generated source files and dependencies(+)<br>&gt; To: <a href="mailto:cmake@cmake.org">cmake@cmake.org</a><br>&gt; Message-ID: &lt;<a href="mailto:200809150915.45723.kde@mosehansen.dk">200809150915.45723.kde@mosehansen.dk</a>&gt;<br>
&gt; Content-Type: text/plain; &nbsp;charset=&quot;iso-8859-1&quot;<br>&gt;<br>&gt; On Sunday 14 September 2008 15:14:15 ZNV wrote:<br>&gt;&gt; Hi!<br>&gt;&gt;<br>&gt;&gt; I am generating header file for subsequent use by multiple<br>
&gt;&gt; libraries/executables in CMake-controlled build.<br>&gt;&gt; My preliminary solution which happens to work is the following; I<br>&gt;&gt; wonder if it is correct.<br>&gt;<br>&gt; If you look at my google protocols buffer module (which I submitted a little<br>
&gt; above), it uses the same strategy<br>&gt;<br>&gt;&gt;<br>&gt;&gt; project(FOO)<br>&gt;&gt; add_custom_target(generate ALL DEPENDS ${FOO_BINARY_DIR}/generated.h)<br>&gt;&gt; add_custom_command(OUTPUT ${FOO_BINARY_DIR}/generated.h COMMAND ...)<br>
&gt;&gt; include_directories(${FOO_BINARY_DIR})<br>&gt;&gt; add_library(foo foo.c) # foo.c includes generated.h<br>&gt;&gt; add_library(bar bar.c) # bar.c includes generated.h as well<br>&gt;&gt;<br>&gt;&gt; The first question is, does CMake detect that &#39;foo&#39; library depends on<br>
&gt;&gt; &#39;generated.h&#39; automaticly?<br>&gt;<br>&gt; Since it includes the generate.h, that should not be a problem.<br>&gt;<br>&gt;&gt;<br>&gt;&gt; The second question is, when are source/header files dependencies<br>
&gt;&gt; scanned? Does it happen<br>&gt;&gt; during configure stage (ie when CMake runs)? Does it happen during<br>&gt;&gt; build stage (when CMake-<br>&gt;&gt; generated Makefile/whatever runs)?<br>&gt;<br>&gt; In big projects, you can actually see CMake writing &quot;scanning dependencies<br>
&gt; for&quot;. I think it does it before building each target.<br>&gt;<br>&gt;&gt; Anyway, I do not understand, how #include dependencies created by<br>&gt;&gt; generated files are handled.<br>&gt;<br>&gt; Same way. The dependencies are scanned before the target that depends on<br>
&gt; generated.h is compiled. It would seem to me that this means scanning the<br>&gt; dependencies for libfoo twice, but I&#39;m no expect in this.<br>&gt;<br>&gt;&gt; Assume &#39;foobar.c&#39; is generated. For sure it includes something. During<br>
&gt;&gt; configure stage there is<br>&gt;&gt; no &#39;foobar.c&#39;. Do I have to manually enlist &#39;foobar.c&#39; dependencies<br>&gt;&gt; via OBJECT_DEPENDS property?<br>&gt;&gt; Or may be &#39;foobar.c&#39; is scanned on build stage, and everything just works<br>
&gt;&gt; fine?<br>&gt;<br>&gt; The latter. It works fine with the protocols buffer this way, and also the<br>&gt; FindQt.cmake seems to work like this (that include is somewhat involved,<br>&gt; though)<br>&gt;<br>&gt;&gt;<br>
&gt;&gt; Finally, how do I control targets ordering during build? I have<br>&gt;&gt; &#39;generate&#39; target that generates &#39;generated.h&#39;.<br>&gt;&gt; I have &#39;foo&#39; and &#39;bar&#39; targets that use &#39;generated.h&#39;. How can I force<br>
&gt;&gt; &#39;generate&#39; to be build before &#39;foo&#39; and &#39;bar&#39;?<br>&gt;<br>&gt;&gt; Is ADD_DEPENDENCIES the only option? Maybe a clever hack exists to<br>&gt;&gt; built the given target *before* all<br>&gt;&gt; other project&#39;s targets?<br>
&gt;<br>&gt; That is what dependency tracking is for. And that should be handled<br>&gt; automatically by the add_custom_target.<br>&gt;<br>&gt; --<br>&gt; kind regards, Esben<br><br></div>