CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>
Новое в версии 3.24.
Эта переменная определяет способ подключения библиотеки или фреймворка для указанного <FEATURE> при использовании генераторного выражения LINK_LIBRARY и языке подключения для целевого объекта <LANG>. Для того, чтобы эта переменная имела какой-либо эффект, связанная переменная CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED должна быть установлена в значение true.
Для функций, не зависящих от языка подключения, должна быть определена переменная CMAKE_LINK_LIBRARY_USING_<FEATURE>.
Имена функций чувствительны к регистру и могут содержать только буквы, цифры и символы подчеркивания. Имена функций, определенные заглавными буквами, зарезервированы для встроенных функций CMake (см. Предопределенные функции ниже).
Некоторые аспекты поведения функции могут быть определены переменными CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES и CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES.
Определения функций
Определение функции библиотеки представляет собой список, содержащий один или три элемента:
[<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,...>для путей к файлам, чтобы ожидаемое поведение было ясным.Добавлен в версии 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–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.30/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.html