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 ::= '[' '='{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, и ) аргументов).
Вышеупомянутое «незаключённый_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() явно устанавливают или удаляют переменную, но и другие команды имеют семантику, которая также изменяет переменные. Имена переменных чувствительны к регистру и могут состоять практически из любого текста, но мы рекомендуем использовать имена, состоящие только из буквенно-цифровых символов плюс _ и -.
Переменные имеют динамический scope. Каждое «установка» или «удаление» переменной создаёт привязку в текущем scope:
- Область действия Функции
-
Определения Команд, созданные командой
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.9/manual/cmake-language.7.html