Spec-Zone.ru › CMake 3.17

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

Spec-Zone.ru

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