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 ::= '[' '='* '['
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_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 резервирует идентификаторы, которые:
- начинаются с
CMAKE_(в верхнем, нижнем или смешанном регистре), или - начинаются с
_CMAKE_(в верхнем, нижнем или смешанном регистре), или - начинаются с
_, за которым следует имя любогоCMake Command.
Переменные среды
Переменные среды аналогичны обычным переменным, с последующими различиями:
- Область видимости
-
Переменные среды имеют глобальную область видимости в процессе 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.18/manual/cmake-language.7.html