CMAKE__LINK_LIBRARY_USING_
Новое в версии 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–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.29/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.html