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 Byte-Order Mark в файлах исходного кода.
Файлы исходного кода
Файл исходного кода языка 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 ::= '[' '='{len} '['
bracket_content ::= <any text not containing a bracket_close
of the same {len} as the bracket_open>
bracket_close ::= ']' '='{len} ']'
Открывающая скобка длины len >= 0 записывается [ за которой следуют len = , за которыми следует [, а соответствующая закрывающая скобка записывается ] за которой следуют len = , за которыми следует ]. Скобки не вложены. Всегда можно выбрать уникальную длину для открывающих и закрывающих скобок, чтобы они содержали закрывающие скобки других длин.
Содержимое аргумента в скобках состоит из всего текста между открывающей и закрывающей скобками, за исключением того, что один перевод строки непосредственно после открывающей скобки, если таковая имеется, игнорируется. Не выполняется никакая оценка заключенного содержимого, таких как Последовательности экранирования или Ссылки на переменные. Аргумент в скобках всегда передается вызову команды ровно как один аргумент.
Например:
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 каждый интерпретируется буквально.
Ссылки в стиле 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} и вычисляется в тех же контекстах, что и обычная ссылка на переменную.
Комментарии
Комментарий начинается с символа #, который не находится внутри Аргумента в квадратных скобках, Аргумента в кавычках, или экранирован с \ как часть Необработанного аргумента. Существует два типа комментариев: Комментарий в квадратных скобках и Строковый комментарий.
Комментарий в Квадратных Скобках
# непосредственно после Аргумента в квадратных скобках формирует комментарий в квадратных скобках, состоящий из всего содержимого скобок:
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 ищет элемент кеша. Если элемент кеша найден, используется его значение. В противном случае ссылка на переменную вычисляется как пустая строка.
Руководство 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.8/manual/cmake-language.7.html