Search code examples
cmakectest

Cannot set variables in generated CMake script


I am trying to get the output from the invocation of an executable in CMake as a string for processing in the build system. It is a list of test suites that I will add to the CTest tool using add_test.

In CMakeLists.txt

...(After adding the mlpack_test target)...
configure_file(generate_test_names.cmake.in generate_test_names.cmake)
add_custom_command(TARGET mlpack_test
  POST_BUILD
  COMMAND ${CMAKE_COMMAND} -P generate_test_names.cmake
)

In generate_test_names.cmake.in

function(get_names)
  message("Adding tests to the test suite")
  execute_process(COMMAND ${CMAKE_BINARY_DIR}/bin/mlpack_test --list_content
    OUTPUT_VARIABLE FOO)
  message(STATUS "FOO='${FOO}'")
endfunction()

get_names()

The script gets executed, and I can see the output from mlpack_test --list_content in the stdout of the build. But FOO is still an empty string.

The output :

Adding tests to the test suite
ActivationFunctionsTest*
    TanhFunctionTest*
    LogisticFunctionTest*
    SoftsignFunctionTest*
    IdentityFunctionTest*
    RectifierFunctionTest*
    LeakyReLUFunctionTest*
    HardTanHFunctionTest*
    ELUFunctionTest*
    SoftplusFunctionTest*
    PReLUFunctionTest*
-- FOO=''

Why is the argument to OUTPUT_VARIABLE not initialised with the stdout of the process executed?


Solution

  • When generate CMake script with configure_file, it is better to use @ONLY option for that command:

    configure_file(generate_test_names.cmake.in generate_test_names.cmake @ONLY)
    

    In that case only @var@ references will be replaced with variable's values, but ${var} references remains unchanged:

    function(get_names)
      message("Adding tests to the test suite")
      # CMAKE_BINARY_DIR will be replaced with the actual value of the variable
      execute_process(COMMAND @CMAKE_BINARY_DIR@/bin/mlpack_test --list_content
        OUTPUT_VARIABLE FOO)
      # But FOO will not be replaced by 'configure_file'.
      message(STATUS "FOO='${FOO}'")
    endfunction()
    
    get_names()