CMake: how to make execute_process wait for subdirectory to finish?

Viewed 3713

Part of my source code is generated by a tool which is also built under our main project with a add_subdirectory. We execute this tool with a execute_process command. Clearly, if the tool is not built before we reach the execute_process statement it will fail.

I use a GLOB (file(GLOB...)) to find the source files generated. I do this because it is not possible to know beforehand how many files are generated, neither their names.

How do I force cmake to wait for the subproject to be compiled before the execute process? I would need something like a DEPENDS property for the execute_process but this option is not available.

# This subproject will source generator the tool
add_subdirectory(generator)


# I need something like: wait_for(generator)
execute_process(COMMAND generator ${CMAKE_SOURCE_DIR}/src)

file(GLOB GeneratedSources ${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(mainprject.exe ${ProcessorSourceFiles}
2 Answers

Command execute_process executes its COMMAND immediately, at configuration stage. So it cannot be arranged after the executable is created with add_executable command: that executable will be built only at build stage.

You need to build subproject at configuration stage too. E.g. with

execute_process(COMMAND ${CMAKE_COMMAND}
    -S ${CMAKE_SOURCE_DIR}/generator
    -B ${CMAKE_BINARY_DIR}/generator
    -G ${CMAKE_GENERATOR}
    )

execute_process(COMMAND ${CMAKE_COMMAND}
    --build ${CMAKE_BINARY_DIR}/generator
    )

The first command invokes cmake for configure the 'generator' project, located under ${CMAKE_SOURCE_DIR}/generator directory. With -G option we use for subproject the same CMake generator, as one used for the main project.

The second command builds that project, so it produces generator executable.

After generator executable is created, you may use it for your project:

execute_process(COMMAND ${CMAKE_BINARY_DIR}/generator/<...>/generator ${CMAKE_SOURCE_DIR}/src)

Here you need to pass absolute path to the generator executable as the first parameter to COMMAND: CMake no longer have generator executable target, so it won't substitute its path automatically.

You will need to model this with target dependencies. The tool "generator" should be a cmake target. In that case use add_custom_target instead of execute_process somthing like this:

add_custom_target(generate_sources ALL COMMAND generator ${CMAKE_SOURCE_DIR}/src))

Then add a target dependency to "generator" using add_dependencies:

add_dependencies(generate_sources generator)

This will make sure your target "generate_sources", which runs the tool will only run during build after the target "generator" has been compiled.

The following is false, see the comments for more info:

Use add_dependencies to add a dependency from "mainproject.exe" to "generate_sources". Now this I have never tested, so take with a grain of salt: With CMake more recent than version 3.12, according to the entry on file, you should then be able to change your file command to:

file(GLOB GeneratedSources CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/src/*.cpp)

Which I interpret as this will re-glob the files during build if the directory changes.

Related