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