Spec-Zone.ru › CMake 3.24

cmake-generator-expressions(7)

  • Введение
  • Пробелы и кавычки
  • Отладка
  • Справочник по выражениям генератора

    • Условные выражения
    • Логические операторы
    • Основные выражения сравнения

      • Сравнение строк
      • Сравнение версий
    • Преобразования строк
    • Выражения списков
    • Выражения путей

      • Сравнение путей
      • Запросы к путям
      • Разложение путей
      • Преобразования путей
      • Пути оболочки
    • Выражения конфигурации
    • Выражения среды компиляции и языка

      • Платформа
      • Версия компилятора
      • Язык и идентификатор компилятора
      • Возможности компиляции
      • Язык и идентификатор компоновщика
      • Возможности компоновки
      • Контекст компоновки
    • Выражения, зависящие от целевого объекта
    • Выражения экспорта и установки
    • Многоуровневая оценка выражений
    • Экранированные символы
    • Устаревшие выражения

Введение

Выражения генератора оцениваются во время генерации системы сборки, чтобы получить информацию, специфичную для каждой конфигурации сборки. Они имеют вид $<...>. Например:

target_include_directories(tgt PRIVATE /opt/include/$<CXX_COMPILER_ID>)

Это будет расширено до /opt/include/GNU, /opt/include/Clang, и т.д., в зависимости от используемого C++ компилятора.

Выражения генератора допускаются в контексте многих свойств целевых объектов, таких как LINK_LIBRARIES, INCLUDE_DIRECTORIES, COMPILE_DEFINITIONS и другие. Они также могут использоваться при использовании команд для заполнения этих свойств, таких как target_link_libraries(), target_include_directories(), target_compile_definitions() и другие. Они позволяют условную компоновку, условные определения, используемые при компиляции, условные каталоги включения и многое другое. Условия могут быть основаны на конфигурации сборки, свойствах целевого объекта, информации о платформе или любой другой запрошиваемой информации.

Выражения генератора могут быть вложены:

target_compile_definitions(tgt PRIVATE
  $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,4.2.0>:OLD_COMPILER>
)

Вышеприведенное расширится до OLD_COMPILER если CMAKE_CXX_COMPILER_VERSION меньше 4.2.0.

Пробелы и кавычки

Выражения генератора обычно анализируются после аргументов команды. Если выражение генератора содержит пробелы, новые строки, точки с запятой или другие символы, которые могут интерпретироваться как разделители аргументов команды, все выражение должно быть заключено в кавычки при передаче команде. В противном случае выражение может быть разделено, и оно больше не будет распознаваться как выражение генератора.

При использовании add_custom_command() или add_custom_target(), используйте параметры VERBATIM и COMMAND_EXPAND_LISTS для получения надельного разделения и цитирования аргументов.

# WRONG: Embedded space will be treated as an argument separator.
# This ends up not being seen as a generator expression at all.
add_custom_target(run_some_tool
  COMMAND some_tool -I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>, -I>
  VERBATIM
)
# Better, but still not robust. Quotes prevent the space from splitting the
# expression. However, the tool will receive the expanded value as a single
# argument.
add_custom_target(run_some_tool
  COMMAND some_tool "-I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>, -I>"
  VERBATIM
)
# Nearly correct. Using a semicolon to separate arguments and adding the
# COMMAND_EXPAND_LISTS option means that paths with spaces will be handled
# correctly. Quoting the whole expression ensures it is seen as a generator
# expression. But if the target property is empty, we will get a bare -I
# with nothing after it.
add_custom_target(run_some_tool
  COMMAND some_tool "-I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,;-I>"
  COMMAND_EXPAND_LISTS
  VERBATIM
)

Использование переменных для построения более сложного выражения генератора также является хорошим способом уменьшить ошибки и улучшить читаемость. Приведенный выше пример можно дополнительно улучшить следующим образом:

# The $<BOOL:...> check prevents adding anything if the property is empty,
# assuming the property value cannot be one of CMake's false constants.
set(prop "$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>")
add_custom_target(run_some_tool
  COMMAND some_tool "$<$<BOOL:${prop}>:-I$<JOIN:${prop},;-I>>"
  COMMAND_EXPAND_LISTS
  VERBATIM
)

Частая ошибка заключается в попытке разбить выражение генератора на несколько строк с отступами:

# WRONG: New lines and spaces all treated as argument separators, so the
# generator expression is split and not recognized correctly.
target_compile_definitions(tgt PRIVATE
  $<$<AND:
      $<CXX_COMPILER_ID:GNU>,
      $<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>
    >:HAVE_5_OR_LATER>
)

Вместо этого используйте вспомогательные переменные с хорошо выбранными именами для построения понятного выражения:

set(is_gnu "$<CXX_COMPILER_ID:GNU>")
set(v5_or_later "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>")
set(meet_requirements "$<AND:${is_gnu},${v5_or_later}>")
target_compile_definitions(tgt PRIVATE
  "$<${meet_requirements}:HAVE_5_OR_LATER>"
)

Отладка

Поскольку выражения генератора оцениваются во время генерации системы сборки, а не во время обработки файлов CMakeLists.txt, невозможно проверить их результат с помощью команды message(). Один из возможных способов создания сообщений отладки — добавление пользовательского целевого объекта:

add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$<...>")

После выполнения cmake, вы можете создать целевой объект genexdebug, чтобы напечатать результат выражения $<...> (т.е. выполнить команду cmake --build ... --target genexdebug).

Другой способ — запись сообщений отладки в файл с помощью file(GENERATE):

file(GENERATE OUTPUT filename CONTENT "$<...>")

Справочник по выражениям генератора

Примечание

Этот справочник отличается от большей части документации CMake тем, что опускает угловые скобки <...> вокруг заполнительных значений, таких как condition, string, target, и т.д. Это предотвращает возможность неправильной интерпретации этих заполнительных значений как выражений генератора.

Условные выражения

Фундаментальная категория выражений генератора связана с условной логикой. Поддерживаются две формы условных выражений генератора:

$<condition:true_string>

Вычисляется как true_string если condition равно 1, или пустой строкой, если condition оценивается как 0. Любое другое значение для condition приводит к ошибке.

$<IF:condition,true_string,false_string>

Новое в версии 3.8.

Вычисляется как true_string если condition равно 1, или как false_string если condition равно 0. Любое другое значение для condition приводит к ошибке.

Обычно condition само по себе является выражением генератора. Например, следующее выражение расширяется до DEBUG_MODE при использовании конфигурации Debug, и до пустой строки во всех других конфигурациях:

$<$<CONFIG:Debug>:DEBUG_MODE>

Булевы значения condition кроме 1 или 0 могут обрабатываться с помощью выражения генератора $<BOOL:...>:

$<BOOL:string>

Преобразует string в 0 или 1. Вычисляется как 0 если выполняется хотя бы одно из следующих условий:

  • string пустое,
  • string (независимо от регистра) равно 0, FALSE, OFF, N, NO, IGNORE, или NOTFOUND, или
  • string заканчивается на -NOTFOUND (регистрозависимо).

В противном случае вычисляется как 1.

Выражение генератора $<BOOL:...> часто используется, когда condition предоставляется переменной CMake:

$<$<BOOL:${HAVE_SOME_FEATURE}>:-DENABLE_SOME_FEATURE>

Логические операторы

Поддерживаются обычные логические операторы:

$<AND:conditions>

где conditions — это список булевых выражений через запятую, все из которых должны быть либо 1, либо 0. Все выражение вычисляется как 1 если все условия 1. Если хотя бы одно условие 0, все выражение вычисляется как 0.

$<OR:conditions>

где conditions — это список логических выражений, разделённых запятыми. Все они должны вычисляться как 1 или 0. Весь выражение вычисляется как 1 , если хотя бы одно из conditions равно 1. Если все conditions вычисляются как 0, то всё выражение вычисляется как 0.

$<NOT:condition>

condition должен быть 0 или 1. Результат выражения — 0 если condition равно 1, иначе 1.

Основные выражения сравнения

CMake поддерживает различные выражения генератора для сравнения объектов. В этом разделе рассматриваются основные и наиболее часто используемые типы сравнений. Другие более специфические типы сравнения описаны в отдельных разделах ниже.

Сравнения строк

$<STREQUAL:string1,string2>

1 если string1 и string2 равны, иначе 0. Сравнение регистрозависимое. Для регистронезависимого сравнения комбинируйте с выражением генератора для преобразования строк. Например, следующее выражение вычисляется как 1 , если ${foo} равно любому из значений BAR, Bar, bar и т. д.

$<STREQUAL:$<UPPER_CASE:${foo}>,BAR>
$<EQUAL:value1,value2>

1 если value1 и value2 численно равны, иначе 0.

Сравнения версий

$<VERSION_LESS:v1,v2>

1 если v1 является версией меньше v2, иначе 0.

$<VERSION_GREATER:v1,v2>

1 если v1 является версией больше v2, иначе 0.

$<VERSION_EQUAL:v1,v2>

1 если v1 имеет ту же версию, что и v2, иначе 0.

$<VERSION_LESS_EQUAL:v1,v2>

Добавлена в версии 3.7.

1 если v1 является версией меньше или равной v2, иначе 0.

$<VERSION_GREATER_EQUAL:v1,v2>

Добавлена в версии 3.7.

1 если v1 является версией больше или равной v2, иначе 0.

Преобразования строк

$<LOWER_CASE:string>

Содержимое string преобразуется в нижний регистр.

$<UPPER_CASE:string>

Содержимое string преобразуется в верхний регистр.

$<MAKE_C_IDENTIFIER:...>

Содержимое ... преобразуется в идентификатор C. Преобразование выполняется аналогично поведению команды string(MAKE_C_IDENTIFIER).

Выражения списков

$<IN_LIST:string,list>

Добавлена в версии 3.12.

1 если string является элементом в списке, разделённом точкой с запятой list, иначе 0 . Используются регистрозависимые сравнения.

$<JOIN:list,string>

Объединяет список, вставляя содержимое string между каждым элементом.

$<REMOVE_DUPLICATES:list>

Добавлена в версии 3.15.

Удаляет дублирующиеся элементы в заданном списке list. Относительный порядок элементов сохраняется, но если встречаются дубликаты, сохраняется только первый экземпляр.

$<FILTER:list,INCLUDE|EXCLUDE,regex>

Добавлена в версии 3.15.

Включает или исключает элементы из списка list, которые соответствуют регулярному выражению regex.

Выражения путей

Большинство выражений в этом разделе тесно связаны с командой cmake_path(), предоставляя те же возможности, но в виде выражения генератора.

Для всех выражений генератора в этом разделе пути ожидаются в формате CMake. Выражение генератора $<PATH:CMAKE_PATH> может использоваться для преобразования системного пути в путь CMake-стиля.

Сравнения путей

$<PATH_EQUAL:path1,path2>

Добавлена в версии 3.24.

Сравнивает лексические представления двух путей. Никакая нормализация путей не выполняется. Возвращает 1 , если пути равны, 0 в противном случае.

См. cmake_path(COMPARE) для получения дополнительной информации.

Запросы к путям

Эти выражения обеспечивают возможности генерации, эквивалентные параметрам запроса к командам Запрос команды cmake_path(). Все пути ожидаются в формате CMake.

$<PATH:HAS_*,path>

Добавлена в версии 3.24.

Следующие операции возвращают 1 , если указанный компонент пути присутствует, 0 в противном случае. См. Структура и терминология путей для значения каждого компонента пути.

$<PATH:HAS_ROOT_NAME,path>
$<PATH:HAS_ROOT_DIRECTORY,path>
$<PATH:HAS_ROOT_PATH,path>
$<PATH:HAS_FILENAME,path>
$<PATH:HAS_EXTENSION,path>
$<PATH:HAS_STEM,path>
$<PATH:HAS_RELATIVE_PART,path>
$<PATH:HAS_PARENT_PATH,path>

Обратите внимание на следующие частные случаи:

  • Для HAS_ROOT_PATH, истинный результат будет возвращён только в том случае, если хотя бы один из root-name или root-directory не пуст.
  • Для HAS_PARENT_PATH, корневой каталог также считается имеющим родительский каталог, который будет сам по себе. Результат истинный, за исключением случая, когда путь состоит только из имени файла.
$<PATH:IS_ABSOLUTE,path>

Добавлена в версии 3.24.

Возвращает 1 , если путь является абсолютным, 0 в противном случае.

$<PATH:IS_RELATIVE,path>

Добавлена в версии 3.24.

Это вернёт противоположное значению IS_ABSOLUTE.

$<PATH:IS_PREFIX[,NORMALIZE],path,input>

Добавлена в версии 3.24.

Возвращает 1 , если path является префиксом input, 0 в противном случае.

Когда указан параметр NORMALIZE, path и input нормализуются перед проверкой.

Декомпозиция путей

Эти выражения предоставляют возможности генерации, эквивалентные параметрам Декомпозиция команды cmake_path(). Все пути ожидаются в формате CMake.

$<PATH:GET_*,...>

Добавлена в версии 3.24.

Следующие операции извлекают различные компоненты или группы компонентов из пути. См. Структура и терминология путей для значения каждого компонента пути.

$<PATH:GET_ROOT_NAME,path>
$<PATH:GET_ROOT_DIRECTORY,path>
$<PATH:GET_ROOT_PATH,path>
$<PATH:GET_FILENAME,path>
$<PATH:GET_EXTENSION[,LAST_ONLY],path>
$<PATH:GET_STEM[,LAST_ONLY],path>
$<PATH:GET_RELATIVE_PART,path>
$<PATH:GET_PARENT_PATH,path>

Если запрашиваемый компонент отсутствует в пути, возвращается пустая строка.

Преобразования путей

Эти выражения предоставляют возможности генерации, эквивалентные параметрам Модификация и Генерация команды cmake_path(). Все пути ожидаются в формате CMake.

$<PATH:CMAKE_PATH[,NORMALIZE],path>

Новая в версии 3.24.

Возвращает path. Если path — это путь операционной системы, он преобразуется в путь CMake со слешами вперёд (/). В Windows учитывается маркер длинного имени файла.

При указании параметра NORMALIZE, путь нормализуется после преобразования.

$<PATH:APPEND,path,input,...>

Новая в версии 3.24.

Возвращает все аргументы input , добавленные к path с использованием / в качестве directory-separator. В зависимости от input, значение path может быть отброшено.

См. cmake_path(APPEND) для получения более подробной информации.

$<PATH:REMOVE_FILENAME,path>

Новая в версии 3.24.

Возвращает path с удалённой частью имени файла (как возвращается $<PATH:GET_FILENAME>). После удаления любые завершающие directory-separator остаются без изменений, если присутствуют.

См. cmake_path(REMOVE_FILENAME) для получения более подробной информации.

$<PATH:REPLACE_FILENAME,path,input>

Новая в версии 3.24.

Возвращает path с заменой компонента имени файла на input. Если path не имеет компонента имени файла (т.е. $<PATH:HAS_FILENAME> возвращает 0 ), path остаётся без изменений.

См. cmake_path(REPLACE_FILENAME) для получения более подробной информации.

$<PATH:REMOVE_EXTENSION[,LAST_ONLY],path>

Новая в версии 3.24.

Возвращает path с удалённым расширением, если таковое имеется.

См. cmake_path(REMOVE_EXTENSION) для получения более подробной информации.

$<PATH:REPLACE_EXTENSION[,LAST_ONLY],path,input>

Новая в версии 3.24.

Возвращает path с заменой расширения на input, если таковое имеется.

См. cmake_path(REPLACE_EXTENSION) для получения более подробной информации.

$<PATH:NORMAL_PATH,path>

Новая в версии 3.24.

Возвращает path , нормализованный в соответствии с этапами, описанными в Нормализация.

$<PATH:RELATIVE_PATH,path,base_directory>

Новая в версии 3.24.

Возвращает path, изменённый для того, чтобы сделать его относительным к аргументу base_directory.

См. cmake_path(RELATIVE_PATH) для получения более подробной информации.

$<PATH:ABSOLUTE_PATH[,NORMALIZE],path,base_directory>

Новая в версии 3.24.

Возвращает path как абсолютный. Если path — относительный путь ($<PATH:IS_RELATIVE> возвращает 1 ), он оценивается относительно указанного базового каталога, заданного аргументом base_directory.

При указании параметра NORMALIZE, путь нормализуется после вычисления пути.

См. cmake_path(ABSOLUTE_PATH) для получения более подробной информации.

Пути оболочки

$<SHELL_PATH:...>

Новая в версии 3.4.

Содержимое ... преобразуется в стиль пути оболочки. Например, слеши преобразуются в обратные слеши в оболочках Windows, а буквы диска преобразуются в пути POSIX в оболочках MSYS. ... должен быть абсолютным путем.

Новая в версии 3.14: ... может быть списком, разделённым точкой с запятой путей, в этом случае каждый путь преобразуется индивидуально, а список результатов генерируется с использованием разделителя путей оболочки (: на POSIX и ; в Windows). Убедитесь, что аргумент, содержащий этот genex, заключён в двойные кавычки в коде CMake, чтобы ; не разделял аргументы.

Выражения конфигурации

$<CONFIG>

Имя конфигурации. Используйте его вместо устаревшего выражения генератора CONFIGURATION.

$<CONFIG:cfgs>

1 , если config соответствует одному из элементов в списке, разделённом запятой cfgs, в противном случае 0. Это сравнение не учитывает регистр. Сопоставление в MAP_IMPORTED_CONFIG_<CONFIG> также учитывается этим выражением при его оценке на свойстве цели IMPORTED.

$<OUTPUT_CONFIG:...>

Новая в версии 3.20.

Действителен только в add_custom_command() и add_custom_target() в качестве внешнего выражения генератора в аргументе. С генератором Ninja Multi-Config, выражения генератора в ... оцениваются с использованием "конфигурации вывода" пользовательской команды. С другими генераторами содержимое ... оценивается обычно.

$<COMMAND_CONFIG:...>

Новая в версии 3.20.

Действителен только в add_custom_command() и add_custom_target() в качестве внешнего выражения генератора в аргументе. С генератором Ninja Multi-Config, выражения генератора в ... оцениваются с использованием "конфигурации команды" пользовательской команды. С другими генераторами содержимое ... оценивается обычно.

Выражения инструментальной цепочки и языка

Платформа

$<PLATFORM_ID>

Идентификатор платформы CMake текущей системы. Также см. переменную CMAKE_SYSTEM_NAME.

END_OF_DOCUMENT_MARKER
$<PLATFORM_ID:platform_ids>

где platform_ids — список, разделённый запятыми. 1 если идентификатор платформы CMake соответствует одному из элементов в platform_ids, в противном случае 0. См. также переменную CMAKE_SYSTEM_NAME.

Версия компилятора

См. также переменную CMAKE_<LANG>_COMPILER_VERSION, которая тесно связана с выражениями в этом подразделе.

$<C_COMPILER_VERSION>

Версия используемого компилятора C.

$<C_COMPILER_VERSION:version>

1 если версия компилятора C соответствует version, в противном случае 0.

$<CXX_COMPILER_VERSION>

Версия используемого компилятора CXX.

$<CXX_COMPILER_VERSION:version>

1 если версия компилятора CXX соответствует version, в противном случае 0.

$<CUDA_COMPILER_VERSION>

Новая в версии 3.15.

Версия используемого компилятора CUDA.

$<CUDA_COMPILER_VERSION:version>

Новая в версии 3.15.

1 если версия компилятора CXX соответствует version, в противном случае 0.

$<OBJC_COMPILER_VERSION>

Новая в версии 3.16.

Версия используемого компилятора OBJC.

$<OBJC_COMPILER_VERSION:version>

Новая в версии 3.16.

1 если версия компилятора OBJC соответствует version, в противном случае 0.

$<OBJCXX_COMPILER_VERSION>

Новая в версии 3.16.

Версия используемого компилятора OBJCXX.

$<OBJCXX_COMPILER_VERSION:version>

Новая в версии 3.16.

1 если версия компилятора OBJCXX соответствует version, в противном случае 0.

$<Fortran_COMPILER_VERSION>

Версия используемого компилятора Fortran.

$<Fortran_COMPILER_VERSION:version>

1 если версия компилятора Fortran соответствует version, в противном случае 0.

$<HIP_COMPILER_VERSION>

Новая в версии 3.21.

Версия используемого компилятора HIP.

$<HIP_COMPILER_VERSION:version>

Новая в версии 3.21.

1 если версия компилятора HIP соответствует version, в противном случае 0.

$<ISPC_COMPILER_VERSION>

Новая в версии 3.19.

Версия используемого компилятора ISPC.

$<ISPC_COMPILER_VERSION:version>

Новая в версии 3.19.

1 если версия компилятора ISPC соответствует version, в противном случае 0.

Язык и идентификатор компилятора

См. также переменную CMAKE_<LANG>_COMPILER_ID, которая тесно связана с большинством выражений в этом подразделе.

$<C_COMPILER_ID>

Идентификатор компилятора C, используемый CMake.

$<C_COMPILER_ID:compiler_ids>

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора C CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<CXX_COMPILER_ID>

Идентификатор компилятора CXX, используемый CMake.

$<CXX_COMPILER_ID:compiler_ids>

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора CXX CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<CUDA_COMPILER_ID>

Новая в версии 3.15.

Идентификатор компилятора CUDA, используемый CMake.

$<CUDA_COMPILER_ID:compiler_ids>

Новая в версии 3.15.

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора CUDA CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<OBJC_COMPILER_ID>

Новая в версии 3.16.

Идентификатор компилятора OBJC, используемый CMake.

$<OBJC_COMPILER_ID:compiler_ids>

Новая в версии 3.16.

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора Objective-C CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<OBJCXX_COMPILER_ID>

Новая в версии 3.16.

Идентификатор компилятора OBJCXX, используемый CMake.

$<OBJCXX_COMPILER_ID:compiler_ids>

Новая в версии 3.16.

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора Objective-C++ CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<Fortran_COMPILER_ID>

Идентификатор компилятора Fortran, используемый CMake.

$<Fortran_COMPILER_ID:compiler_ids>

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора Fortran CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<HIP_COMPILER_ID>

Новая в версии 3.21.

Идентификатор компилятора HIP, используемый CMake.

$<HIP_COMPILER_ID:compiler_ids>

Новая в версии 3.21.

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора HIP CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

$<ISPC_COMPILER_ID>

Новая в версии 3.19.

Идентификатор компилятора ISPC, используемый CMake.

$<ISPC_COMPILER_ID:compiler_ids>

Новая в версии 3.19.

где compiler_ids — список, разделённый запятыми. 1 если идентификатор компилятора ISPC CMake соответствует одному из элементов в compiler_ids, в противном случае 0.

END_OF_DOCUMENT_MARKER
$<COMPILE_LANGUAGE>

Новое в версии 3.3.

Язык компиляции исходных файлов при оценке параметров компиляции. См. соответствующее логическое выражение $<COMPILE_LANGUAGE:language> для примечаний о переносимости этого выражения генератора.

$<COMPILE_LANGUAGE:languages>

Новое в версии 3.3.

1 если язык, используемый для единицы компиляции, соответствует одному из элементов в languages, иначе 0. Это выражение может использоваться для указания параметров компиляции, определений компиляции и каталогов заголовков для исходных файлов определённого языка в целевом объекте. Например:

add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
target_compile_options(myapp
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
)
target_compile_definitions(myapp
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
          $<$<COMPILE_LANGUAGE:CUDA>:COMPILING_CUDA>
)
target_include_directories(myapp
  PRIVATE $<$<COMPILE_LANGUAGE:CXX,CUDA>:/opt/foo/headers>
)

Это указывает на использование параметра компиляции -fno-exceptions, определение компиляции COMPILING_CXX и каталог заголовков cxx_headers только для C++. (Проверки идентификаторов компилятора опущены). Также это указывает определение компиляции COMPILING_CUDA для CUDA.

Обратите внимание, что с генераторами Visual Studio и Xcode нет способа представить определения компиляции или каталоги заголовков для всего целевого объекта отдельно для языков C и CXX. Также с генераторами Visual Studio нет способа представить флаги целевого объекта отдельно для языков C и CXX. В этих генераторах выражения для исходных файлов C и C++ будут оцениваться с использованием CXX если есть исходные файлы C++, и в противном случае с использованием C. Решение - создать отдельные библиотеки для каждого языка исходных файлов:

add_library(myapp_c foo.c)
add_library(myapp_cxx bar.cpp)
target_compile_options(myapp_cxx PUBLIC -fno-exceptions)
add_executable(myapp main.cpp)
target_link_libraries(myapp myapp_c myapp_cxx)
$<COMPILE_LANG_AND_ID:language,compiler_ids>

Новое в версии 3.15.

1 если язык, используемый для единицы компиляции, соответствует language и идентификатор компилятора CMake для компилятора language соответствует одному из элементов в compiler_ids, иначе 0. Это выражение является сокращённой формой комбинации $<COMPILE_LANGUAGE:language> и $<LANG_COMPILER_ID:compiler_ids>. Это выражение может использоваться для указания параметров компиляции, определений компиляции и каталогов заголовков для исходных файлов определённого языка и компилятора в целевом объекте. Например:

add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
target_compile_definitions(myapp
  PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:COMPILING_CXX_WITH_CLANG>
          $<$<COMPILE_LANG_AND_ID:CXX,Intel>:COMPILING_CXX_WITH_INTEL>
          $<$<COMPILE_LANG_AND_ID:C,Clang>:COMPILING_C_WITH_CLANG>
)

Это указывает на использование различных определений компиляции, основанных как на идентификаторе компилятора, так и на языке компиляции. В этом примере будет использоваться определение компиляции COMPILING_CXX_WITH_CLANG когда Clang является компилятором C++, и COMPILING_CXX_WITH_INTEL когда Intel является компилятором C++. Аналогично, когда компилятор C является Clang, он увидит только определение COMPILING_C_WITH_CLANG.

Без выражения генератора COMPILE_LANG_AND_ID та же логика выражалась бы как:

target_compile_definitions(myapp
  PRIVATE $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:AppleClang,Clang>>:COMPILING_CXX_WITH_CLANG>
          $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:Intel>>:COMPILING_CXX_WITH_INTEL>
          $<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:Clang>>:COMPILING_C_WITH_CLANG>
)

Compile Features

$<COMPILE_FEATURES:features>

Новое в версии 3.1.

где features - это список, разделённый запятыми. Принимает значение 1 если все features доступны для целевого объекта 'head', и 0 в противном случае. Если это выражение используется при оценке реализации связи целевого объекта, и если какая-либо зависимость транзитивно увеличивает требуемые C_STANDARD или CXX_STANDARD для целевого объекта 'head', будет выдано сообщение об ошибке. См. руководство cmake-compile-features(7) для получения информации о функциях компиляции и списка поддерживаемых компиляторов.

Linker Language And ID

$<LINK_LANGUAGE>

Новое в версии 3.18.

Язык компоновки целевого объекта при оценке параметров компоновки. См. соответствующее логическое выражение $<LINK_LANGUAGE:languages> для примечаний о переносимости этого выражения генератора.

Примечание

Это выражение генератора не поддерживается свойствами библиотек компоновки для предотвращения побочных эффектов из-за двойной оценки этих свойств.

$<LINK_LANGUAGE:languages>

Новое в версии 3.18.

1 если язык, используемый для шага компоновки, соответствует одному из элементов в languages, иначе 0. Это выражение может использоваться для указания библиотек компоновки, параметров компоновки, каталогов компоновки и зависимостей компоновки для определённого языка в целевом объекте. Например:

add_library(api_C ...)
add_library(api_CXX ...)
add_library(api INTERFACE)
target_link_options(api   INTERFACE $<$<LINK_LANGUAGE:C>:-opt_c>
                                    $<$<LINK_LANGUAGE:CXX>:-opt_cxx>)
target_link_libraries(api INTERFACE $<$<LINK_LANGUAGE:C>:api_C>
                                    $<$<LINK_LANGUAGE:CXX>:api_CXX>)

add_executable(myapp1 main.c)
target_link_options(myapp1 PRIVATE api)

add_executable(myapp2 main.cpp)
target_link_options(myapp2 PRIVATE api)

Это указывает на использование целевого объекта api для компоновки целевых объектов myapp1 и myapp2. На практике, myapp1 будет компоноваться с целевым объектом api_C и параметром -opt_c, потому что он будет использовать C в качестве языка компоновки. И myapp2 будет компоноваться с api_CXX и параметром -opt_cxx, потому что CXX будет языком компоновки.

Примечание

Для определения языка компоновки целевого объекта необходимо собрать, транзитивно, все целевые объекты, которые будут компоноваться с ним. Таким образом, для свойств библиотек компоновки будет выполнена двойная оценка. При первой оценке выражения $<LINK_LANGUAGE:..> всегда возвращают 0. Вычисленный язык компоновки после этого первого прохода будет использован для второго прохода. Для предотвращения несоответствий необходимо, чтобы второй проход не изменял язык компоновки. Кроме того, для предотвращения неожиданных побочных эффектов необходимо указывать полные сущности в качестве части выражения $<LINK_LANGUAGE:..>. Например:

add_library(lib STATIC file.cxx)
add_library(libother STATIC file.c)

# bad usage
add_executable(myapp1 main.c)
target_link_libraries(myapp1 PRIVATE lib$<$<LINK_LANGUAGE:C>:other>)

# correct usage
add_executable(myapp2 main.c)
target_link_libraries(myapp2 PRIVATE $<$<LINK_LANGUAGE:C>:libother>)

В этом примере для myapp1, первый проход неожиданно определит, что языком компоновки является CXX, так как вычисление выражения генератора будет пустой строкой, поэтому myapp1 будет зависеть от целевого объекта lib, который является C++. Напротив, для myapp2, первая оценка даст C в качестве языка компоновки, поэтому второй проход правильно добавит целевой объект libother в качестве зависимости компоновки.

$<LINK_LANG_AND_ID:language,compiler_ids>

Новое в версии 3.18.

1 если язык, используемый для шага компоновки, соответствует language и идентификатор компилятора CMake для линкера языка соответствует одному из элементов в compiler_ids, иначе 0. Это выражение является сокращённой формой комбинации $<LINK_LANGUAGE:language> и $<LANG_COMPILER_ID:compiler_ids>. Это выражение может использоваться для указания библиотек компоновки, параметров компоновки, каталогов компоновки и зависимостей компоновки для определённого языка и компилятора в целевом объекте. Например:

add_library(libC_Clang ...)
add_library(libCXX_Clang ...)
add_library(libC_Intel ...)
add_library(libCXX_Intel ...)

add_executable(myapp main.c)
if (CXX_CONFIG)
  target_sources(myapp PRIVATE file.cxx)
endif()
target_link_libraries(myapp
  PRIVATE $<$<LINK_LANG_AND_ID:CXX,Clang,AppleClang>:libCXX_Clang>
          $<$<LINK_LANG_AND_ID:C,Clang,AppleClang>:libC_Clang>
          $<$<LINK_LANG_AND_ID:CXX,Intel>:libCXX_Intel>
          $<$<LINK_LANG_AND_ID:C,Intel>:libC_Intel>)

Это указывает на использование различных библиотек компоновки, основанных как на идентификаторе компилятора, так и на языке компоновки. В этом примере целевой объект libCXX_Clang будет зависимостью компоновки, когда Clang или AppleClang является линкером CXX, и libCXX_Intel когда Intel является линкером CXX. Аналогично, когда C линкером является Clang или AppleClang, целевой объект libC_Clang будет добавлен в качестве зависимости компоновки и libC_Intel когда Intel является линкером C.

См. примечание, относящееся к $<LINK_LANGUAGE:language> для ограничений использования этого выражения генератора.

Link Features

$<LINK_LIBRARY:feature,library-list>

Новое в версии 3.24.

Укажите набор библиотек для связи с целевым объектом, а также feature, который предоставляет информацию о том, как их следует связать. Например:

add_library(lib1 STATIC ...)
add_library(lib2 ...)
target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,lib1>")

Это указывает, что lib2 должен связаться с lib1 и использовать функцию WHOLE_ARCHIVE при этом.

Имена функций чувствительны к регистру и могут содержать только буквы, цифры и символы подчеркивания. Имена функций, определенные в верхнем регистре, зарезервированы для собственных встроенных функций 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
  • [/path/to/]FwName.framework/Versions/*/FwName

Обратите внимание, что CMake распознает и автоматически обрабатывает целевые объекты фреймворка, даже без использования выражения $<LINK_LIBRARY:FRAMEWORK,...>. Выражение генератора всё ещё может быть использовано с целевым объектом CMake, если проект хочет быть явным в этом вопросе, но это не обязательно. Командная строка Linker может иметь некоторые различия между использованием выражения генератора или без него, но конечный результат должен быть одинаковым. С другой стороны, если указан путь к файлу, CMake будет автоматически распознавать некоторые пути, но не все случаи. Проект может использовать $<LINK_LIBRARY: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.

Встроенные и пользовательские функции библиотек определяются в терминах следующих переменных:

  • CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED
  • CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>
  • CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED
  • CMAKE_LINK_LIBRARY_USING_<FEATURE>

Значение, используемое для каждой из этих переменных, - это значение, установленное в конце области каталога, в которой был создан целевой объект. Использование следующее:

  1. Если языковая переменная CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED имеет значение true, переменная feature должна быть определена соответствующей переменной CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>.
  2. Если какая-либо языковая поддержка feature не поддерживается, то переменная CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED должна иметь значение true, и переменная feature должна быть определена соответствующей переменной CMAKE_LINK_LIBRARY_USING_<FEATURE>.

Следует отметить следующие ограничения:

  • library-list может указывать целевые объекты или библиотеки CMake. Любой целевой объект CMake типа OBJECT или INTERFACE проигнорирует аспект функции выражения и вместо этого будет связан стандартным способом.
  • Выражение генератора $<LINK_LIBRARY:...> может быть использовано только для указания связанных библиотек. На практике это означает, что оно может появляться в целевых свойствах LINK_LIBRARIES, INTERFACE_LINK_LIBRARIES и INTERFACE_LINK_LIBRARIES_DIRECT, и быть указано в командах target_link_libraries() и link_libraries().
  • Если выражение генератора $<LINK_LIBRARY:...> появляется в свойстве INTERFACE_LINK_LIBRARIES целевого объекта, оно будет включено в импортированный целевой объект, сгенерированный командой install(EXPORT). Ответственность по определению функции связи, используемой этим выражением, лежит на окружающей среде, использующей этот импорт.
  • Каждый целевой объект или библиотека, участвующая в шаге связи, должны иметь не более одного типа функции библиотеки. Отсутствие функции также несовместимо со всеми другими функциями. Например:

    add_library(lib1 ...)
    add_library(lib2 ...)
    add_library(lib3 ...)
    
    # lib1 will be associated with feature1
    target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>")
    
    # lib1 is being linked with no feature here. This conflicts with the
    # use of feature1 in the line above and would result in an error.
    target_link_libraries(lib3 PRIVATE lib1 lib2)
    

    Когда невозможно использовать одну и ту же функцию на протяжении всего построения для данного целевого объекта или библиотеки, целевые свойства LINK_LIBRARY_OVERRIDE и LINK_LIBRARY_OVERRIDE_<LIBRARY> могут быть использованы для разрешения таких несоответствий.

  • Выражение генератора $<LINK_LIBRARY:...> не гарантирует, что список указанных целевых объектов и библиотек будет сохранён вместе. Для управления конструкциями, такими как --start-group и --end-group, которые поддерживаются Linker GNU ld, используйте выражение генератора LINK_GROUP вместо этого.
$<LINK_GROUP:feature,library-list>

Новое в версии 3.24.

Укажите группу библиотек для связывания с целевым объектом, вместе с feature, который определяет, как эта группа должна быть связана. Например:

add_library(lib1 STATIC ...)
add_library(lib2 ...)
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:RESCAN,lib1,external>")

Это указывает, что lib2 должен быть связан с lib1 и external, и что обе эти библиотеки должны быть включены в командной строке компоновщика в соответствии с определением функции RESCAN.

Имена функций чувствительны к регистру и могут содержать только буквы, цифры и символы подчеркивания. Имена функций, определенные в верхнем регистре, зарезервированы для собственных встроенных функций CMake. В настоящее время существует только одна предопределенная встроенная функция группы:

RESCAN

Некоторые компоновщики работают только в один проход. Для таких компоновщиков циклические ссылки между библиотеками обычно приводят к неразрешенным символам. Эта функция указывает компоновщику многократно искать указанные статические библиотеки до тех пор, пока не будут созданы новые неразрешенные ссылки.

Обычно статическая библиотека ищется только один раз в порядке, в котором она указана в командной строке. Если символ в этой библиотеке необходим для разрешения неразрешенного символа, на который ссылается объект в библиотеке, которая появляется позже в командной строке, компоновщик не сможет разрешить эту ссылку. Группируя статические библиотеки с помощью функции RESCAN, все они будут многократно просматриваться до тех пор, пока не будут разрешены все возможные ссылки. Это будет использовать такие параметры компоновщика, как --start-group и --end-group, или на SunOS, -z rescan-start и -z rescan-end.

Использование этой функции имеет значительную стоимость производительности. Лучше всего использовать ее только тогда, когда неизбежны циклические ссылки между двумя или более статическими библиотеками.

Эта функция доступна при использовании инструментальных цепочек, нацеленных на Linux, BSD и SunOS. Она также может быть использована при нацеливании на платформы Windows, если используется инструментальная цепочка GNU.

Встроенные и настраиваемые функции группы определяются в терминах следующих переменных:

  • CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED
  • CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>
  • CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED
  • CMAKE_LINK_GROUP_USING_<FEATURE>

Значение, используемое для каждой из этих переменных, — это значение, установленное в конце области каталога, в которой был создан целевой объект. Использование выглядит следующим образом:

  1. Если языковая переменная CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED имеет значение true, то переменная feature должна быть определена соответствующей переменной CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>.
  2. Если для языка не поддерживается feature, то переменная CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED должна иметь значение true, а переменная feature должна быть определена соответствующей переменной CMAKE_LINK_GROUP_USING_<FEATURE>.

Выражение генератора LINK_GROUP совместимо с выражением генератора LINK_LIBRARY. Библиотеки, участвующие в группе, могут быть указаны с помощью выражения генератора LINK_LIBRARY.

Каждый целевой объект или внешняя библиотека, участвующая в шаге связывания, может быть частью нескольких групп, но только если все участвующие группы указывают один и тот же feature. Такие группы не будут объединены в командной строке компоновщика, отдельные группы все равно будут сохранены. Смешивание различных функций групп для одного и того же целевого объекта или библиотеки запрещено.

add_library(lib1 ...)
add_library(lib2 ...)
add_library(lib3 ...)
add_library(lib4 ...)
add_library(lib5 ...)

target_link_libraries(lib3 PUBLIC  "$<LINK_GROUP:feature1,lib1,lib2>")
target_link_libraries(lib4 PRIVATE "$<LINK_GROUP:feature1,lib1,lib3>")
# lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3}.
# Both groups specify the same feature, so this is fine.

target_link_libraries(lib5 PRIVATE "$<LINK_GROUP:feature2,lib1,lib3>")
# An error will be raised here because both lib1 and lib3 are part of two
# groups with different features.

Если целевой объект или внешняя библиотека участвует в шаге связывания как часть группы и также не входит в какую-либо группу, любое появление элемента связывания, не относящегося к группе, будет заменено группами, к которым он принадлежит.

add_library(lib1 ...)
add_library(lib2 ...)
add_library(lib3 ...)
add_library(lib4 ...)

target_link_libraries(lib3 PUBLIC lib1)

target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
# lib4 will only be linked with lib3 and the group {lib1,lib2}

Поскольку lib1 входит в группу, определенную для lib4, эта группа затем применяется к использованию lib1 для lib3. Конечный результат будет таким, как если бы отношение связывания для lib3 было указано как:

target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")

Обратите внимание, что приоритет группы над элементом связывания, не относящимся к группе, может привести к циклическим зависимостям между группами. Если это произойдёт, возникает ошибка, так как циклические зависимости для групп недопустимы.

add_library(lib1A ...)
add_library(lib1B ...)
add_library(lib2A ...)
add_library(lib2B ...)
add_library(lib3 ...)

# Non-group linking relationships, these are non-circular so far
target_link_libraries(lib1A PUBLIC lib2A)
target_link_libraries(lib2B PUBLIC lib1B)

# The addition of these groups creates circular dependencies
target_link_libraries(lib3 PRIVATE
  "$<LINK_GROUP:feat,lib1A,lib1B>"
  "$<LINK_GROUP:feat,lib2A,lib2B>"
)

Из-за групп, определённых для lib3, отношения связывания для lib1A и lib2B фактически расширяются до эквивалента:

target_link_libraries(lib1A PUBLIC "$<LINK_GROUP:feat,lib2A,lib2B>")
target_link_libraries(lib2B PUBLIC "$<LINK_GROUP:feat,lib1A,lib1B>")

Это создает циклическую зависимость между группами: lib1A --> lib2B --> lib1A.

Также следует учитывать следующие ограничения:

  • library-list может указывать целевые объекты или библиотеки CMake. Любой целевой объект CMake типа OBJECT или INTERFACE проигнорирует аспект функции выражения и вместо этого будет связан стандартным способом.
  • Выражение генератора $<LINK_GROUP:...> может использоваться только для указания библиотек связывания. На практике это означает, что оно может появляться в свойствах целевого объекта LINK_LIBRARIES, INTERFACE_LINK_LIBRARIES и INTERFACE_LINK_LIBRARIES_DIRECT, и быть указанным в командах target_link_libraries() и link_libraries().
  • Если выражение генератора $<LINK_GROUP:...> появляется в свойстве INTERFACE_LINK_LIBRARIES целевого объекта, оно будет включено в импортированный целевой объект, сгенерированный командой install(EXPORT). Ответственность по определению функции связывания, используемой этим выражением, лежит на среде, потребляющей этот импорт.

Контекст связывания

$<LINK_ONLY:...>

Новое в версии 3.1.

Содержимое ..., за исключением сбора Требований к использованию зависимостей, в этом случае это пустая строка. Это предназначено для использования в свойстве целевого объекта INTERFACE_LINK_LIBRARIES, обычно заполняемом командой target_link_libraries(), для указания частных зависимостей связывания без других требований к использованию.

Новое в версии 3.24: LINK_ONLY также может быть использовано в свойстве целевого объекта LINK_LIBRARIES. См. политику CMP0131.

$<DEVICE_LINK:list>

Новое в версии 3.18.

Возвращает список, если это этап связывания устройства, в противном случае пустой список. Этап связывания устройства контролируется свойствами CUDA_SEPARABLE_COMPILATION и CUDA_RESOLVE_DEVICE_SYMBOLS и политикой CMP0105. Это выражение может использоваться только для указания параметров связывания.

$<HOST_LINK:list>

Новое в версии 3.18.

Возвращает список, если это обычная стадия линковки, в противном случае пустой список. Это выражение полезно в основном, когда также участвует стадия линковки устройства (см. выражение генератора $<DEVICE_LINK:list>). Это выражение можно использовать только для указания параметров линковки.

Зависимые от целевых выражения

Эти запросы относятся к целевому tgt. Если не указано иное, это может быть любой артефакт выполнения, а именно:

  • Целевой исполняемый файл, созданный с помощью add_executable().
  • Целевой общий модуль (.so, .dll но не их .lib импортная библиотека) созданный с помощью add_library().
  • Целевой статический модуль, созданный с помощью add_library().

В дальнейшем фраза «имя файла целевого исполняемого файла» означает имя файла двоичного файла целевого исполняемого файла. Это следует отличать от фразы «имя целевого объекта», которая просто представляет собой строку tgt.

$<TARGET_EXISTS:tgt>

Новое в версии 3.12.

1 если tgt существует как целевой объект CMake, иначе 0.

$<TARGET_NAME_IF_EXISTS:tgt>

Новое в версии 3.12.

Имя целевого объекта tgt если целевой объект существует, в противном случае пустая строка.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение.

$<TARGET_NAME:...>

Помечает ... как имя целевого объекта. Это требуется при экспорте целевых объектов в несколько зависимых наборов экспорта. ... должно быть буквальным именем целевого объекта, оно не может содержать выражения генератора.

$<TARGET_PROPERTY:tgt,prop>

Значение свойства prop для целевого объекта tgt.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение.

$<TARGET_PROPERTY:prop>

Значение свойства prop для целевого объекта, для которого вычисляется выражение. Обратите внимание, что для выражений генератора в Требования к использованию целевого объекта это целевой объект, использующий требование, а не целевой объект, определяющий требование.

$<TARGET_OBJECTS:tgt>

Новое в версии 3.1.

Список объектов, полученных в результате построения tgt. Это обычно используется для целевых объектов библиотека объектов.

$<TARGET_POLICY:policy>

1 если policy было NEW при создании целевого объекта 'head', иначе 0. Если policy не было установлено, будет выведено сообщение об ошибке для политики. Это выражение генератора работает только для подмножества политик.

$<TARGET_FILE:tgt>

Полный путь к файлу двоичного файла целевого объекта.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение, если выражение не используется в add_custom_command() или add_custom_target().

$<TARGET_FILE_BASE_NAME:tgt>

Новое в версии 3.15.

Базовое имя tgt, т.е. $<TARGET_FILE_NAME:tgt> без префикса и суффикса. Например, если имя файла целевого объекта — libbase.so, базовое имя — base.

См. также свойства целевого объекта OUTPUT_NAME, ARCHIVE_OUTPUT_NAME, LIBRARY_OUTPUT_NAME и RUNTIME_OUTPUT_NAME и их конфигурационно-специфичные варианты OUTPUT_NAME_<CONFIG>, ARCHIVE_OUTPUT_NAME_<CONFIG>, LIBRARY_OUTPUT_NAME_<CONFIG> и RUNTIME_OUTPUT_NAME_<CONFIG>.

Свойства целевого объекта <CONFIG>_POSTFIX и DEBUG_POSTFIX также могут быть рассмотрены.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение.

$<TARGET_FILE_PREFIX:tgt>

Новое в версии 3.15.

Префикс имени файла целевого объекта (например, lib).

См. также свойство целевого объекта PREFIX.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение.

$<TARGET_FILE_SUFFIX:tgt>

Новое в версии 3.15.

Суффикс имени файла целевого объекта (расширение, например, .so или .exe).

См. также свойство целевого объекта SUFFIX.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение.

$<TARGET_FILE_NAME:tgt>

Имя файла целевого объекта.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение (см. политику CMP0112).

$<TARGET_FILE_DIR:tgt>

Директория файла двоичного файла целевого объекта.

Обратите внимание, что tgt не добавляется в качестве зависимости от целевого объекта, для которого вычисляется это выражение (см. политику CMP0112).

$<TARGET_LINKER_FILE:tgt>

Файл, используемый при линковке с целевым объектом tgt. Обычно это будет библиотека, которую tgt представляет (.a, .lib, .so). Но для общего модуля на платформах DLL это будет импортная библиотека DLL, связанная с DLL.

END_OF_DOCUMENT_MARKER
$<TARGET_LINKER_FILE_BASE_NAME:tgt>

Новое в версии 3.15.

Базовое имя файла, используемого для линковки целевого объекта tgt, т.е. $<TARGET_LINKER_FILE_NAME:tgt> без префикса и суффикса. Например, если имя целевого файла libbase.a, то базовое имя base.

См. также свойства целевого объекта OUTPUT_NAME, ARCHIVE_OUTPUT_NAME и LIBRARY_OUTPUT_NAME и их конфигурационно-специфичные варианты OUTPUT_NAME_<CONFIG>, ARCHIVE_OUTPUT_NAME_<CONFIG> и LIBRARY_OUTPUT_NAME_<CONFIG>.

Также можно учитывать свойства целевого объекта <CONFIG>_POSTFIX и DEBUG_POSTFIX.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение.

$<TARGET_LINKER_FILE_PREFIX:tgt>

Новое в версии 3.15.

Префикс имени файла, используемого для линковки целевого объекта tgt.

См. также свойства целевого объекта PREFIX и IMPORT_PREFIX.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение.

$<TARGET_LINKER_FILE_SUFFIX:tgt>

Новое в версии 3.15.

Суффикс имени файла, используемого для линковки, где tgt — имя целевого объекта.

Суффикс соответствует расширению файла (например, ".so" или ".lib").

См. также свойства целевого объекта SUFFIX и IMPORT_SUFFIX.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение.

$<TARGET_LINKER_FILE_NAME:tgt>

Имя файла, используемого для линковки целевого объекта tgt.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_LINKER_FILE_DIR:tgt>

Директория файла, используемого для линковки целевого объекта tgt.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_SONAME_FILE:tgt>

Файл с именем soname (.so.3) где tgt - имя целевого объекта.

$<TARGET_SONAME_FILE_NAME:tgt>

Имя файла с именем soname (.so.3).

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_SONAME_FILE_DIR:tgt>

Директория файла с именем soname (.so.3).

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_PDB_FILE:tgt>

Новое в версии 3.1.

Полный путь к файлу базы данных программы (.pdb), сгенерированной линковщиком, где tgt - имя целевого объекта.

См. также свойства целевого объекта PDB_NAME и PDB_OUTPUT_DIRECTORY и их конфигурационно-специфичные варианты PDB_NAME_<CONFIG> и PDB_OUTPUT_DIRECTORY_<CONFIG>.

$<TARGET_PDB_FILE_BASE_NAME:tgt>

Новое в версии 3.15.

Базовое имя файла базы данных программы (.pdb), сгенерированной линковщиком, где tgt - имя целевого объекта.

Базовое имя соответствует имени файла PDB целевого объекта (см. $<TARGET_PDB_FILE_NAME:tgt>) без префикса и суффикса. Например, если имя целевого файла base.pdb, то базовое имя base.

См. также свойство целевого объекта PDB_NAME и его конфигурационно-специфичный вариант PDB_NAME_<CONFIG>.

Также можно учитывать свойства целевого объекта <CONFIG>_POSTFIX и DEBUG_POSTFIX.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение.

$<TARGET_PDB_FILE_NAME:tgt>

Новое в версии 3.1.

Имя файла базы данных программы (.pdb), сгенерированной линковщиком.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_PDB_FILE_DIR:tgt>

Новое в версии 3.1.

Директория файла базы данных программы (.pdb), сгенерированной линковщиком.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_BUNDLE_DIR:tgt>

Новое в версии 3.9.

Полный путь к папке с пакетом (/path/to/my.app, /path/to/my.framework, или /path/to/my.bundle), где tgt - имя целевого объекта.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_BUNDLE_DIR_NAME:tgt>

Новое в версии 3.24.

Имя папки с пакетом (my.app, my.framework, или my.bundle), где tgt - имя целевого объекта.

Обратите внимание, что tgt не добавляется в качестве зависимости целевого объекта, для которого вычисляется данное выражение (см. политику CMP0112).

$<TARGET_BUNDLE_CONTENT_DIR:tgt>

Новое в версии 3.9.

Полный путь к каталогу с содержимым пакета, где tgt — имя целевого объекта. Для macOS SDK он ведет к /path/to/my.app/Contents, /path/to/my.framework, или /path/to/my.bundle/Contents. Для всех остальных SDK (например, iOS) он ведет к /path/to/my.app, /path/to/my.framework, или /path/to/my.bundle из-за плоской структуры пакета.

Обратите внимание, что tgt не добавляется как зависимость целевого объекта, к которому применяется данное выражение (см. политику CMP0112).

$<TARGET_RUNTIME_DLLS:tgt>

Новое в версии 3.21.

Список DLL, от которых зависит целевой объект во время выполнения. Это определяется расположением всех SHARED целевых объектов в транзитивных зависимостях целевого объекта. Использование этого генератора выражений для объектов, отличных от исполняемых файлов, SHARED библиотек и MODULE библиотек, является ошибкой. В платформах, не поддерживающих DLL, это выражение всегда вычисляется как пустая строка.

Это генераторское выражение может использоваться для копирования всех DLL, от которых зависит целевой объект, в каталог вывода с помощью пользовательской команды POST_BUILD. Например:

find_package(foo CONFIG REQUIRED) # package generated by install(EXPORT)

add_executable(exe main.c)
target_link_libraries(exe PRIVATE foo::foo foo::bar)
add_custom_command(TARGET exe POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe>
  COMMAND_EXPAND_LISTS
)

Примечание

Импортированные целевые объекты поддерживаются только в том случае, если они знают расположение своих .dll файлов. Импортированная SHARED библиотека должна иметь свойство IMPORTED_LOCATION установленным на свой .dll файл. Подробности см. в разделе add_library импортированные библиотеки. Многие модули Поиск модулей генерируют импортированные целевые объекты типа UNKNOWN и поэтому будут проигнорированы.

Выражения экспорта и установки

$<INSTALL_INTERFACE:...>

Содержимое ... при экспорте свойства с помощью install(EXPORT), в противном случае пустая строка.

$<BUILD_INTERFACE:...>

Содержимое ... при экспорте свойства с помощью export() или при использовании целевого объекта другой целью в том же наборе инструментов сборки. В противном случае выводится пустая строка.

$<INSTALL_PREFIX>

Содержимое префикса установки, когда целевой объект экспортирован через install(EXPORT), или когда он вычисляется в свойстве INSTALL_NAME_DIR или аргументе INSTALL_NAME_DIR команды install(RUNTIME_DEPENDENCY_SET), в противном случае пустая строка.

Многоуровневая оценка выражений

$<GENEX_EVAL:expr>

Новое в версии 3.12.

Содержимое expr вычисляется как генераторское выражение в текущем контексте. Это позволяет использовать генераторские выражения, результаты которых являются генераторскими выражениями.

$<TARGET_GENEX_EVAL:tgt,expr>

Новое в версии 3.12.

Содержимое expr вычисляется как генераторское выражение в контексте целевого объекта tgt. Это позволяет использовать пользовательские свойства целевых объектов, которые сами содержат генераторские выражения.

Возможность вычисления генераторских выражений очень полезна, когда требуется управлять пользовательскими свойствами, поддерживающими генераторские выражения. Например:

add_library(foo ...)

set_property(TARGET foo PROPERTY
  CUSTOM_KEYS $<$<CONFIG:DEBUG>:FOO_EXTRA_THINGS>
)

add_custom_target(printFooKeys
  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:foo,CUSTOM_KEYS>
)

Эта упрощенная реализация пользовательской команды printFooKeys неверна, потому что свойство целевого объекта CUSTOM_KEYS не вычисляется, и содержимое передается как есть (то есть $<$<CONFIG:DEBUG>:FOO_EXTRA_THINGS>).

Для получения ожидаемого результата (то есть FOO_EXTRA_THINGS если config — Debug) необходимо вычислить результат $<TARGET_PROPERTY:foo,CUSTOM_KEYS>.

add_custom_target(printFooKeys
  COMMAND ${CMAKE_COMMAND} -E
    echo $<TARGET_GENEX_EVAL:foo,$<TARGET_PROPERTY:foo,CUSTOM_KEYS>>
)

Символы с экранированием

Эти выражения вычисляются как конкретные строковые литералы. Используйте их вместо фактического строкового литерала, когда необходимо предотвратить их специальное значение.

$<ANGLE-R>

Литеральный >. Используется, например, для сравнения строк, содержащих >.

$<COMMA>

Литеральный ,. Используется, например, для сравнения строк, содержащих ,.

$<SEMICOLON>

Литеральный ;. Используется для предотвращения расширения списка в аргументе с ;.

Устаревшие выражения

$<CONFIGURATION>

Имя конфигурации. Устарело с CMake 3.0. Используйте CONFIG вместо него.

© 2000–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.24/manual/cmake-generator-expressions.7.html

Spec-Zone.ru

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