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 ::= '[' '='* '['
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, и ) аргументы).
Вышеупомянутое «необработанный_устаревший» производство представляет такие аргументы. Мы не рекомендуем использовать устаревшие необработанные аргументы в новом коде. Вместо этого используйте Аргумент в кавычках или Аргумент в скобках для представления содержимого.
Последовательности Экранирования
Последовательность экранирования — это \ за которым следует один символ:
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. Они никогда не кэшируются.
- Ссылки
-
Ссылки на переменные имеют вид
$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.15/manual/cmake-language.7.html