frans
frans

Reputation: 9808

In CMake how do I deal with generated source files which number and names are not known before?

Imagine a code generator which reads an input file (say a UML class diagram) and produces an arbitrary number of source files which I want to be handled in my project. (to draw a simple picture let's assume the code generator just produces .cpp files).

The problem is now the number of files generated depends on the input file and thus is not known when writing the CMakeLists.txt file or even in CMakes configure step. E.g.:

>>> code-gen uml.xml
generate class1.cpp..
generate class2.cpp..
generate class3.cpp..

What's the recommended way to handle generated files in such a case? You could use FILE(GLOB.. ) to collect the file names after running code-gen the first time but this is discouraged because CMake would not know any files on the first run and later it would not recognize when the number of files changes.

I could think of some approaches but I don't know if CMake covers them, e.g.:

Update: This question targets a similar problem but just asks how to glob generated files which does not address how to re-configure when the input file changes.

Upvotes: 3

Views: 2070

Answers (1)

frans
frans

Reputation: 9808

Together with Tsyvarev's answer and some more googling I came up with the following CMakeList.txt which does what I want:

project(generated)
cmake_minimum_required(VERSION 3.6)
set(IN_FILE "${CMAKE_SOURCE_DIR}/input.txt")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IN_FILE}")
execute_process(
    COMMAND python3 "${CMAKE_SOURCE_DIR}/code-gen" "${IN_FILE}"
    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
    INPUT_FILE "${IN_FILE}"
    OUTPUT_VARIABLE GENERATED_FILES
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_executable(generated main.cpp ${GENERATED_FILES})

It turns an input file (input.txt) into output files using code-gen and compiles them.

execute_process is being executed in the configure step and the set_property() command makes sure CMake is being re-run when the input file changes.

Note: in this example the code-generator must print a CMake-friendly list on stdout which is nice if you can modify the code generator. FILE(GLOB..) would do the trick too but this would for sure lead to problems (e.g. old generated files being compiled, too, colleagues complaining about your code etc.)

PS: I don't like to answer my own questions - If you come up with a nicer or cleaner solution in the next couple of days I'll take yours!

Upvotes: 2

Related Questions