带有 Xcode 生成器的特定于配置的 add_custom_command

DoD*_*oDo 6 c++ xcode cmake

我想创建一个自定义命令,libtool在构建期间使用 Apple 的命令将所有静态库合并到一个胖静态库中。我正在使用 Xcode 生成器和 CMake 3.19.1。我的脚本是这样的:

set( TARGET_OUTPUT_NAME ${CMAKE_BINARY_DIR}/fat-libs/${CMAKE_CFG_INTDIR}/lib${libname}.a )
add_custom_command(
    OUTPUT
        ${TARGET_OUTPUT_NAME}
    COMMAND
        /usr/bin/libtool -static -o ${TARGET_OUTPUT_NAME} $<TARGET_FILE:${libname}>
        $<$<CONFIG:Debug>:${all_dependencies_debug}>
        $<$<CONFIG:Release>:${all_dependencies_release}>
    DEPENDS
        ${libname}
    COMMENT
        "Building merged static library"
)
add_custom_target( ${TARGET_NAME} DEPENDS ${TARGET_OUTPUT_NAME} )
Run Code Online (Sandbox Code Playgroud)

libname是目标的名称,其调试和发布的依赖项被收集到all_dependencies_debugall_dependencies_release列表中并应合并。这些列表的内容可能包含静态库或生成器表达式的实际路径(如果依赖项是另一个目标,无论是真实的还是导入的)。

但是,这会在 Xcode 中生成以下脚本:

set( TARGET_OUTPUT_NAME ${CMAKE_BINARY_DIR}/fat-libs/${CMAKE_CFG_INTDIR}/lib${libname}.a )
add_custom_command(
    OUTPUT
        ${TARGET_OUTPUT_NAME}
    COMMAND
        /usr/bin/libtool -static -o ${TARGET_OUTPUT_NAME} $<TARGET_FILE:${libname}>
        $<$<CONFIG:Debug>:${all_dependencies_debug}>
        $<$<CONFIG:Release>:${all_dependencies_release}>
    DEPENDS
        ${libname}
    COMMENT
        "Building merged static library"
)
add_custom_target( ${TARGET_NAME} DEPENDS ${TARGET_OUTPUT_NAME} )
Run Code Online (Sandbox Code Playgroud)

当然,这在构建过程中会失败,因为 xcodesyntax error在解析$<1:.

我也试过添加VERBATIM,但这只会导致$被转义。

这是 CMake Xcode 生成器中的错误还是我做错了什么?

我还尝试使用不支持现代 Apple Build System 的旧版本 CMake (3.18.4),但无济于事。

CMake 文档说明COMMAND部分add_custom_command应该能够使用生成器表达式。

DoD*_*oDo 3

实际上,诀窍在于使用COMMAND_EXPAND_LISTS.

正如此 CMake gitlab 问题中所解释的,正确的 CMake 脚本是:

set( TARGET_OUTPUT_NAME ${CMAKE_BINARY_DIR}/fat-libs/${CMAKE_CFG_INTDIR}/lib${libname}.a )
add_custom_command(
    OUTPUT
        ${TARGET_OUTPUT_NAME}
    COMMAND
        /usr/bin/libtool -static -o "${TARGET_OUTPUT_NAME}" "$<TARGET_FILE:${libname}>"
        "$<$<CONFIG:Debug>:${all_dependencies_debug}>"
        "$<$<CONFIG:Release>:${all_dependencies_release}>"
    DEPENDS
        ${libname}
    COMMENT
        "Building merged static library"
    VERBATIM
    COMMAND_EXPAND_LISTS
)
add_custom_target( ${TARGET_NAME} DEPENDS ${TARGET_OUTPUT_NAME} )
Run Code Online (Sandbox Code Playgroud)

首先,所有参数都必须用双引号引起来,以确保;列表中的空格和分隔符传递到add_custom_command. 接下来,COMMAND_EXPAND_LISTS确保通过生成器表达式(即 )给出的列表"$<$<CONFIG:Debug>:${all_dependencies_debug}>"将被正确扩展 - 如果没有这个,分号将最终出现在最终的 Xcode 构建阶段脚本中。最后,VERBATIM需要正确转义可能混淆 Xcode 阶段构建脚本的所有其他字符。

感谢 Brad King 在gitlab 问题上的快速帮助和响应。