Stephen H. Gerstacker
Stephen H. Gerstacker

Reputation: 763

CMake Custom Command Depending On Variable

Part of my build process requires passing in a variable to a script to generate some source files. It looks something like this:

    add_custom_command(OUTPUT
        rebuild_files
        COMMAND ${CMAKE_COMMAND} -E echo
        COMMENT "Force rebuild of generated files"
    )

    add_custom_command(OUTPUT "File.c" "File.h"
        COMMAND ruby generate_files.rb ${OPTIONS_LIST}
        COMMENT "Generate files"
        DEPENDS rebuild_files
    )

Of course, this runs on every compilation, which isn't needed. The OPTIONS_LIST is set up at configuration time, so it could be cached.

Is there a mechanism to make a custom command dependent on a variable? The ultimate goal is to have this only compile if:

  1. OPTIONS_LIST changes.
  2. File.c or File.h do not exist.

Upvotes: 3

Views: 2684

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 65928

Using configure_file one may convert "dependency from the variable" to "dependency from the file" which is naturally handled by custom target/command:

options_list_file.in:

${OPTIONS_LIST}

CMakeLists.txt:

# Variable which can be modified by a user
set(OPTIONS_LIST "a,b" CACHE STRING "<description>")
# Configure file which will be updated on changing the variable's content
configure_file("options_list_file.in" "options_list_file")

add_custom_command(OUTPUT "File.c" "File.h"
    COMMAND ruby generate_files.rb ${OPTIONS_LIST}
    COMMENT "Generate files"
    DEPENDS "${CMAKE_CURRENT_BINART_DIR}/options_list_file" # dependency from the file
)

Changing the OPTIONS_LIST variable implies re-running CMake (configuration stage). Upon that re-run the configure_file will be called unconditionally.

But the file options_list_file will be updated only when its content would be changed. This is a main feature of configure_file.

That is, if the variable is set by a user to another value, then options_list_file will be updated, and this triggers re-running custom COMMAND on next build.

But if the variable's content is not changed, then configure_file wouldn't change the file options_list_file and its timestamp (this is important!). So, next build won't treat the file as updated and won't trigger the COMMAND re-run.

Upvotes: 4

Related Questions