Search code examples
cmakeadd-custom-targetcmake-cache

How to use CMake cached variables inside subprocess called by custom target?


My project contains a custom target which generates some output via .cmake script. It looks like this:

add_custom_target(TargetName
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/script.cmake
    BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/generated/output
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    VERBATIM
)

But now I want to set come cache variables inside the script. I tried doing like that:

message("MY_CACHE_VARIABLE = ${MY_CACHE_VARIABLE}")
set(MY_CACHE_VARIABLE "VALUE" CACHE INTERNAL "")

And I faced with the problem that cache variables are not saved. It always prints me empty output:

MY_CACHE_VARIABLE =

I already tried setting working directory as CMAKE_BINARY_DIR, or passing CMAKE_BINARY_DIR of the last argument of cmake command, or passing -B ${CMAKE_BINARY_DIR} or -C ${CMAKE_BINARY_DIR}/CMakeCache.txt as arguments and etc. None of these worked.
So is there any way to reuse existing cache inside CMake subprocess or I just should write my own cache inside the script?


Solution

  • You have to distinguish between running CMake to generate build files (for Make, Ninja, etc.) and running CMake in script mode:

    Script mode simply runs the commands in the given CMake Language source file and does not generate a build system. It does not allow CMake commands that define build targets or actions.
    -- cmake-language(7)

    No configure or generate step is performed and the cache is not modified.
    -- cmake(1)

    So in script mode (-P), CMake is not aware of the cache or any variable/target/etc. defined in your regular CMakeLists.txt files. It is more similar to executing a bash/shell script than to processing a "usual" CMakeLists.txt.

    But don't worry, there is still a solution to your problem. You can simply pass your arguments as -D options to your script:

    add_custom_target(TargetName
      COMMAND ${CMAKE_COMMAND}
        -DMY_VAR="..."
        -DANOTHER_VAR="..."
        -P ${CMAKE_SOURCE_DIR}/cmake/script.cmake
      ...
    )
    

    Note however:

    If variables are defined using -D, this must be done before the -P argument.
    -- cmake(1)