Spec-Zone.ru › CMake 3.31

cmake-language(7)

  • Организация

    • Директории
    • Скрипты
    • Модули
  • Синтаксис

    • Кодировка
    • Файлы исходного кода
    • Вызовы команд
    • Аргументы команд

      • Аргумент в скобках
      • Аргумент в кавычках
      • Незамещённый аргумент
    • Последовательности экранирования
    • Ссылая на переменные
    • Комментарии

      • Комментарии в скобках
      • Однострочные комментарии
  • Управляющие структуры

    • Условные блоки
    • Циклы
    • Определения команд
  • Переменные
  • Переменные окружения
  • Списки

Организация

Файлы ввода CMake написаны на языке CMake в файлах исходного кода, имеющих имя CMakeLists.txt или заканчивающихся расширением .cmake.

Файлы исходного кода языка CMake в проекте организованы следующим образом:

  • Директории (CMakeLists.txt),
  • Скрипты (<script>.cmake), и
  • Модули (<module>.cmake).

Директории

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

Скрипты

Отдельный файл исходного кода <script>.cmake может обрабатываться в режиме скрипта с помощью инструмента командной строки cmake(1) с опцией -P. Режим скрипта просто выполняет команды в указанном файле исходного кода языка CMake и не генерирует систему сборки. Он не позволяет использовать команды CMake, определяющие цели сборки или действия.

Модули

Код языка CMake в директориях или скриптах может использовать команду include() для загрузки файла исходного кода <module>.cmake в контексте включения. Смотрите справочную страницу cmake-modules(7) для документации модулей, включенных в дистрибутив CMake. Деревья исходного кода проекта также могут предоставлять свои модули и указывать их расположение(я) в переменной CMAKE_MODULE_PATH.

Синтаксис

Кодировка

Файл исходного кода языка CMake может быть записан в 7-битовом ASCII для максимальной переносимости на всех поддерживаемых платформах. Переводы строк могут быть закодированы как \n или \r\n, но будут преобразованы в \n при чтении файлов ввода.

Обратите внимание, что реализация является 8-битной, поэтому файлы исходного кода могут быть закодированы в UTF-8 на платформах с системными API, поддерживающими эту кодировку. Кроме того, CMake 3.2 и выше поддерживают файлы исходного кода, закодированные в UTF-8 в Windows (используя UTF-16 для вызовов системных API). Кроме того, CMake 3.0 и выше допускают лидирующую UTF-8 метку порядка байтов в файлах исходного кода.

Файлы исходного кода

Файл исходного кода языка CMake состоит из нуля или более вызовов команд, разделенных переводом строки и необязательно пробелами и комментариями:

file         ::=  file_element*
file_element ::=  command_invocation line_ending |
                  (bracket_comment|space)* line_ending
line_ending  ::=  line_comment? newline
space        ::=  <match '[ \t]+'>
newline      ::=  <match '\n'>

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

Вызовы команд

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

command_invocation  ::=  space* identifier space* '(' arguments ')'
identifier          ::=  <match '[A-Za-z_][A-Za-z0-9_]*'>
arguments           ::=  argument? separated_arguments*
separated_arguments ::=  separation+ argument? |
                         separation* '(' arguments ')'
separation          ::=  space | line_ending

Например:

add_executable(hello world.c)

Имена команд регистронезависимы. Вложенные незамещённые скобки в аргументах должны быть сбалансированы. Каждый ( или ) передаётся в вызов команды как литеральный незамещённый аргумент. Это может использоваться в вызовах команды if() для заключения условий. Например:

if(FALSE AND (FALSE OR TRUE)) # evaluates to FALSE

Примечание

Версии CMake до 3.0 требуют, чтобы идентификаторы имён команд содержали не менее 2 символов.

Версии CMake до 2.8.12 молча принимают незамещённый аргумент или аргумент в кавычках непосредственно после аргумента в кавычках, не разделённые пробелами. Для совместимости CMake 2.8.12 и выше принимают такой код, но выдают предупреждение.

Аргументы команд

Существует три типа аргументов в вызовах команд:

argument ::=  bracket_argument | quoted_argument | unquoted_argument

Аргумент в скобках

Аргумент в скобках, вдохновлённый синтаксисом длинных скобок Lua, заключает содержимое между открывающей и закрывающей "скобками" одинаковой длины:

bracket_argument ::=  bracket_open bracket_content bracket_close
bracket_open     ::=  '[' '='* '['
bracket_content  ::=  <any text not containing a bracket_close with
                       the same number of '=' as the bracket_open>
bracket_close    ::=  ']' '='* ']'

Открывающая скобка записывается как [ за которой следуют ноль или более = и [. Соответствующая закрывающая скобка записывается как ] за которой следуют такое же количество = и ]. Скобки не вложены. Длина может всегда выбираться уникально для открывающей и закрывающей скобок, содержащих закрывающие скобки других длин.

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

Например:

message([=[
This is the first line in a bracket argument with bracket length 1.
No \-escape sequences or ${variable} references are evaluated.
This is always one argument even though it contains a ; character.
The text does not end on a closing bracket of length 0 like ]].
It does end in a closing bracket of length 1.
]=])

Примечание

Версии CMake до 3.0 не поддерживают аргументы в скобках. Они интерпретируют открывающую скобку как начало незамещённого аргумента.

Аргумент в кавычках

Аргумент в кавычках заключает содержимое между открывающими и закрывающими двойными кавычками:

quoted_argument     ::=  '"' quoted_element* '"'
quoted_element      ::=  <any character except '\' or '"'> |
                         escape_sequence |
                         quoted_continuation
quoted_continuation ::=  '\' newline

Содержимое аргумента в кавычках состоит из всего текста между открывающими и закрывающими кавычками. Оба экранирования и ссылки на переменные вычисляются. Аргумент в кавычках всегда передаётся вызову команды как ровно один аргумент.

Например:

message("This is a quoted argument containing multiple lines.
This is always one argument even though it contains a ; character.
Both \\-escape sequences and ${variable} references are evaluated.
The text does not end on an escaped double-quote like \".
It does end in an unescaped double quote.
")

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

message("\
This is the first line of a quoted argument. \
In fact it is the only line but since it is long \
the source code uses line continuation.\
")

Примечание

Версии CMake до 3.0 не поддерживают продолжение с \. Они сообщают об ошибках в аргументах в кавычках, содержащих строки, заканчивающиеся нечётным количеством символов \.

Незамещённый аргумент

Незамещённый аргумент не заключён в какой-либо синтаксис цитирования. Он не может содержать пробелов, (, ), #, ", или \ за исключением случаев, когда они экранированы обратным слэшем:

unquoted_argument ::=  unquoted_element+ | unquoted_legacy
unquoted_element  ::=  <any character except whitespace or one of '()#"\'> |
                       escape_sequence
unquoted_legacy   ::=  <see note in text>

Содержимое незамещённого аргумента состоит из всего текста в смежном блоке разрешённых или экранированных символов. Оба экранирования и ссылки на переменные оцениваются. Результирующее значение делится так же, как списки делятся на элементы. Каждый ненулевой элемент передаётся вызову команды как аргумент. Поэтому незамещённый аргумент может быть передан вызову команды как ноль или более аргументов.

Например:

foreach(arg
    NoSpace
    Escaped\ Space
    This;Divides;Into;Five;Arguments
    Escaped\;Semicolon
    )
  message("${arg}")
endforeach()

Примечание

Для поддержки устаревшего кода CMake, не заключенные в кавычки аргументы также могут содержать двойные кавычки ("...", возможно, заключающие горизонтальные пробелы), и ссылки на переменные в стиле make ($(MAKEVAR)).

Неэкранированные двойные кавычки должны быть сбалансированы, не могут появляться в начале не заключённого в кавычки аргумента и обрабатываются как часть содержимого. Например, не заключенные в кавычки аргументы -Da="b c", -Da=$(v), и a" "b"c"d каждый интерпретируются буквально. Вместо этого они могут быть записаны как аргументы в кавычках "-Da=\"b c\"", "-Da=$(v)", и "a\" \"b\"c\"d", соответственно.

Ссылки в стиле make обрабатываются буквально как часть содержимого и не подвергаются расширению переменных. Они обрабатываются как часть одного аргумента (а не как отдельные $, (, MAKEVAR, и ) аргументы).

Вышеупомянутое «незаключённые_в_кавычки_устаревшее» производство представляет такие аргументы. Мы не рекомендуем использовать устаревшие не заключенные в кавычки аргументы в новом коде. Вместо этого используйте Аргумент в кавычках или Аргумент в скобках для представления содержимого.

Последовательности Экранирования

Последовательность экранирования — это \, за которым следует один символ:

escape_sequence  ::=  escape_identity | escape_encoded | escape_semicolon
escape_identity  ::=  '\' <match '[^A-Za-z0-9;]'>
escape_encoded   ::=  '\t' | '\r' | '\n'
escape_semicolon ::=  '\;'

\ за которым следует не буквенно-цифровой символ, просто кодирует буквальный символ без интерпретации его как синтаксиса. \t, \r, или \n кодирует символ табуляции, возврат каретки или новую строку, соответственно. \; вне Ссылок на Переменные кодирует себя, но может использоваться в Незаключенном аргументе для кодирования ; без разделения значения аргумента на нём. \; внутри Ссылок на Переменные кодирует буквальный символ ;. (См. также политику CMP0053 для исторических соображений.)

Ссылки на Переменные

Ссылка на переменную имеет вид ${<variable>} и оценивается внутри Аргумента в кавычках или Незаключённого аргумента. Ссылка на переменную заменяется значением указанной переменной или записи кеша, или, если ни то, ни другое не установлено, пустой строкой. Ссылки на переменные могут быть вложенными и вычисляются изнутри наружу, например, ${outer_${inner_variable}_variable}.

Буквальные ссылки на переменные могут состоять из буквенно-цифровых символов, символов /_.+-, и Последовательностей Экранирования. Вложенные ссылки могут использоваться для оценки переменных любого имени. См. также политику CMP0053 для исторических соображений и причин, по которым $ также технически разрешен, но не рекомендуется.

Раздел Переменные описывает область видимости имён переменных и как устанавливаются их значения.

Ссылка на переменную среды имеет вид $ENV{<variable>}.. См. раздел Переменные Окружения для получения дополнительной информации.

Ссылка на переменную кеша имеет вид $CACHE{<variable>}, и заменяется значением указанной записи кеша без проверки наличия обычной переменной с тем же именем. Если запись кеша не существует, она заменяется пустой строкой. См. CACHE для получения дополнительной информации.

Команда if() имеет специальный синтаксис условия, который позволяет использовать ссылки на переменные в короткой форме <variable> вместо ${<variable>}. Однако переменные окружения всегда должны ссылаться как $ENV{<variable>}.

Комментарии

Комментарий начинается с символа #, который не находится внутри Аргумента в Скобках, Аргумента в Кавычках или экранирован с \ как часть Незаключённого Аргумента. Существуют два типа комментариев: Комментарий в Скобках и Комментарий в Строке.

Комментарий в Скобках

# непосредственно за которым следует bracket_open образует комментарий в скобках, состоящий из всего содержимого скобок:

bracket_comment ::=  '#' bracket_argument

Например:

#[[This is a bracket comment.
It runs until the close bracket.]]
message("First Argument\n" #[[Bracket Comment]] "Second Argument")

Примечание

Версии CMake до 3.0 не поддерживают комментарии в скобках. Они интерпретируют открывающую # как начало Комментарии в Строке.

Комментарий в Строке

#, не непосредственно за которым следует bracket_open образует комментарий в строке, который продолжается до конца строки:

line_comment ::=  '#' <any text not starting in a bracket_open
                       and not containing a newline>

Например:

# This is a line comment.
message("First Argument\n" # This is a line comment :)
        "Second Argument") # This is a line comment.

Структуры Управления

Условные Блоки

Команды if()/elseif()/else()/endif() ограничивают блоки кода, которые должны выполняться условно.

Циклы

Команды foreach()/endforeach() и while()/endwhile() ограничивают блоки кода, которые должны выполняться в цикле. Внутри таких блоков команда break() может использоваться для досрочного завершения цикла, а команда continue() может быть использована для немедленного перехода к следующей итерации.

Определения Команд

Команды macro()/endmacro() и function()/endfunction() ограничивают блоки кода, которые записываются для последующего вызова как команды.

Переменные

Переменные — это базовая единица хранения в языке CMake. Их значения всегда имеют строковый тип, хотя некоторые команды могут интерпретировать строки как значения других типов. Команды set() и unset() явно устанавливают или сбрасывают переменную, но и другие команды имеют семантику, которая изменяет переменные. Имена переменных чувствительны к регистру и могут состоять практически из любого текста, но мы рекомендуем использовать имена, состоящие только из буквенно-цифровых символов плюс _ и -.

Переменные имеют динамическую область видимости. Каждое «установление» или «сброс» переменной создаёт привязку в текущей области видимости:

Область видимости блока

Команда block() может создавать новую область видимости для привязок переменных.

Область видимости функции

Определения Команд, созданные командой function(), создают команды, которые при вызове обрабатывают записанные команды в новой области видимости привязок переменных. Переменная «установка» или «сброс» связывается в этой области видимости и видна для текущей функции и любых вложенных вызовов в ней, но не после возвращения функции.

Область видимости директории

Каждая из Директорий в дереве исходных кодов имеет свои собственные привязки переменных. Перед обработкой файла CMakeLists.txt для директории CMake копирует все привязки переменных, которые в настоящее время определены в родительской директории, если таковые имеются, для инициализации новой области видимости директории. CMake Сценарии, когда обрабатываются с cmake -P, связывают переменные в одной области видимости «директории».

Переменная «установка» или «сброс», не находящаяся внутри вызова функции, связывается с текущей областью видимости директории.

Постоянный кэш

CMake хранит отдельный набор «переменных кеша» или «записей кеша», значения которых сохраняются между несколькими запусками в дереве сборки проекта. Записи кеша имеют изолированную область видимости, которая изменяется только по явным запросам, например, с помощью опции CACHE команд set() и unset().

При оценке ссылок на переменные, CMake сначала ищет привязку в стеке вызовов функций, если таковой имеется, а затем переходит к привязке в области текущего каталога, если таковая имеется. Если найдена привязка "set", используется её значение. Если найдена привязка "unset" или привязка не найдена, CMake ищет запись в кэше. Если запись в кэше найдена, используется её значение. В противном случае ссылка на переменную оценивается как пустая строка. Синтаксис $CACHE{VAR} может использоваться для непосредственного поиска записей в кэше.

В руководстве cmake-variables(7) описаны многочисленные переменные, предоставляемые CMake или имеющие значение для CMake, когда задаются кодом проекта.

Примечание

CMake резервирует идентификаторы, которые:

  • начинаются с CMAKE_ (заглавные, строчные или смешанные регистры), или
  • начинаются с _CMAKE_ (заглавные, строчные или смешанные регистры), или
  • начинаются с _ за которым следует имя любой CMake Command.

Переменные окружения

Переменные окружения похожи на обычные переменные, с следующими отличиями:

Область видимости

Переменные окружения имеют глобальную область видимости в процессе CMake. Они никогда не кэшируются.

Ссылки

Ссылки на переменные имеют вид $ENV{<variable>}, используя оператор ENV.

Инициализация

Начальные значения переменных окружения CMake — это значения вызывающего процесса. Значения могут быть изменены с помощью команд set() и unset(). Эти команды влияют только на выполняемый процесс CMake, а не на системное окружение в целом. Изменённые значения не записываются обратно в вызывающий процесс, и они не видны последующими процессами сборки или тестирования.

См. команду командной строки cmake -E env для запуска команды в изменённом окружении.

Проверка

См. команду командной строки cmake -E environment для отображения всех текущих переменных окружения.

В руководстве cmake-env-variables(7) описаны переменные окружения, имеющие особое значение для CMake.

Списки

Хотя все значения в CMake хранятся как строки, строка может обрабатываться как список в определённых контекстах, таких как во время оценки необработанного аргумента. В таких контекстах строка разбивается на элементы списка путём разделения на символы ; не следующие за нечётным числом символов [ и ] и не предшествуемые непосредственно символом \. Последовательность \; не разделяет значение, а заменяется на ; в результирующем элементе.

Список элементов представляется как строка путём конкатенации элементов, разделённых ;. Например, команда set() сохраняет несколько значений в целевую переменную как список:

set(srcs a.c b.c c.c) # sets "srcs" to "a.c;b.c;c.c"

Списки предназначены для простых случаев использования, таких как список исходных файлов, и не должны использоваться для сложных задач обработки данных. Большинство команд, которые строят списки, не экранируют символы ; в элементах списка, тем самым выравнивая вложенные списки:

set(x a "b;c") # sets "x" to "a;b;c", not "a;b\;c"

В целом, списки не поддерживают элементы, содержащие символы ;. Чтобы избежать проблем, рассмотрите следующие рекомендации:

  • Интерфейсы многих команд CMake, переменных и свойств принимают списки, разделённые точкой с запятой. Избегайте передачи списков с элементами, содержащими точки с запятой, этим интерфейсам, если они не документируют прямую поддержку или способ экранирования или кодирования точек с запятой.
  • При построении списка замените любой в противном случае неиспользуемый заполнитель на ; в элементах при. Затем замените ; на заполнитель при обработке элементов списка. Например, следующий код использует | вместо символов ;.

    set(mylist a "b|c")
    foreach(entry IN LISTS mylist)
      string(REPLACE "|" ";" entry "${entry}")
      # use "${entry}" normally
    endforeach()
    

    Опция LIST_SEPARATOR модуля ExternalProject является примером интерфейса, построенного с помощью этого подхода.

  • В списках generator expressions используйте выражение генератора $<SEMICOLON>.
  • В вызовах команд используйте синтаксис цитируемого аргумента по возможности. Вызванная команда получит содержимое аргумента с сохранёнными точками с запятой. Нецитируемый аргумент будет разбит по точкам с запятой.
  • В реализациях function() избегайте использования ARGV и ARGN, которые не различают точки с запятой в значениях от разделяющих значения. Вместо этого предпочтительнее использовать именованные позиционные аргументы и переменные ARGC и ARGV#. При использовании cmake_parse_arguments() для разбора аргументов, предпочтительнее использовать его подпись PARSE_ARGV, которая использует переменные ARGV#.

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

© 2000–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.31/manual/cmake-language.7.html

Spec-Zone.ru

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