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 (см. Предопределённые функции ниже).
Некоторые аспекты поведения функций могут быть определены переменными 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 -
Этот параметр сообщает linker о поиске указанной фреймворка с помощью параметра linker
-framework. Он может использоваться только на платформах Apple и только с linker, понимающим используемый параметр (т.е. linker, предоставленный 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, если проект хочет быть явным, но это не требуется. Команда linker может иметь некоторые различия между использованием выражения генератора или без него, но конечный результат должен быть одинаковым. С другой стороны, если задан путь к файлу, CMake будет распознавать некоторые пути автоматически, но не все случаи. Проект может использовать$<LINK_LIBRARY:FRAMEWORK,...>для путей к файлам, чтобы ожидаемое поведение было ясным.Добавлена в версии 3.25: Свойство целевого объекта
FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>, а такжеsuffixимени библиотеки фреймворка сейчас поддерживаются функциямиFRAMEWORK. -
NEEDED_FRAMEWORK -
Это аналогично функции
FRAMEWORK, за исключением того, что это принудительно связывает linker с фреймворком, даже если из него не используются никакие символы. Используется параметр-needed_framework, и у него те же ограничения linker, что и уFRAMEWORK. -
REEXPORT_FRAMEWORK -
Это аналогично функции
FRAMEWORK, за исключением того, что оно сообщает linker, что фреймворк должен быть доступен клиентам, связывающимся с создаваемой библиотекой. Используется параметр-reexport_framework, и у него те же ограничения linker, что и уFRAMEWORK. -
WEAK_FRAMEWORK -
Это аналогично функции
FRAMEWORK, за исключением того, что принудительно указывает linker пометить фреймворк и все ссылки на него как слабые импорты. Используется параметр-weak_framework, и у него те же ограничения linker, что и уFRAMEWORK. -
NEEDED_LIBRARY -
Это аналогично функции
NEEDED_FRAMEWORK, за исключением того, что оно предназначено для использования с целевыми объектами или библиотеками, не являющимися фреймворками (только платформы Apple). Используется параметр-needed_libraryили-needed-lсоответственно, и у него те же ограничения linker, что и уNEEDED_FRAMEWORK. -
REEXPORT_LIBRARY -
Это аналогично функции
REEXPORT_FRAMEWORK, за исключением того, что оно предназначено для использования с целевыми объектами или библиотеками, не являющимися фреймворками (только платформы Apple). Используется параметр-reexport_libraryили-reexport-lсоответственно, и у него те же ограничения linker, что и уREEXPORT_FRAMEWORK. -
WEAK_LIBRARY -
Это аналогично функции
WEAK_FRAMEWORK, за исключением того, что оно предназначено для использования с целевыми объектами или библиотеками, не являющимися фреймворками (только платформы Apple). Используется параметр-weak_libraryили-weak-lсоответственно, и у него те же ограничения linker, что и уWEAK_FRAMEWORK.
© 2000–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/latest/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.html