Spec-Zone.ru › CMake 3.30

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 (см. Предопределённые функции ниже).

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

Spec-Zone.ru

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