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> -
равно
string1иstring2равны, иначе0. Сравнение регистрозависимое. Для регистронезависимого сравнения объедините с выражением генератора преобразования строк. Например, следующее выражение оценивается как1если${foo}равно любому изBAR,Bar,barи т.д.$<STREQUAL:$<UPPER_CASE:${foo}>,BAR>
-
$<EQUAL:value1,value2> -
равно
value1иvalue2численно равны, иначе0.
Сравнения версий
-
$<VERSION_LESS:v1,v2> -
равно
v1меньше, чемv2, иначе0.
-
$<VERSION_GREATER:v1,v2> -
равно
v1больше, чемv2, иначе0.
-
$<VERSION_EQUAL:v1,v2> -
равно
v1такая же версия, какv2, иначе0.
-
$<VERSION_LESS_EQUAL:v1,v2> -
Добавлена в версии 3.7.
равно
v1меньше или равноv2, иначе0.
-
$<VERSION_GREATER_EQUAL:v1,v2> -
Добавлена в версии 3.7.
равно
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.
равно
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 — любой из элементов в списке, разделённом запятыми,MAP_IMPORTED_CONFIG_<CONFIG>, иначе0. Это сравнение не учитывает регистр. Сопоставление вMAP_IMPORTED_CONFIG_<CONFIG>также учитывается этим выражением при его вычислении на свойствеIMPORTEDцелевого объекта.Изменено в версии 3.19: Несколько конфигураций могут быть указаны для
cfgs. CMake 3.18 и более ранние версии поддерживали только одну конфигурацию.
-
$<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.
- $<PLATFORM_ID: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.
-
$<COMPILE_LANGUAGE> -
Новое в версии 3.3.
Язык компиляции исходных файлов при оценке опций компиляции. См. соответствующее логическое выражение
$<COMPILE_LANGUAGE:language>для заметок о переносимости этого выражения генератора.
- $<COMPILE_LANGUAGE:languages>
-
Новое в версии 3.3.
Изменено в версии 3.15: Для
languagesможно указать несколько языков. CMake 3.14 и более ранние версии принимали только один язык.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и идентификатор компилятора CMakelanguageкомпилятора соответствует любому из перечисленных через запятую значений в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 является компилятором CXX, иCOMPILING_CXX_WITH_INTELкогда Intel является компилятором CXX. Аналогично, когда компилятор 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:features> -
Новое в версии 3.1.
где
features— список, разделённый запятыми. Возвращает значение1если всеfeaturesдоступны для целевого объекта 'head', и0в противном случае. Если это выражение используется при оценке реализации линковки целевого объекта, и любой зависимый объект транзитивно увеличивает требуемыйC_STANDARDилиCXX_STANDARDдля целевого объекта 'head', выводится ошибка. См. руководствоcmake-compile-features(7)для информации о функциях компиляции и списка поддерживаемых компиляторов.
Язык и идентификатор линковщика
-
$<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_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 -
Этот параметр сообщает линковщику искать указанную фреймворк, используя параметр линковщика
-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.
Встроенные и пользовательские функции библиотек определяются в терминах следующих переменных:
CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDCMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDCMAKE_LINK_LIBRARY_USING_<FEATURE>
Значение, используемое для каждой из этих переменных, является значением, установленным в конце области каталога, в которой был создан целевой объект. Использование следующее:
- Если языковая переменная
CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDимеет значение true, тоfeatureдолжно быть определено соответствующей переменнойCMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>. - Если какая-либо языковая
featureне поддерживается, то переменнаяCMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDдолжна быть true, иfeatureдолжно быть определено соответствующей переменнойCMAKE_LINK_LIBRARY_USING_<FEATURE>.
Следует обратить внимание на следующие ограничения:
-
- Выражение
library-listможет указывать на CMake-цели или библиотеки. Любая CMake-цель типа ОБЪЕКТ или ИНТЕРФЕЙС проигнорирует аспект функции выражения и вместо этого будет связана стандартным способом. - Генераторское выражение
$<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, поддерживаемыми линковщиком GNUld, используйте генераторское выражение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>_SUPPORTEDCMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTEDCMAKE_LINK_GROUP_USING_<FEATURE>
Значение, используемое для каждой из этих переменных, является значением, установленным в конце области каталога, в которой был создан целевой объект. Использование:
- Если языковая переменная
CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTEDимеет значение true, тоfeatureдолжно быть определено соответствующей переменнойCMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>. - Если какая-либо языковая
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 типа ОБЪЕКТ или ИНТЕРФЕЙС проигнорирует аспект функции выражения и вместо этого будет связан стандартным способом.- Выражение генератора
$<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» означает имя двоичного файла tgt . Это следует отличать от фразы «имя целевого объекта», которая представляет собой просто строку 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не добавляется в качестве зависимости от целевого объекта, для которого оценивается это выражение.Изменено в версии 3.26: При обнаружении во время оценки Требований к использованию целевых объектов, обычно в свойстве целевого объекта
INTERFACE_*поиск имениtgtпроисходит в каталоге целевого объекта, определяющего требование, а не в каталоге потребляющего целевого объекта, для которого оценивается выражение.
- $<TARGET_PROPERTY:prop>
-
Значение свойства
propцелевого объекта, для которого оценивается выражение. Обратите внимание, что для выражений генератора в Требованиях к использованию целевых объектов это целевой объект, потребляющий, а не определяющий требование.
-
$<TARGET_OBJECTS:tgt> -
Новое в версии 3.1.
Список объектов, полученных в результате построения
tgt. Обычно это используется для целевых объектов библиотек объектов.
-
$<TARGET_POLICY:policy> -
1еслиpolicyбылNEWпри создании целевого объекта «head», иначе0. Еслиpolicyне был установлен, будет выведено сообщение об ошибке для политики. Это выражение генератора работает только для подмножества политик.
-
$<TARGET_FILE:tgt> -
Полный путь к двоичному файлу
tgt.Обратите внимание, что
tgtне добавляется в качестве зависимости от целевого объекта, для которого оценивается это выражение, если выражение используется вadd_custom_command()илиadd_custom_target().
-
$<TARGET_FILE_BASE_NAME:tgt> -
Новое в версии 3.15.
Базовое имя
tgt, т. е.$<TARGET_FILE_NAME:tgt>без префикса и суффикса. Например, если имя файла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.
Префикс имени файла
tgt(например,lib).См. также свойство целевого объекта
PREFIX.Обратите внимание, что
tgtне добавляется в качестве зависимости от целевого объекта, для которого оценивается это выражение.
-
$<TARGET_FILE_SUFFIX:tgt> -
Новое в версии 3.15.
Суффикс имени файла
tgt(расширение, например,.soили.exe).См. также свойство целевого объекта
SUFFIX.Обратите внимание, что
tgtне добавляется в качестве зависимости от целевого объекта, для которого оценивается это выражение.
-
$<TARGET_FILE_NAME:tgt> -
Имя файла
tgt.Обратите внимание, что
tgtне добавляется в качестве зависимости от целевого объекта, для которого оценивается это выражение (см. политикуCMP0112).
-
$<TARGET_FILE_DIR:tgt> -
Каталог двоичного файла
tgt.Обратите внимание, что
tgtне добавляется в качестве зависимости от целевого объекта, для которого оценивается это выражение (см. политикуCMP0112).
-
$<TARGET_LINKER_FILE:tgt> -
Файл, используемый при линковке с целевым объектом
tgt. Обычно это библиотека, которуюtgtпредставляет (.a,.lib,.so), но для динамической библиотеки на платформах DLL это будет библиотека импорта DLL, связанная с DLL.
-
$<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с помощью командыcmake -E copy -t. Например: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 -t $<TARGET_FILE_DIR:exe> $<TARGET_RUNTIME_DLLS:exe> COMMAND_EXPAND_LISTS )Примечание
Импортированные целевые объекты поддерживаются только в том случае, если они знают расположение своих
.dllфайлов. ИмпортированнаяSHAREDбиблиотека должна иметьIMPORTED_LOCATIONустановлен на свой.dllфайл. Подробности см. в разделе add_library импортированные библиотеки. Многие Модули поиска создают импортированные целевые объекты с типомUNKNOWNи поэтому будут проигнорированы.
На платформах, поддерживающих пути во время выполнения (RPATH), обратитесь к свойству целевого объекта INSTALL_RPATH. На платформах Apple обратитесь к свойству целевого объекта INSTALL_NAME_DIR.
Выражения экспорта и установки
-
$<INSTALL_INTERFACE:...> -
Содержимое
...при экспорте свойства с помощьюinstall(EXPORT), и пустая строка в противном случае.
-
$<BUILD_INTERFACE:...> -
Содержимое
...при экспорте свойства с помощьюexport()или при использовании целевого объекта другой целевым объектом в той же системе сборки. В противном случае вычисляется как пустая строка.
-
$<BUILD_LOCAL_INTERFACE:...> -
Новое в версии 3.26.
Содержимое
...при использовании целевого объекта другим целевым объектом в той же системе сборки. В противном случае вычисляется как пустая строка.
-
$<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если конфигурация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–2023 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.26/manual/cmake-generator-expressions.7.html