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



我想创建一个自定义命令,在构建过程中使用Apple的libtool命令将所有静态库合并到一个胖静态库中。我使用的是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} )

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

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

#!/bin/sh
set -e
if test "$CONFIGURATION" = "Debug"; then :
cd /path/to/build/folder
/usr/bin/libtool -static -o /path/to/build/folder/fat-libs/$CONFIGURATION$EFFECTIVE_PLATFORM_NAME/libMyLib.a /path/to/build/folder/Debug/libMyLib.a $<1:/path/to/first/debug/libSomething.a /path/to/second/debug/libSomething.a> $<0:/path/to/first/release/libSomething.a /path/to/second/release/libSomething.a>
fi
if test "$CONFIGURATION" = "Release"; then :
cd /path/to/build/folder
/usr/bin/libtool -static -o /path/to/build/folder/fat-libs/$CONFIGURATION$EFFECTIVE_PLATFORM_NAME/libMyLib.a /path/to/build/folder/Release/libMyLib.a $<0:/path/to/first/debug/libSomething.a /path/to/second/debug/libSomething.a> $<1:/path/to/first/release/libSomething.a /path/to/second/release/libSomething.a>
fi

当然,这在构建过程中会失败,因为xcode在解析$<1:时抛出syntax error

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

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

我也尝试过使用旧版本的CMake(3.18.4(,它不支持现代苹果构建系统,但没有用。

CMake文档指出add_custom_commandCOMMAND部分应该能够使用生成器表达式。

实际上,诀窍在于使用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} )

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

感谢Brad King对gitlab问题的快速帮助和回应。

相关内容

最新更新