List variable expanded differently when passed to a command

Hi all.

Consider the following snippet:

set(implicit_dirs ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})

message(STATUS "implicit_dirs = ${implicit_dirs}")

add_custom_target(my_custom_target
    COMMAND ${CMAKE_COMMAND} -E env
        IMPLICIT_DIRS="${implicit_dirs}"
        some_command
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

I want to pass the semicolon separated list of directories in ${implicit_dirs} to the env var IMPLICIT_DIRS for the external command some_command. The problem is that when the value is passed in cmake -E env the semicolons are being replaced by spaces, so the environment variable passing doesn’t work.

However, when I print ${implicit_dirs} in the message() call it outputs as a semicolon separated list as expected.

How can I maintain the semicolon separation in the list when I pass it on to cmake -E env?

The placement of your quotes assumes unix shell behavior, but CMake doesn’t work that way. You need to quote the whole IMPLICIT_DIRS=... part, not just the value to the right of the = character. The other missing piece is that you need to add the VERBATIM keyword. A working version would look like this:

add_custom_target(my_custom_target
    COMMAND ${CMAKE_COMMAND} -E env
        "IMPLICIT_DIRS=${implicit_dirs}"
        some_command
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    VERBATIM
)

And you can also have a look at cmake_path(CONVERT … TO_NATIVE_PATH_LIST …) if you want a list in the platform format…