[CMake] How to use add_custom_command correctly

Martin Kupke martin.kupke at novero.com
Wed Sep 28 06:53:16 EDT 2011



On 27.09.11 18:24, Michael Wild wrote:
> On 09/27/2011 05:59 PM, Martin Kupke wrote:
>> Hi,
>>
>> in my project there is a subfolder which SHALL contain sources to
>> generate a library. The problem is that at startup of the project there
>> are no source files existing, because they will be generated by a code
>> generator. This means within the build process the code generator needs
>> to be called first, then generates the output files in the subfolder and
>> then a library shall be generated from that source files (this are
>> standard .c and .h files). If I start the code generator by hand to
>> generate the source files and remove the custom command, then the
>> compilation is successful, but I want the code generator to be started
>> every time the configuration file for the code generator has changed.
>>
>> In my sample below
>> * the driver.c would be one of the files which the code generator would
>> generate
>> * the variable CodeGen is the executable tool (the code generator himself)
>> * the variable CodeGenParam contains the parameters which are passed to
>> be able to generate without any user interaction
>> * the variable CodeGenConfig is the input file for the code generator
>>
>> This subfolder contains its own CMakeLists.txt with the following settings:
>> ##################### snip #####################
>> project(CANstack C)
>>
>> add_custom_command( OUTPUT driver.c
>>                                             COMMAND ${CodeGen}
>> ${CodeGenParam}
>>                                             DEPENDS ${CodeGenConfig} )
>> )
>>
>> file(GLOB CANstack_srcs "*.c")
>> file(GLOB CANstack_hdrs "*.h")
>>
>> set(lib_name "CANstack")
>> add_library(${lib_name} STATIC ${CANstack_srcs} ${CANstack_hdrs})
>>
>> ##################### snap #####################
>>
>> I don't get it work that the custom command is called and the source
>> files from the code generator are produced.
>>
> A few issues here:
>
> - Never generate output in the source tree, only in the binary tree.
> - Always use absolute paths with add_custom_command().
I use the absolute paths
> - Always list *all* outputs after the OUTPUT argument, otherwise CMake
> won't know that they are generated sources.
I added the list of *all* files which shall be generated
> - Never use file(GLOB ...). It is evil. And breaks in your case. Just don't.
I don't use the file(GLOB ...) anymore in this CMakeLists.txt
> Michael
>
In case the generated output files already exist and the dependency file 
${CodeGenConfig} has been touched, then the output will be generated.

Typically there is from beginning of the project no source file 
existing, because the generator needs to be run first. If the output 
files are not existing, then I get an error message from CMake:

##################### snip #####################

CMake Error at Generated/CarIF_Appl/CANstack/CMakeLists.txt:31 
(add_library):
   Cannot find source file:

     D:/project/Discovery/Generated/Driver/uart.c

   Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
   .hxx .in .txx

##################### snap #####################

How do I have to instruct CMake to run the code generator first, so that 
the library can be build of that sources?

Br,
Martin



More information about the CMake mailing list