Я хочу создать пользовательскую команду, которая объединит все статические библиотеки в толстую статическую библиотеку с помощью команды 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_debug
и all_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 выдает syntax error
при разборе $<1:
.
Я также пытался добавить VERBATIM
, но это приводит только к экранированию $
.
Это ошибка в генераторе CMake Xcode или я что-то не так сделал?
Я также пытался использовать более старые версии CMake (3.18.4), которые не поддерживают современную систему сборки Apple, но безрезультатно.
Документация CMake гласит, что COMMAND
часть add_custom_command
должна иметь возможность использовать выражения генератора.
Итак, ваш вопрос имеет некоторые особенности по сравнению с другим. Я снова открыл его.
Поскольку вы знаете, что ваша проблема не связана с XCode, не могли бы вы отредактировать заголовок?
@Tsyvarev, поскольку вопрос напрямую относится к сгенерированному сценарию фазы сборки Xcode, я бы предпочел сохранить тот же заголовок. Хотя теперь, когда я нашел ответ, я согласен с тем, что исходная проблема не обязательно связана с генератором CMake Xcode.
На самом деле, хитрость заключается в использовании 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.
Спасибо Брэду Кингу за быструю помощь и ответ на gitlab Issues.
Чувак, это было полезно. Спасибо.
На самом деле можно использовать список элементов в выражениях генератора, как мне сказали после того, как задал тот же вопрос на CMake gitlab. Хитрость в использовании
COMMAND_EXPAND_LISTS
- я как раз собирался добавить сюда ответ и закрыть вопрос, но вы оказались быстрее.