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 (см. Предопределённые функции ниже).
Определения функций
Определение функции библиотеки — это список, содержащий один или три элемента:
[<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–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.25/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.html