Xcode生成器的特定于配置的add_custom_command [英] Configuration-specific add_custom_command with Xcode generator

查看:69
本文介绍了Xcode生成器的特定于配置的add_custom_command的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create a custom command that will merge all static libraries into a fat static library using Apple's libtool command during build. I'm using Xcode generator and CMake 3.19.1. My script is like this:

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_debug all_dependencies_release 列表中,并应合并.这些列表的内容可能包含指向静态库或生成器表达式的实际路径(如果依赖关系是另一个目标,则为实际目标或导入目标).

libname is the name of the target whose dependencies for debug and release are collected into all_dependencies_debug and all_dependencies_release lists and should be merged. The contents of those lists may contain actual paths to static libraries or generator expressions (in case dependency is another target, either real or imported).

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

However, this generates the following script in 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:时会抛出语法错误.

This, of course, fails during build because xcode throws syntax error when parsing $<1:.

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

I've also tried adding VERBATIM, but this only causes $ to be escaped.

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

Is this a bug in CMake Xcode generator or did I do something wrong?

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

I've also tried using older versions of CMake (3.18.4), which don't support Modern Apple Build System, but to no avail.

CMake文档指出 COMMAND add_custom_command 的code>部分应该能够使用生成器表达式.

CMake documentation states that COMMAND part of add_custom_command should be able to use generator expressions.

推荐答案

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

Actually, the trick is in using COMMAND_EXPAND_LISTS.

此CMake gitlab问题所述,正确的CMake脚本是:

As explained in this CMake gitlab issue, the correct CMake script is:

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阶段构建脚本感到困惑的其他字符.

First, all parameters must be given in double quotes, in order to ensure that spaces and ; separator in list are passed through to the add_custom_command. Next, the COMMAND_EXPAND_LISTS will make sure that list given via generator expression (i.e. "$<$<CONFIG:Debug>:${all_dependencies_debug}>") will be properly expanded - without this, the semicolons would end-up in the final Xcode build phase script. Finally, the VERBATIM is needed to properly escape all other characters that may confuse the Xcode phase build script.

感谢Brad King在 gitlab问题上的快速帮助和回复.

Thank you Brad King for your quick help and response at gitlab issues.

这篇关于Xcode生成器的特定于配置的add_custom_command的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆