Spec-Zone.ru › CMake 3.22

cmake-language(7)

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

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

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

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

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

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

Организация

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

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

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

Директории

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

Скрипты

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

Модули

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

Синтаксис

Кодировка

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

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

Исходные файлы

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

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, и ) аргументы).

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

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

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

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>} или $CACHE{<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() явно задают или удаляют переменную, но и другие команды имеют семантику, которая изменяет переменные. Имена переменных регистрозависимы и могут состоять практически из любого текста, но мы рекомендуем использовать имена, состоящие только из буквенно-цифровых символов плюс _ и -.

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

Область действия функции

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

Область действия каталога

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

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

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

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

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

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

Примечание

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

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

Переменные среды

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

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

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

Ссылок

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

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

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

В руководстве 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"

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

Spec-Zone.ru

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