Spec-Zone.ru › CMake 3.16

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, и ) аргументы).

Вышеприведенное «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() явно устанавливают или удаляют переменную, но и другие команды имеют семантику, которая изменяет переменные. Имена переменных регистрозависимы и могут состоять из практически любого текста, но мы рекомендуем придерживаться имен, состоящих только из алфавитно-цифровых символов плюс _ и -.

Переменные имеют динамический область действия. Каждая переменная «set» или «unset» создает привязку в текущем объёме:

Область действия Функции

Определения Команд, созданные командой function(), создают команды, которые при вызове обрабатывают записанные команды в новой области привязки переменных. Переменная «set» или «unset» привязывается в этой области и видна для текущей функции и любых вложенных вызовов внутри неё, но не после возвращения из функции.

Область действия Директории

Каждая из Директорий в дереве источников имеет свои собственные привязки переменных. Перед обработкой файла CMakeLists.txt для директории CMake копирует все привязки переменных, которые в настоящее время определены в родительской директории, если таковые имеются, для инициализации новой области действия директории. CMake Скрипты, при обработке с помощью cmake -P, связывают переменные в одной области действия «директории».

Переменная «set» или «unset», которая не находится внутри вызова функции, привязывается к текущей области действия директории.

Постоянный Кэш

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.16/manual/cmake-language.7.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API