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, и ) аргументов).
Вышеупомянутое «unquoted_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_name} и оценивается внутри Аргумента в кавычках или Необработанного аргумента. Ссылка на переменную заменяется значением переменной или пустой строкой, если переменная не задана. Ссылки на переменные могут быть вложенными и оцениваются изнутри наружу, например, ${outer_${inner_variable}_variable}.
Буквальные ссылки на переменные могут состоять из буквенно-цифровых символов, символов /_.+-, и Последовательностей экранирования. Вложенные ссылки могут использоваться для оценки переменных любого имени. См. также документацию политики CMP0053 для исторических соображений и причин, по которым $ также технически разрешено, но не рекомендуется.
Раздел Переменные описывает область видимости имён переменных и то, как устанавливаются их значения.
Ссылка на переменную окружения имеет вид $ENV{VAR} и оценивается в тех же контекстах, что и обычная ссылка на переменную. См. ENV для получения дополнительной информации.
Ссылка на переменную кэша имеет вид $CACHE{VAR} и оценивается в тех же контекстах, что и обычная ссылка на переменную. См. CACHE для получения дополнительной информации.
Комментарии
Комментарий начинается с символа #, который не находится внутри Аргумента в скобках, Аргумента в кавычках или экранирован с \ как часть Необработанного аргумента. Есть два типа комментариев: Комментарий в скобках и Строчный комментарий.
Комментарий в Скобках
# , непосредственно за которым следует Аргумент в скобках, образует комментарий в скобках, состоящий из всего содержимого скобок:
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 не поддерживают комментарии в скобках. Они интерпретируют открывающую # как начало Строчного комментария.
Строчный Комментарий
# , не непосредственно за которым следует Аргумент в скобках, образует строчный комментарий, который продолжается до конца строки:
line_comment ::= '#' <any text not starting in a bracket_argument
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 хранятся как строки, строка может рассматриваться как список в определенных контекстах, например, во время вычисления Необработанного аргумента. В таких контекстах строка делится на элементы списка путем разделения по ; символам, не следующим за неравным числом [ и ] символов и не предшествующих непосредственно \. Последовательность \; не разделяет значение, но заменяется на ; в результирующем элементе.
Список элементов представлен как строка путем конкатенации элементов, разделенных ;. Например, команда 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–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.13/manual/cmake-language.7.html