Spec-Zone.ru › CMake 3.25

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 не может быть истинным для языка линковки, используемого целевым объектом, для которого применяется генератор выражение 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,...> для путей к файлам, чтобы ожидаемое поведение было ясным.

Новое в версии 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_LINK_LIBRARY_USING_FEATURE.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API