Configuration-specific add_custom_command with Xcode generator

半腔热情 提交于 2021-02-08 14:06:24

问题


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 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).

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

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

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

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

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 documentation states that COMMAND part of add_custom_command should be able to use generator expressions.


回答1:


Actually, the trick is in using COMMAND_EXPAND_LISTS.

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} )

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.

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



来源:https://stackoverflow.com/questions/65222331/configuration-specific-add-custom-command-with-xcode-generator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!