CMake: execute a macro/function as the command of add_custom_command
Asked Answered
C

3

14

I'm using an external library which provides a CMake function for automatic code generation, to be used in my CMakeLists. The problem is that whenever I modify a CMakeLists then the function is run again, triggering the recompilation of the newly generated but unchanged sources. I'd need something like add_custom_command with the possibility to specify the CMake function as COMMAND instead of an executable, so that the function is run only if the automatically generated files are not already present. Is this feasible? If not, does it exist another way to obtain the same result? Thanks.

Callaway answered 14/1, 2015 at 15:34 Comment(0)
D
6

To prevent that function to run, just wrap it into if:

if(NOT EXISTS ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp)
   run_your_provided_command(BLAH_BLAH)
endif()

Easy!

Update: To run it when config file has changed just use little more complicated condition:

if(
   NOT EXISTS ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp OR
   ${CMAKE_SOURCE_DIR}/blah-blah.config IS_NEWER_THAN ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp
  )
...

and use add_dependencies command to make sure your binary will be rebuild in case of config file modifications:

add_executable(
    YourBinary
    ...
    ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp
  )
add_dependencies(YourBinary ${CMAKE_SOURCE_DIR}/blah-blah.config)
Detect answered 14/1, 2015 at 17:4 Comment(4)
Thank you, this largely solves my problem. But since the function reads a config file in order to generate the code I'd need to re-run it when the config file changes. This is why I asked for something like add_custom_command which support dependencies.Callaway
Wow, I didn't know IS_NEWER_THAN. The updated answer is the complete solution for my problem, thanks!Callaway
You do not need to an additional NOT EXISTS check in conjunction with IS_NEWER_THAN, because the latter already implies the former.Unchartered
add_dependencies works with targets, not random external files. I had to go with cmake -Dvar=value -P=script method.Ddene
X
12

Take a look to this SO post.

You can call your function in a separate CMake script, call this script with add_custom_target and cmake -P then add a dependency to your binary :

add_custom_target(run_script COMMAND ${CMAKE_COMMAND} -P separate_script.cmake)
add_executable(your_binary ...)
# or add_library(your_binary ...)
add_dependencies(your_binary run_script)
Xerox answered 12/4, 2016 at 17:11 Comment(1)
Is there a way to pass a parameter to the separate_script.cmake?Schaerbeek
P
9

Is there a way to pass a parameter to the separate_script.cmake?

You can use the cmake variables to pass values when you call the script e.g.

"COMMAND ${CMAKE_COMMAND} -DPARAM=value -P separate_script.cmake" 
Paradise answered 12/7, 2019 at 14:3 Comment(0)
D
6

To prevent that function to run, just wrap it into if:

if(NOT EXISTS ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp)
   run_your_provided_command(BLAH_BLAH)
endif()

Easy!

Update: To run it when config file has changed just use little more complicated condition:

if(
   NOT EXISTS ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp OR
   ${CMAKE_SOURCE_DIR}/blah-blah.config IS_NEWER_THAN ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp
  )
...

and use add_dependencies command to make sure your binary will be rebuild in case of config file modifications:

add_executable(
    YourBinary
    ...
    ${CMAKE_BINARY_DIR}/blah-blah/generated.cpp
  )
add_dependencies(YourBinary ${CMAKE_SOURCE_DIR}/blah-blah.config)
Detect answered 14/1, 2015 at 17:4 Comment(4)
Thank you, this largely solves my problem. But since the function reads a config file in order to generate the code I'd need to re-run it when the config file changes. This is why I asked for something like add_custom_command which support dependencies.Callaway
Wow, I didn't know IS_NEWER_THAN. The updated answer is the complete solution for my problem, thanks!Callaway
You do not need to an additional NOT EXISTS check in conjunction with IS_NEWER_THAN, because the latter already implies the former.Unchartered
add_dependencies works with targets, not random external files. I had to go with cmake -Dvar=value -P=script method.Ddene

© 2022 - 2024 — McMap. All rights reserved.