[CMake] Handling generated headers

Michael Ellery mellery451 at gmail.com
Mon Mar 27 18:37:08 EDT 2017


> On Mar 27, 2017, at 2:57 PM, Bruce Stephens <bruce.r.stephens at gmail.com> wrote:
> 
> Yes, that's the idea: I have custom commands (created with
> add_custom_command) listing the headers in OUTPUT.
> 
> And there are source files which #include such headers.
> 
> I'd like it so that compiling such a source file would cause the
> header to be generated.
> 
> Concretely, with a CMakeLists.txt like the attached, with the obvious
> main.c (also attached), I'd like "ninja exe" to work.
> 
> I find that it does not.
> 
> After "ninja build-incl" (or "ninja incl.h") then "ninja exe" will
> work. And then after removing incl.h,
> "ninja exe" will recreate incl.h and then rebuild exe. (Presumably
> ninja is caching some dependency information, likely
> in its .ninja_deps file.) But correct recompilation (while obviously
> desirable) doesn't seem sufficient; I want the first
> build to work too.
> 
> (I'm also not sure why the add_custom_target is required, but it does
> seem to be. Presumably without it CMake
> can't see why the custom command might be used.)
> 
> In most cases I have a natural place where I need the things to be
> built, so the custom target can have ALL DEPENDS
> (rather than.the DEPENDS in the example). However, in some cases in
> parallel builds I still end up with (sometimes)
> source files not compiling because the needed headers haven't been generated.
> 
> As I say, so far this is OK: I can just generated dependencies
> explicitly in a pre-CMake step. But handling cases where
> main.c includes some source header which includes this generated
> incl.h seems not easily doable.
> 
> If I'm not missing something silly and all this is expected behaviour
> (as it appears to be) it's not a disaster. We can add
> a few explicit dependencies and get things to work. But maybe I'm
> missing something and this should work more
> smoothly.
> 
> 
> On Mon, Mar 27, 2017 at 4:08 PM, Michael Ellery <mellery451 at gmail.com> wrote:
> <CMakeLists.txt><main.c>

Doing this worked for me:

————
add_executable(exe main.c ${CMAKE_CURRENT_BINARY_DIR}/incl.h)

target_include_directories(exe PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/incl.h
    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/incl.h)
————

..in other words, I used the binary dir as the output location of the generated file and then I explicitly added the header file to the sources list. Yeah, it would be nice if header reps auto detection worked in this case, but it seems like it does not, so you form the dependency relationship explicitly I guess.

-Mike




More information about the CMake mailing list