如何使用 CMake 列表中的空条目作为参数

How to use empty entries in CMake lists as arguments

当使用 CMake 列表为函数指定多个参数时,空参数不会作为参数传递给列表。在某些情况下,需要一个空字符串作为参数。有办法实现吗?

如果我运行这个

set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT)

set(LIST_VAR
    "ONE"
    "TWO"
    ""
    "FOUR"
)
execute_process(
    COMMAND
    ${CMAKE_COMMAND} -E echo
        ${LIST_VAR}
)

execute_process(
    COMMAND
    ${CMAKE_COMMAND} -E echo
    "ONE"
    "TWO"
    ""
    "FOUR"
)

cmake -P test.cmake

我得到:

'cmake' '-E' 'echo' 'ONE' 'TWO' 'FOUR'
ONE TWO FOUR
'cmake' '-E' 'echo' 'ONE' 'TWO' '' 'FOUR'
ONE TWO  FOUR

在第一个变体中,第三个空参数被吞没了,如果存在空参数可能 possible/needed 并且参数被准备为 CMake 列表的情况,这真的很烦人。

在我的应用程序中,我需要调用脚本而不是 cmake -E echo,它在某些情况下需要空参数。

此外,空条目当然不会像这个简化示例中那样按字面意思输入。而不是 "" 我有类似 "${MIGHT_BE_EMPTY}".

的东西

有没有办法安全地将空字符串作为列表条目传输到函数参数?

如果没有,是否有解决此问题的好方法?

例如将未设置的变量转换为类似 space (" ") 的东西,这可能相当于被调用脚本的空参数?

问题是CMake中没有列表,只有字符串。并且有一些 CMake 命令可以理解的约定:如果变量中有未加引号的 ;(分号),那么它是一个列表,列表中的每个元素通过 ; 与另一个元素分隔开。并且有一个规则允许用白色 space 分隔的多个字符串创建列表。 所以这个命令:

set(LIST_VAR
    "ONE"
    "TWO"
    ""
    "FOUR"
)

创建一个包含以下内容的变量:ONE;TWO;;FOUR 这是 CMake 书中的一个列表。现在有 another rule (反向)CMake 在扩展未引用的变量时使用:

Each non-empty element is given to the command invocation as an argument.

因此您不能使用空元素并让 CMake 列表在脚本中传播它们。不过,您可以使用 non-empty 之类的东西,例如空元素。例如,您可以使用 space 字符来表示该元素为空,前提是它不会与您的其他数据混淆:

set(EMPTY " ")
set(LIST_VAR
    "ONE"
    "TWO"
    "${EMPTY}"
    "FOUR"
    )

如果您不能通过显式提供 ${EMPTY} 元素来修改列表,您可以像这样将其添加到现有列表中:string(REPLACE ";;" ";${EMPTY};" LIST_VAR "${LIST_VAR}").

最后,如果您需要修改的不是列表而是一些特定的、可能为空的变量,那么您可以使用以下命令:

if(MIGHT_BE_EMPTY STREQUAL "")
    set(MIGHT_BE_EMPTY "${EMPTY}")
endif()

我使用 EMPTY 变量,因为它很方便,您可以将其删除并替换为您喜欢的任何符号 - 它不会有什么不同。