[CMake] add_custom_command and generated true

Micha Renner Micha.Renner at t-online.de
Tue Jan 25 10:21:51 EST 2011


Am Dienstag, den 25.01.2011, 15:34 +0100 schrieb Michael Hertling:
> On 01/25/2011 10:17 AM, Micha Renner wrote:
> > Recently, I learned that ADD_CUSTOM_COMMAND generated the property
> > GENERATED TRUE for the generated file.
> > 
> > Somehow I have trouble in this situation:
> > 
> > In a top level CMakeLists file a source file, blue.c, is generated. This
> > file should be used in a subdirectory with its own CMakeLists file.
> > 
> > Running CMake generates the message: "cannot find blue.c etc..."
> > 
> > Okay, the information, that this is a generated sourcefile is, maybe,
> > lost on the transition to the subdirectory.
> 
> The documentation of SET_SOURCE_FILES_PROPERTIES() states
> 
> "Source file properties are visible only to targets added in the same
> directory (CMakeLists.txt)."
> 
> and GENERATED is a source file property, so it's not amazing that the
> subdirectory's CMakeLists.txt doesn't recognize blue.c as generated,
> even if the property is imposed by ADD_CUSTOM_COMMAND(OUTPUT ...).
> 
> > So, I inserted in the CMakeLists file of subdirectory the line:
> > 	SET_SOURCE_FILES_PROPERTIES(blue.c PROPERTIES GENERATED TRUE)
> > which generates the make message
> > 	No rule to build target subdirectory/blue.c
> 
> Explicitly setting the GENERATED property here quiets CMake, but the
> subdirectory's Makefile won't have a rule to generate blue.c because
> the custom command is defined in the top-level CMakeLists.txt; from
> the documentation of ADD_CUSTOM_COMMAND():
> 
> "A target created in the same directory (CMakeLists.txt file)
> that specifies any output of the custom command as a source file
> is given a rule to generate the file using the command at build time."
> 
> So, the build will fail with the mentioned error message from make.
> 
> > I changed the inserted line (see above) to...
> > 	SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/blue.c
> > 		 PROPERTIES GENERATED TRUE) 
> > ... which is okay.
> 
> AFAICS from your example, this works by accident: The custom target is
> processed before make descends to the subdirectory, so blue.c already
> exists when the cTest target gets built, and CMake is happy because
> blue.c is marked as GENERATED in that *directory's* CMakeLists.txt.
> Remove the ALL flag from the ADD_CUSTOM_TARGET() command, and you
> will probably see your example fail, regardless if and how the
> GENERATED property is set.
> 
> > => Two question
> > 
> > - Is it general true, that properties are lost on transition to a
> >   subdirectory?
> 
> This is true for the source file properties and for some directory
> properties like EXCLUDE_FROM_ALL; the latter is not inherited by sub-
> directories, but the COMPILE_DEFINITIONS directory property, e.g., is.
> 
> > - In which cases is it absolute necessary to work with absolute paths
> >   and SET_SOURCE_FILES?
> 
> IMO, the rule of thumb is: Use absolute paths where the behavior
> for relative paths is not specified or not appropriate. E.g.,
> 
> ADD_CUSTOM_COMMAND(OUTPUT blue.c ...)
> 
> will generate ${CMAKE_CURRENT_BINARY_DIR}/blue.c, but which directory
> 
> SET_SOURCE_FILES_PROPERTIES(blue.c PROPERTIES ...)
> 
> bases on? For the GENERATED property, CMAKE_CURRENT_BINARY_DIR would be
> reasonable, but for the LANGUAGE property, CMAKE_CURRENT_SOURCE_DIR
> might suit better. Thus, SET_SOURCE_FILES_PROPERTIES() should be
> invoked with absolute paths only.

Thanks, these are understandable explanations. Very good.

> 
> BTW, you shouldn't do in-source builds, and do not write to the source
> directories; it's bad style, doesn't play nicely with version control
> systems and might be the reason for some quite subtle problems.
I know, but sometimes you have a given structure, which you can't
change. The above example is the result of a move-over of glibmm. Here
many src-files are generated in-source and these files already exists.
If I install the CMake scripts, I could remove the generated source
files, but then I need a list of the generated files in my installation
script and this is want I don't want.

Greetings Micha




More information about the CMake mailing list