Spec-Zone.ru › CMake 3.14

cmake-generator-expressions(7)

  • Введение
  • Логические выражения генератора

    • Логические операторы
    • Сравнения строк
    • Запросы переменных
  • Строковые выражения генератора

    • Экранированные символы
    • Условные выражения
    • Преобразования строк
    • Запросы переменных
    • Запросы, зависящие от целей
    • Выражения, связанные с выводом
  • Отладка

Введение

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

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

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

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

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

Логические выражения генератора

Логические выражения генератора вычисляются либо как 0 , либо как 1. Обычно они используются для построения условия в условном выражении генератора.

Доступные логические выражения:

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

$<BOOL:string>

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

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

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

$<AND:conditions>

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

$<OR:conditions>

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

$<NOT:condition>

0 , если condition равно 1, иначе 1.

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

$<STREQUAL:string1,string2>

1 , если string1 и string2 равны, иначе 0. Сравнение чувствительно к регистру. Для регистронезависимого сравнения объедините с выражением генератора преобразования строк,

$<STREQUAL:$<UPPER_CASE:${foo}>,"BAR"> # "1" if ${foo} is any of "BAR", "Bar", "bar", ...
$<EQUAL:value1,value2>

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

$<IN_LIST:string,list>

1 , если string является элементом разделяемого запятыми списка list, иначе 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>

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

$<VERSION_GREATER_EQUAL:v1,v2>

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

Запросы переменных

$<TARGET_EXISTS:target>

1 если target существует, иначе 0.

$<CONFIG:cfg>

1 если конфигурация равна cfg, иначе 0. Это сравнение не учитывает регистр. При вычислении выражения на свойстве целевого объекта MAP_IMPORTED_CONFIG_<CONFIG> также учитывается сопоставление в IMPORTED.

$<PLATFORM_ID:platform_id>

1 если идентификатор CMake платформы совпадает с platform_id, иначе 0. См. также переменную CMAKE_SYSTEM_NAME.

$<C_COMPILER_ID:compiler_id>

1 если идентификатор CMake компилятора C совпадает с compiler_id, иначе 0. См. также переменную CMAKE_<LANG>_COMPILER_ID.

$<CXX_COMPILER_ID:compiler_id>

1 если идентификатор CMake компилятора C++ совпадает с compiler_id, иначе 0. См. также переменную CMAKE_<LANG>_COMPILER_ID.

$<Fortran_COMPILER_ID:compiler_id>

1 если идентификатор CMake компилятора Fortran совпадает с compiler_id, иначе 0. См. также переменную CMAKE_<LANG>_COMPILER_ID.

$<C_COMPILER_VERSION:version>

1 если версия компилятора C совпадает с version, иначе 0. См. также переменную CMAKE_<LANG>_COMPILER_VERSION.

$<CXX_COMPILER_VERSION:version>

1 если версия компилятора C++ совпадает с version, иначе 0. См. также переменную CMAKE_<LANG>_COMPILER_VERSION.

$<Fortran_COMPILER_VERSION:version>

1 если версия компилятора Fortran совпадает с version, иначе 0. См. также переменную CMAKE_<LANG>_COMPILER_VERSION.

$<TARGET_POLICY:policy>

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

$<COMPILE_FEATURES:features>

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

$<COMPILE_LANGUAGE:language>

1 когда язык, используемый для компиляции блока, совпадает с language, иначе 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>:/opt/foo/cxx_headers>
)

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

Обратите внимание, что в Visual Studio Generators и Xcode нет способа представить определения компиляции или каталоги включения, относящиеся ко всей цели, раздельно для C и CXX языков. Также в Visual Studio Generators нет способа представить флаги, относящиеся ко всей цели, раздельно для 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)

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

Эти выражения преобразуются в строку. Например,

include_directories(/usr/include/$<CXX_COMPILER_ID>/)

преобразуется в /usr/include/GNU/ или /usr/include/Clang/ и т. д., в зависимости от идентификатора компилятора.

Строковые выражения также могут быть объединены с другими выражениями. Вот пример строкового выражения внутри булевого выражения в условном выражении:

$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,4.2.0>:OLD_COMPILER>

преобразуется в OLD_COMPILER если CMAKE_CXX_COMPILER_VERSION

И вот два вложенных строковых выражения:

-I$<JOIN:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>, -I>

генерирует строку с записями из свойства целевого объекта INCLUDE_DIRECTORIES, при этом каждая запись предваряется -I.

Продолжая предыдущий пример, если сначала нужно проверить, не пусто ли свойство INCLUDE_DIRECTORIES, рекомендуется ввести вспомогательную переменную для повышения читаемости кода:

set(prop "$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>") # helper variable
$<$<BOOL:${prop}>:-I$<JOIN:${prop}, -I>>

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

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

Строковые литералы для экранирования специального значения, которое символ в противном случае имел бы:

$<ANGLE-R>

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

$<COMMA>

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

$<SEMICOLON>

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

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

Условные выражения генератора зависят от булевого условия, которое должно быть 0 или 1.

$<condition:true_string>

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

$<IF:condition,true_string,false_string>

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

Обычно condition является булевым выражением генератора. Например,

$<$<CONFIG:Debug>:DEBUG_MODE>

преобразуется в DEBUG_MODE при использовании конфигурации Debug, и в противном случае преобразуется в пустую строку.

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

$<JOIN:list,string>

Объединяет список с содержимым string.

$<LOWER_CASE:string>

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

$<UPPER_CASE:string>

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

$<GENEX_EVAL:expr>

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

$<TARGET_GENEX_EVAL:tgt,expr>

Содержимое 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>>
)

Запросы к переменным

$<CONFIG>

Имя конфигурации.

$<CONFIGURATION>

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

$<PLATFORM_ID>

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

$<C_COMPILER_ID>

Идентификатор компилятора C, используемого CMake. Смотрите также переменную CMAKE_<LANG>_COMPILER_ID.

$<CXX_COMPILER_ID>

Идентификатор компилятора C++, используемого CMake. Смотрите также переменную CMAKE_<LANG>_COMPILER_ID.

$<Fortran_COMPILER_ID>

Идентификатор компилятора Fortran, используемого CMake. Смотрите также переменную CMAKE_<LANG>_COMPILER_ID.

$<C_COMPILER_VERSION>

Версия используемого компилятора C. Смотрите также переменную CMAKE_<LANG>_COMPILER_VERSION.

$<CXX_COMPILER_VERSION>

Версия используемого компилятора C++. Смотрите также переменную CMAKE_<LANG>_COMPILER_VERSION.

$<Fortran_COMPILER_VERSION>

Версия используемого компилятора Fortran. Смотрите также переменную CMAKE_<LANG>_COMPILER_VERSION.

$<COMPILE_LANGUAGE>

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

Зависимые от целевых запросы

$<TARGET_NAME_IF_EXISTS:tgt>

Расширяется до tgt, если заданная цель существует, в противном случае пустой строкой.

$<TARGET_FILE:tgt>

Полный путь к основному файлу (.exe, .so.1.2, .a), где tgt — имя цели.

$<TARGET_FILE_NAME:tgt>

Имя основного файла (.exe, .so.1.2, .a).

$<TARGET_FILE_DIR:tgt>

Директория основного файла (.exe, .so.1.2, .a).

$<TARGET_LINKER_FILE:tgt>

Файл, используемый для компоновки (.a, .lib, .so), где tgt — имя цели.

$<TARGET_LINKER_FILE_NAME:tgt>

Имя файла, используемого для компоновки (.a, .lib, .so).

$<TARGET_LINKER_FILE_DIR:tgt>

Директория файла, используемого для компоновки (.a, .lib, .so).

$<TARGET_SONAME_FILE:tgt>

Файл с именем soname (.so.3), где tgt — имя цели.

$<TARGET_SONAME_FILE_NAME:tgt>

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

$<TARGET_SONAME_FILE_DIR:tgt>

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

$<TARGET_PDB_FILE:tgt>

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

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

$<TARGET_PDB_FILE_NAME:tgt>

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

$<TARGET_PDB_FILE_DIR:tgt>

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

$<TARGET_BUNDLE_DIR:tgt>

Полный путь к каталогу пакета (my.app, my.framework, или my.bundle), где tgt — имя цели.

$<TARGET_BUNDLE_CONTENT_DIR:tgt>

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

$<TARGET_PROPERTY:tgt,prop>

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

$<TARGET_PROPERTY:prop>

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

$<INSTALL_PREFIX>

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

Выражения, связанные с выводом

$<TARGET_NAME:...>

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

$<LINK_ONLY:...>

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

$<INSTALL_INTERFACE:...>

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

$<BUILD_INTERFACE:...>

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

$<MAKE_C_IDENTIFIER:...>

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

$<TARGET_OBJECTS:objLib>

Список объектов, полученных в результате сборки objLib. objLib должен быть объектом типа OBJECT_LIBRARY.

$<SHELL_PATH:...>

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

Отладка

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

Один из возможных способов вывода сообщений отладки — добавление пользовательской цели,

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

Команда оболочки make genexdebug (вызываемая после выполнения cmake) затем отобразит результат $<...>.

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

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

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

Spec-Zone.ru

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