CMAKE_LINK_LIBRARY_USING_<FEATURE>
Новое в версии 3.24.
Эта переменная определяет способ линковки библиотеки или фреймворка для указанного <FEATURE> при использовании генераторного выражения LINK_LIBRARY. Для того, чтобы эта переменная имела какой-либо эффект, должны быть выполнены оба следующих условия:
- Соответствующая переменная
CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDдолжна быть установлена в значение true. - Нет языкоспецифичного определения для того же
<FEATURE>. Это означает, чтоCMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDне может быть установлено в значение true для языка линковки, используемого целевым объектом, для которого оценивается генераторное выражениеLINK_LIBRARY.
Имена функций чувствительны к регистру и могут содержать только буквы, цифры и символы подчёркивания. Имена функций, определённые только заглавными буквами, зарезервированы для встроенных функций CMake (см. Предопределённые функции ниже).
Определения функций
Определение функции библиотеки — это список, содержащий один или три элемента:
[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]
Когда <PREFIX> и <SUFFIX> указаны, они предшествуют и следуют, соответственно, всему списку библиотек, указанных в выражении LINK_LIBRARY, а не каждому элементу списка библиотек индивидуально. Нет гарантии, что список указанных библиотек будет оставаться сгруппированным, поэтому <PREFIX> и <SUFFIX> могут появляться более одного раза, если список библиотек переупорядочивается CMake для удовлетворения других ограничений. Это означает, что конструкции типа --start-group и --end-group, поддерживаемые линковщиком GNU ld, не могут быть использованы таким образом. Для таких конструкций следует использовать генераторное выражение LINK_GROUP.
<LIBRARY_EXPRESSION> используется для указания шаблона для построения соответствующего фрагмента в командной строке линковщика для каждой библиотеки. В выражении можно использовать следующие плейсхолдеры:
-
<LIBRARY>расширяется до полного пути к библиотеке для целевых объектов CMake или до платформоспецифического значения в другом случае (то же, что и<LINK_ITEM>в Windows, или имя базовой библиотеки для других платформ). -
<LINK_ITEM>расширяется до того, как библиотека обычно линковалась бы в командной строке линковщика. -
<LIB_ITEM>расширяется до полного пути к библиотеке для целевых объектов CMake или самого элемента точно так, как он был указан в<LIBRARY_EXPRESSION>в ином случае.
В дополнение к вышесказанному, возможно иметь один шаблон для путей (целевые объекты CMake и внешние библиотеки, указанные с путями к файлам) и другой для других элементов, указанных только по имени. Обёртки PATH{} и NAME{} могут быть использованы для предоставления расширения для этих двух случаев соответственно. При использовании обёрток обе должны присутствовать. Например:
set(CMAKE_LINK_LIBRARY_USING_weak_library
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)
Для всех трёх элементов этой переменной (<PREFIX>, <LIBRARY_EXPRESSION>, и <SUFFIX>) можно использовать префикс LINKER:.
Для передачи опций линковщику у каждого драйвера компилятора есть свой синтаксис. Префикс LINKER: и разделитель , могут использоваться для указания в переносимом виде опций для передачи линковщику. LINKER: заменяется соответствующей опцией драйвера, а , соответствующим разделителем драйвера. Префикс и разделитель драйвера задаются значениями переменных CMAKE_<LANG>_LINKER_WRAPPER_FLAG и CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP.
Например, "LINKER:-z,defs" становится -Xlinker -z -Xlinker defs для Clang и -Wl,-z,defs для GNU GCC.
Префикс LINKER: может быть указан как часть выражения префикса SHELL:.
Префикс LINKER: поддерживает, как альтернативный синтаксис, указание аргументов, используя префикс SHELL: и пробел в качестве разделителя. В этом случае предыдущий пример становится "LINKER:SHELL:-z defs".
Примечание
Указание префикса SHELL: в любом месте, кроме начала префикса LINKER:, не поддерживается.
Примеры
Загрузка всей статической библиотеки
Часто требуется предотвратить отбрасывание линковщиком каких-либо символов из статической библиотеки. Разные линковщики используют разные синтаксисы для достижения этого. Следующий пример показывает, как это можно реализовать для некоторых линковщиков. Обратите внимание, что это только для иллюстративных целей. Проекты должны использовать встроенную функцию WHOLE_ARCHIVE (см. Предопределённые функции), которая обеспечивает более полную и надёжную реализацию этой функциональности.
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>")
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive
"LINKER:--push-state,--whole-archive"
"<LINK_ITEM>"
"LINKER:--pop-state"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
else()
# feature not yet supported for the other environments
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED FALSE)
endif()
add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)
if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED)
# The -force_load Apple linker option requires a file name
set(external_lib
"$<IF:$<LINK_LANG_AND_ID:C,AppleClang>,libexternal.a,external>"
)
target_link_libraries(lib2 PRIVATE
"$<LINK_LIBRARY:load_archive,lib1,${external_lib}>"
)
else()
target_link_libraries(lib2 PRIVATE lib1 external)
endif()
CMake сгенерирует следующие выражения линковки:
-
AppleClang:-force_load /path/to/lib1.a -force_load libexternal.a -
GNU:-Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state -
MSVC:/WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib
Линковка библиотеки как слабой
В macOS можно линковать библиотеку в слабом режиме (библиотека и все ссылки помечены как слабые импорты). Для библиотеки, указанной по пути к файлу, и библиотеки, указанной по имени, должны использоваться разные флаги. Это ограничение можно решить, используя обёртки PATH{} и NAME{}. Опять же, следующий пример показывает, как это можно реализовать для некоторых линковщиков, но он предназначен только для иллюстративных целей. Проекты должны использовать встроенные функции WEAK_FRAMEWORK или WEAK_LIBRARY (см. Предопределённые функции), которые предоставляют более полные и надёжные реализации этой функциональности.
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(CMAKE_LINK_LIBRARY_USING_weak_library
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)
set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE)
endif()
add_library(lib SHARED ...)
add_executable(main ...)
if(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED)
target_link_libraries(main PRIVATE "$<LINK_LIBRARY:weak_library,lib,external>")
else()
target_link_libraries(main PRIVATE lib external)
endif()
CMake сгенерирует следующий фрагмент командной строки линковщика при линковке main с помощью инструментария AppleClang:
-weak_library /path/to/lib -Xlinker -weak-lexternal.
Предопределённые функции
Следующие встроенные функции библиотек предопределены CMake:
-
DEFAULT -
Эта функция соответствует стандартному связыванию, по сути, эквивалентному использованию без каких-либо дополнительных функций. Она обычно используется только с целевыми свойствами
LINK_LIBRARY_OVERRIDEиLINK_LIBRARY_OVERRIDE_<LIBRARY>. -
WHOLE_ARCHIVE -
Принудительное включение всех элементов статической библиотеки. Данная функция поддерживается только для следующих платформ с ограничениями, указанными ниже:
- Linux.
- Все варианты BSD.
- SunOS.
- Все варианты Apple. Библиотека должна быть указана как имя целевого объекта CMake, имя файла библиотеки (например,
libfoo.a) или путь к файлу библиотеки (например,/path/to/libfoo.a). Из-за ограничения Apple linker, она не может быть указана как простое имя библиотеки, например,foo, гдеfooне является целевым объектом CMake. - Windows. При использовании MSVC или аналогичной цепочки инструментов, версия MSVC должна быть больше 1900.
- Cygwin.
- MSYS.
-
FRAMEWORK -
Этот параметр сообщает линковщику искать указанную фреймворк-библиотеку, используя опцию линковщика
-framework. Он может быть использован только на платформах Apple и только с линковщиком, понимающим используемую опцию (т.е. линковщик, поставляемый с Xcode или совместимый с ним).Фреймворк может быть указан как целевой объект CMake, как простое имя фреймворка или как путь к файлу. Если указан целевой объект, то для этого объекта должно быть установлено свойство целевого объекта
FRAMEWORKсо значением true. Для пути к файлу, если он содержит часть пути к каталогу, этот каталог будет добавлен как путь к поиску фреймворка.add_library(lib SHARED ...) target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>") # The constructed linker command line will contain: # -F/path/to -framework my_framework
Пути к файлам должны соответствовать одному из следующих шаблонов (
*— символ подстановки, а необязательные части показаны как[...]):[/path/to/]FwName[.framework][/path/to/]FwName.framework/FwName[suffix][/path/to/]FwName.framework/Versions/*/FwName[suffix]
Обратите внимание, что CMake распознаёт и автоматически обрабатывает целевые объекты фреймворка, даже без использования выражения
$<LINK_LIBRARY:FRAMEWORK,...>. Выражение генератора всё равно можно использовать с целевым объектом CMake, если проект хочет быть явным, но это не обязательно. Командная строка линковщика может иметь некоторые различия при использовании или неиспользовании выражения генератора, но конечный результат должен быть одинаковым. С другой стороны, если задан путь к файлу, CMake будет автоматически распознавать некоторые пути, но не все случаи. Проект может захотеть использовать$<LINK_LIBRARY:FRAMEWORK,...>для путей к файлам, чтобы ожидаемое поведение было ясным.New in version 3.25: Свойство целевого объекта
FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>а такжеsuffixимени библиотеки фреймворка теперь поддерживаются функциямиFRAMEWORK. -
NEEDED_FRAMEWORK -
Это аналогично функции
FRAMEWORK, за исключением того, что она принуждает линковщик к линкованию с фреймворком даже если из него не используются никакие символы. Она использует опцию-needed_frameworkи имеет те же ограничения линковщика, что иFRAMEWORK. -
REEXPORT_FRAMEWORK -
Это аналогично функции
FRAMEWORK, за исключением того, что оно сообщает линковщику, что фреймворк должен быть доступен клиентам, ссылающимся на создаваемую библиотеку. Она использует опцию-reexport_frameworkи имеет те же ограничения линковщика, что иFRAMEWORK. -
WEAK_FRAMEWORK -
Это аналогично функции
FRAMEWORK, за исключением того, что она принуждает линковщик отмечать фреймворк и все ссылки на него как слабые импорты. Она использует опцию-weak_frameworkи имеет те же ограничения линковщика, что иFRAMEWORK. -
NEEDED_LIBRARY -
Это аналогично функции
NEEDED_FRAMEWORK, за исключением того, что оно предназначено для использования с целевыми объектами или библиотеками, не являющимися фреймворками (только для платформ Apple). Оно использует опцию-needed_libraryили-needed-lсоответственно и имеет те же ограничения линковщика, что иNEEDED_FRAMEWORK. -
REEXPORT_LIBRARY -
Это аналогично функции
REEXPORT_FRAMEWORK, за исключением того, что оно предназначено для использования с целевыми объектами или библиотеками, не являющимися фреймворками (только для платформ Apple). Оно использует опцию-reexport_libraryили-reexport-lсоответственно и имеет те же ограничения линковщика, что иREEXPORT_FRAMEWORK. -
WEAK_LIBRARY -
Это аналогично функции
WEAK_FRAMEWORK, за исключением того, что оно предназначено для использования с целевыми объектами или библиотеками, не являющимися фреймворками (только для платформ Apple). Оно использует опцию-weak_libraryили-weak-lсоответственно и имеет те же ограничения линковщика, что иWEAK_FRAMEWORK.
© 2000–2023 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.26/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.html