[CMake] How to use add_custom_command correctly
Martin Kupke
martin.kupke at novero.com
Wed Sep 28 07:45:13 EDT 2011
Now it seems to be solved, the generator is called and the generated
sources / headers are then compiled and linked into a library.
My changes are in the
D:/project/Discovery/Generated/Driver/CMakeLists.txt
just adding a add_custom_target( MyGeneratedSources ALL DEPENDS
${all_generated_srcs} ${all_generated_hdrs} )
Additionally I added in the root CMakeLists.txt
add_dependencies( ${MY_PROJECT} MyGeneratedSources )
This works fine.
On 28.09.11 13:34, Rolf Eike Beer wrote:
>>
>> 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
> --
>
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
More information about the CMake
mailing list