检测 CMake 中是否存在生成器表达式

Detect presence of generator expressions in CMake

以下问题的用例是部署的宏包,因此输入完全由用户定义。

考虑以下最小示例:

function(foo)
    cmake_parse_arguments(FOO "" "POSSIBLY_RELATIVE_POSSIBLY_GENEX_PATH" "" ${ARGN})
    # Chosen as an example for a necessary step which doesn't have a generator expression equivalent
    get_filename_component(
        ABSOLUTE_PATH
        "${FOO_POSSIBLY_RELATIVE_POSSIBLY_GENEX_PATH}"
        REALPATH
        BASE_DIR
            "${CMAKE_CURRENT_SOURCE_DIR}"
    )
    # Compatible with generator expressions by itself
    add_custom_command(
        OUTPUT
            ${MY_OUTPUT}
        COMMAND
            ${MY_TOOL}
            ${ABSOLUTE_PATH}
    )
endfunction()

add_custom_command 本身支持生成器表达式,但需要通过 get_filename_component 处理一个 class 输入(相对路径,为了调用代码简洁),以及使用该中间步骤的另一个 class 输入(构建类型相关的生成器表达式,被 get_filename_component 打乱)是不可能的。

只要 POSSIBLY_RELATIVE_POSSIBLY_GENEX_PATH 包含任何 genex 组件,就无法有效地使用

get_filename_componentget_filename_component 也没有等效的生成器表达式,因此无法替换该逻辑。

是否有一种可靠的方法来检测 CMake 变量中是否存在有效的生成器表达式,因此它可以用作信号 not 来尝试任何非 genex 转换那个输入?

您可以使用命令 string(GENEX_STRIP) 从字符串中去除生成器表达式,并将其结果与原始字符串进行比较:

string(GENEX_STRIP "${FOO_POSSIBLY_RELATIVE_POSSIBLY_GENEX_PATH}" no_genex)
if(FOO_POSSIBLY_RELATIVE_POSSIBLY_GENEX_PATH STREQUAL no_genex)
  # The string doesn't contain generator expressions.
  # It is safe to use e.g. 'get_filename_component'
else()
  # The string contains generator expressions.
  # This case requires special handling.
endif()