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.Изменено в версии 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.
-
$<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.Обратите внимание, что
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.
Префикс имени файла бинарника целевого объекта (например,
lib).См. также свойство целевого объекта
PREFIX.Обратите внимание, что
tgtне добавляется в качестве зависимости целевого объекта, для которого оценивается это выражение.
-
$<TARGET_FILE_SUFFIX:tgt> -
Новое в версии 3.15.
Суффикс имени файла бинарника целевого объекта (расширение, например,
.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пользовательской команде. Например: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если конфигурация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.25/manual/cmake-generator-expressions.7.html