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 метку порядка байтов в файлах исходного кода.
Файлы исходного кода
Файл исходного кода 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, и ) аргументы).
Вышеупомянутое «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>} и оценивается внутри аргумента в кавычках или неявного аргумента. Ссылка на переменную заменяется значением переменной или пустой строкой, если переменная не задана. Ссылки на переменные могут быть вложенными и вычисляются изнутри наружу, например ${outer_${inner_variable}_variable}.
Буквальные ссылки на переменные могут состоять из буквенно-цифровых символов, символов /_.+- и последовательностей экранирования. Вложенные ссылки могут использоваться для оценки переменных любого имени. См. также документацию политики CMP0053 для исторических соображений и причин, почему $ также технически разрешено, но не рекомендуется.
Раздел Переменные документирует область действия имён переменных и то, как устанавливаются их значения.
Ссылка на переменную среды имеет вид $ENV{<variable>}. См. раздел Переменные среды для получения дополнительной информации.
Ссылка на переменную кэша имеет вид $CACHE{<variable>}. См. CACHE для получения дополнительной информации.
Команда if() имеет специальный синтаксис условия, который позволяет использовать ссылки на переменные в сокращенной форме <variable> вместо ${<variable>}. Однако переменные среды и кэша всегда должны быть ссылаться как $ENV{<variable>} или $CACHE{<variable>}.
Комментарии
Комментарий начинается с символа #, который не находится внутри аргумента в скобках, аргумента в кавычках или не экранирован с помощью \ как части неявного аргумента. Существует два типа комментариев: комментарий в скобках и строчный комментарий.
Комментарий в скобках
# , сразу за которым следует аргумент в скобках, образует комментарий в скобках, состоящий из всего содержимого скобок:
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 сначала ищет привязку в стеке вызовов функций, если таковой имеется, а затем обращается к привязке в текущем области действия каталога, если таковая имеется. Если найдена привязка «set», используется её значение. Если найдена привязка «unset» или привязка не найдена, CMake ищет запись в кэше. Если запись в кэше найдена, используется её значение. В противном случае ссылка на переменную оценивается как пустая строка. Синтаксис $CACHE{VAR} может использоваться для прямого поиска записей в кэше.
В руководстве cmake-variables(7) описаны многочисленные переменные, предоставляемые CMake или имеющие значение для CMake, когда они заданы кодом проекта.
Переменные окружения
Переменные окружения похожи на обычные переменные с последующими отличиями:
- Область действия
-
Переменные окружения имеют глобальную область действия в процессе 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–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.14/manual/cmake-language.7.html