[CMake] How to use add_custom_command correctly
Rolf Eike Beer
eike at sf-mail.de
Wed Sep 28 07:34:33 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?
Can you paste the relevant snippet from your new CMakeLists.txt?
You can try this first and see if it helps:
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/driver.c
COMMAND ${CodeGen} {CodeGenParam}
DEPENDS ${CodeGenConfig} )
add_executable(myexe ${CMAKE_CURRENT_BINARY_DIR}/driver.c)
Of course you must tell the CodeGen where to put the result, preferably by
passing "${CMAKE_CURRENT_BINARY_DIR}/driver.c" as argument (with the
quotes, to make paths with spaces work right). If the generator can't
handle this you can try to set WORKING_DIRECTORY to
${CMAKE_CURRENT_BINARY_DIR}, passing all other file arguments with
absolute paths then.
Eike
More information about the CMake
mailing list