cmake-server(7)
- Введение
- Работа
- Отладка
- API протокола
Введение
cmake(1) способен предоставлять семантическую информацию о коде CMake, который он выполняет, чтобы сгенерировать систему сборки. Если выполняется с параметрами командной строки -E server, он запускается в режиме длительного выполнения и позволяет клиенту запрашивать доступную информацию через протокол JSON.
Протокол предназначен для использования IDE, инструментами рефакторинга и другими инструментами, которым необходимо понять систему сборки целиком.
Один cmake-buildsystem(7) может описывать содержимое системы сборки и свойства сборки, которые отличаются в зависимости от generation-time context, включая:
- Платформу (например, Windows, APPLE, Linux).
- Конфигурацию сборки (например, Debug, Release, Coverage).
- Компилятор (например, MSVC, GCC, Clang) и его версию.
- Язык исходных файлов, которые компилируются.
- Доступные функции компиляции (например, CXX variadic templates).
- Политики CMake.
Протокол предназначен для предоставления информации инструментам для удовлетворения нескольких потребностей:
- Предоставление полного и легко анализируемого источника всей информации, относящейся к инструменту, по отношению к исходному коду. Инструментам не нужно будет анализировать сгенерированные системы сборки, чтобы получить доступ к каталогам включения или определениям компиляции, например.
- Семантическая информация о системе сборки CMake.
- Обеспечение стабильного интерфейса для чтения информации в кэше CMake.
- Информация для определения, когда cmake нужно повторно выполнить в результате изменений файлов.
Работа
Запустите cmake(1) в режиме сервера, передав путь к каталогу сборки для обработки:
cmake -E server (--debug|--pipe <NAMED_PIPE>)
Сервер будет взаимодействовать, используя stdin/stdout (с параметром --debug) или с помощью именованной трубы (с параметром --pipe <NAMED_PIPE>).
При подключении к серверу (через именованную трубу или путем запуска в режиме --debug), сервер ответит сообщением hello:
[== "CMake Server" ==[
{"supportedProtocolVersions":[{"major":1,"minor":0}],"type":"hello"}
]== "CMake Server" ==]
Сообщения, отправляемые и получаемые процессом, заключены в магические строки:
[== "CMake Server" ==[
{
... some JSON message ...
}
]== "CMake Server" ==]
Сервер теперь готов принимать дальнейшие запросы через именованную трубу или stdin.
Отладка
Режим сервера CMake может быть запрошен для предоставления статистики о времени выполнения и т. д. или для вывода копии ответа в файл. Это делается путем передачи JSON-объекта «debug» в качестве дочернего элемента запроса.
Объект debug поддерживает ключ «showStats», который принимает логическое значение и заставляет режим сервера возвращать объект «zzzDebug» со статистикой в качестве части ответа. «dumpToFile» принимает строковое значение и заставит сервер cmake скопировать ответ в заданный файл.
Это ответ от сервера cmake с «showStats», установленным в true:
[== "CMake Server" ==[
{
"cookie":"",
"errorMessage":"Waiting for type \"handshake\".",
"inReplyTo":"unknown",
"type":"error",
"zzzDebug": {
"dumpFile":"/tmp/error.txt",
"jsonSerialization":0.011016,
"size":111,
"totalTime":0.025995
}
}
]== "CMake Server" ==]
Сервер скопировал этот ответ в файл /tmp/error.txt и потратил 0,011 секунды на преобразование JSON-ответа в строку, и на обработку запроса в целом ушло 0,025 секунды. Ответ имеет размер 111 байт.
API протокола
Общий формат сообщений
Все сообщения должны иметь значение «type», которое определяет тип сообщения, которое передаётся туда или обратно. Например, начальное сообщение, отправляемое сервером, имеет тип «hello». Сообщения без типа приведут к ответу типа «error».
Все запросы, отправляемые на сервер, могут содержать значение «cookie». Это значение будет возвращено без изменений во всех ответах, вызванных запросом.
Все ответы будут содержать значение «inReplyTo», которое может быть пустым в случае ошибок разбора, но будет содержать тип сообщения запроса во всех остальных случаях.
Тип «reply»
Этот тип используется сервером для ответа на запросы.
Сообщение может – в зависимости от типа исходного запроса – содержать значения.
Пример:
[== "CMake Server" ==[
{"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"}
]== "CMake Server" ==]
Тип «error»
Этот тип используется для возврата условия ошибки клиенту. Он будет содержать «errorMessage».
Пример:
[== "CMake Server" ==[
{"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"}
]== "CMake Server" ==]
Тип «progress»
Когда сервер занят длительное время, вежливо отправлять клиенту ответы типа «progress». Они будут содержать «progressMessage» со строкой, описывающей текущее выполняемое действие, а также «progressMinimum», «progressMaximum» и «progressCurrent» с целочисленными значениями, описывающими диапазон прогресса.
За сообщениями типа «progress» могут следовать другие сообщения «progress» или сообщение типа «reply» или «error», завершающие запрос.
Сообщения «progress» не могут быть отправлены после сообщения «reply» или «error» для запроса, который вызвал эти ответы, до момента получения.
Тип «message»
Сообщение возникает, когда сервер обрабатывает запрос и генерирует какой-либо вывод, который должен быть отображён пользователю. Сообщение имеет «message» с фактическим текстом для отображения и «title» с предлагаемым заголовком диалогового окна.
Пример:
[== "CMake Server" ==[
{"cookie":"","message":"Something happened.","title":"Title Text","inReplyTo":"handshake","type":"message"}
]== "CMake Server" ==]
Тип «signal»
Сервер может отправлять сигналы, когда он обнаруживает изменения состояния системы. Сигналы имеют тип «signal», пустые поля «cookie» и «inReplyTo» и всегда содержат значение «name», чтобы показать, какой сигнал был отправлен.
Конкретные сигналы
Сервер cmake может отправлять сигналы с указанными ниже именами:
Сигнал «dirty»
Сигнал «dirty» отправляется всякий раз, когда сервер определяет, что конфигурация проекта больше не актуальна. Это происходит, когда любой из файлов, которые влияют на систему сборки, изменяется.
Сигнал «dirty» может выглядеть следующим образом:
[== "CMake Server" ==[
{
"cookie":"",
"inReplyTo":"",
"name":"dirty",
"type":"signal"}
]== "CMake Server" ==]
Сигнал «fileChange»
Сигнал «fileChange» отправляется всякий раз, когда изменяется отслеживаемый файл. Он содержит путь «path», который был изменён, и список «properties» с типом изменения, который был обнаружен. Возможные изменения — «change» и «rename».
Сигнал «fileChange» выглядит следующим образом:
[== "CMake Server" ==[
{
"cookie":"",
"inReplyTo":"",
"name":"fileChange",
"path":"/absolute/CMakeLists.txt",
"properties":["change"],
"type":"signal"}
]== "CMake Server" ==]
Конкретные типы сообщений
Тип «hello»
Первое сообщение, отправленное сервером cmake при запуске, имеет тип «hello». Это единственное сообщение, отправленное сервером, которое не является «reply», «progress» или «error».
Он будет содержать «supportedProtocolVersions» с массивом поддерживаемых версий протокола сервера cmake. Это JSON-объекты с ключами «major» и «minor», содержащими неотрицательные целые значения. Некоторые версии могут быть помечены как экспериментальные. Они будут содержать ключ «isExperimental», установленный в true. Для их включения требуется специальный аргумент командной строки при запуске режима сервера cmake.
В пределах версии «major» все версии «minor» полностью совместимы. Новые версии «minor» могут вводить функциональность таким образом, что существующие клиенты той же версии «major» будут по-прежнему работать, если они проигнорируют ключи в выводе, о которых они не знают.
Пример:
[== "CMake Server" ==[
{"supportedProtocolVersions":[{"major":0,"minor":1}],"type":"hello"}
]== "CMake Server" ==]
Тип «handshake»
Первый запрос, который клиент может отправить серверу, имеет тип «handshake».
В этом запросе необходимо передать одну из «supportedProtocolVersions» ответа типа «hello», полученного ранее, обратно на сервер в поле «protocolVersion». Передача версии «major» запрошенной версии протокола заставит сервер использовать последнюю версию «minor» этого протокола. Используйте это, если вам явно не нужна зависимость от конкретной версии «minor».
Если в каталоге сборки уже есть кэш CMake, достаточно установить атрибут «buildDirectory». Для создания нового каталога сборки требуются дополнительные атрибуты в зависимости от версии протокола.
Версия протокола 1.0 требует установки следующих атрибутов:
- «sourceDirectory» с путем к исходникам
- «buildDirectory» с путем к каталогу сборки
- «generator» с именем генератора
- «extraGenerator» (необязательно!) с дополнительным генератором
- «platform» с платформой генератора (если поддерживается генератором)
- «toolset» с набором инструментов генератора (если поддерживается генератором)
Пример:
[== "CMake Server" ==[
{"cookie":"zimtstern","type":"handshake","protocolVersion":{"major":0},
"sourceDirectory":"/home/code/cmake", "buildDirectory":"/tmp/testbuild",
"generator":"Ninja"}
]== "CMake Server" ==]
что приведёт к ответу типа «reply»:
[== "CMake Server" ==[
{"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"}
]== "CMake Server" ==]
указывающему, что сервер готов к действиям.
Тип «globalSettings»
Этот запрос можно отправить после начального handshake. Он вернёт JSON-структуру с информацией о состоянии cmake.
Пример:
[== "CMake Server" ==[
{"type":"globalSettings"}
]== "CMake Server" ==]
что приведёт к ответу типа «reply»:
[== "CMake Server" ==[
{
"buildDirectory": "/tmp/test-build",
"capabilities": {
"generators": [
{
"extraGenerators": [],
"name": "Watcom WMake",
"platformSupport": false,
"toolsetSupport": false
},
<...>
],
"serverMode": false,
"version": {
"isDirty": false,
"major": 3,
"minor": 6,
"patch": 20160830,
"string": "3.6.20160830-gd6abad",
"suffix": "gd6abad"
}
},
"checkSystemVars": false,
"cookie": "",
"extraGenerator": "",
"generator": "Ninja",
"debugOutput": false,
"inReplyTo": "globalSettings",
"sourceDirectory": "/home/code/cmake",
"trace": false,
"traceExpand": false,
"type": "reply",
"warnUninitialized": false,
"warnUnused": false,
"warnUnusedCli": true
}
]== "CMake Server" ==]
Тип «setGlobalSettings»
Этот запрос можно отправить для изменения атрибутов глобальных настроек. Неизвестные атрибуты будут проигнорированы. Только для чтения атрибуты, возвращаемые «globalSettings», — это все возможности, buildDirectory, generator, extraGenerator и sourceDirectory. Любая попытка установить их также будет проигнорирована.
Все остальные настройки будут изменены.
Сервер ответит пустым сообщением или ошибкой.
Пример:
[== "CMake Server" ==[
{"type":"setGlobalSettings","debugOutput":true}
]== "CMake Server" ==]
CMake ответит на это:
[== "CMake Server" ==[
{"inReplyTo":"setGlobalSettings","type":"reply"}
]== "CMake Server" ==]
Тип «configure»
Этот запрос настроит проект для сборки.
Чтобы настроить директорию сборки, уже содержащую файлы cmake, достаточно установить «buildDirectory» через «setGlobalSettings». Чтобы создать новую директорию сборки, вам также необходимо установить «currentGenerator» и «sourceDirectory» через «setGlobalSettings» в дополнение к «buildDirectory».
Вы можете передать список строк в «configure» через ключ «cacheArguments». Эти строки будут интерпретированы аналогично аргументам командной строки, относящимся к обработке кэша, которые передаются клиенту командной строки cmake.
Пример:
[== "CMake Server" ==[
{"type":"configure", "cacheArguments":["-Dsomething=else"]}
]== "CMake Server" ==]
CMake ответит так (после некоторого времени отображения прогресса):
[== "CMake Server" ==[
{"cookie":"","inReplyTo":"configure","type":"reply"}
]== "CMake Server" ==]
Тип «compute»
Этот запрос сгенерирует файлы системы сборки в директории сборки и доступен только после успешного «configure» проекта.
Пример:
[== "CMake Server" ==[
{"type":"compute"}
]== "CMake Server" ==]
CMake ответит (после отображения информации о прогрессе):
[== "CMake Server" ==[
{"cookie":"","inReplyTo":"compute","type":"reply"}
]== "CMake Server" ==]
Тип «codemodel»
Запрос «codemodel» можно использовать после успешного выполнения «compute» проекта.
Он отобразит полную структуру проекта, как она известна cmake.
Ответ будет содержать ключ «configurations», который будет содержать список объектов конфигурации. Объекты конфигурации используются для различения различных конфигураций, которые могут быть включены в директорию сборки. В то время как большинство генераторов поддерживают только одну конфигурацию, другие могут поддерживать несколько.
Каждый объект конфигурации может иметь следующие ключи:
- «name»
- содержит имя конфигурации. Имя может быть пустым.
- «projects»
- содержит список объектов проекта, по одному для каждого проекта сборки.
Объекты проекта определяют один (под-)проект, определенный в системе сборки cmake.
Каждый объект проекта может иметь следующие ключи:
- «name»
- содержит имя (под-)проекта.
- «sourceDirectory»
- содержит текущую директорию исходного кода
- «buildDirectory»
- содержит текущую директорию сборки.
- «targets»
- содержит список объектов целевых объектов системы сборки.
Объекты целевых объектов определяют отдельные целевые объекты сборки для определенной конфигурации.
Каждый объект целевого объекта может иметь следующие ключи:
- «name»
- содержит имя целевого объекта.
- «type»
- определяет тип сборки целевого объекта. Возможные значения: «STATIC_LIBRARY», «MODULE_LIBRARY», «SHARED_LIBRARY», «OBJECT_LIBRARY», «EXECUTABLE», «UTILITY» и «INTERFACE_LIBRARY».
- «fullName»
- содержит полное имя результата сборки (включая расширения и т. д.).
- «sourceDirectory»
- содержит текущую директорию исходного кода.
- «buildDirectory»
- содержит текущую директорию сборки.
- «artifacts»
- содержит список артефактов сборки. Список отсортирован по приоритету артефактов (например, файл .DLL перечислен перед файлом .PDB в Windows).
- «linkerLanguage»
- содержит язык линковщика, используемого для создания артефакта.
- «linkLibraries»
- содержит список библиотек для линковки. Это значение закодировано в формате оболочки системы.
- «linkFlags»
- содержит список флагов, передаваемых линковщику. Это значение закодировано в формате оболочки системы.
- «linkLanguageFlags»
- содержит флаги для компилятора, использующего linkerLanguage. Это значение закодировано в формате оболочки системы.
- «frameworkPath»
- содержит путь к фреймворку (на компьютерах Apple). Это значение закодировано в формате оболочки системы.
- «linkPath»
- содержит путь линковки. Это значение закодировано в формате оболочки системы.
- «sysroot»
- содержит путь sysroot.
- «fileGroups»
- содержит исходные файлы, составляющие целевой объект.
FileGroups используются для группирования источников, использующих аналогичные настройки.
Каждый объект fileGroup может содержать следующие ключи:
- «language»
- содержит язык программирования, используемый всеми файлами в группе.
- «compileFlags»
- содержит строку со всеми флагами, переданными компилятору при построении любого из файлов в этой группе. Это значение закодировано в формате оболочки системы.
- «includePath»
- содержит список путей включения. Каждый путь включения — это объект, содержащий «path» с фактическим путем включения и «isSystem» со значением bool, указывающим, является ли это обычным включением или включением системы. Это значение закодировано в формате оболочки системы.
- «defines»
- содержит список определений в форме «SOMEVALUE» или «SOMEVALUE=42». Это значение закодировано в формате оболочки системы.
- «sources»
- содержит список исходных файлов.
Все пути к файлам в fileGroup являются либо абсолютными, либо относительными к sourceDirectory целевого объекта.
Пример:
[== "CMake Server" ==[
{"type":"codemodel"}
]== "CMake Server" ==]
CMake ответит:
[== "CMake Server" ==[
{
"configurations": [
{
"name": "",
"projects": [
{
"buildDirectory": "/tmp/build/Source/CursesDialog/form",
"name": "CMAKE_FORM",
"sourceDirectory": "/home/code/src/cmake/Source/CursesDialog/form",
"targets": [
{
"artifacts": [ "/tmp/build/Source/CursesDialog/form/libcmForm.a" ],
"buildDirectory": "/tmp/build/Source/CursesDialog/form",
"fileGroups": [
{
"compileFlags": " -std=gnu11",
"defines": [ "CURL_STATICLIB", "LIBARCHIVE_STATIC" ],
"includePath": [ { "path": "/tmp/build/Utilities" }, <...> ],
"isGenerated": false,
"language": "C",
"sources": [ "fld_arg.c", <...> ]
}
],
"fullName": "libcmForm.a",
"linkerLanguage": "C",
"name": "cmForm",
"sourceDirectory": "/home/code/src/cmake/Source/CursesDialog/form",
"type": "STATIC_LIBRARY"
}
]
},
<...>
]
}
],
"cookie": "",
"inReplyTo": "codemodel",
"type": "reply"
}
]== "CMake Server" ==]
Тип «cmakeInputs»
Запросы «cmakeInputs» сообщат о файлах, используемых CMake в рамках самой системы сборки.
Этот запрос доступен только после успешного выполнения «configure» проекта.
Пример:
[== "CMake Server" ==[
{"type":"cmakeInputs"}
]== "CMake Server" ==]
CMake ответит следующей информацией:
[== "CMake Server" ==[
{"buildFiles":
[
{"isCMake":true,"isTemporary":false,"sources":["/usr/lib/cmake/...", ... ]},
{"isCMake":false,"isTemporary":false,"sources":["CMakeLists.txt", ...]},
{"isCMake":false,"isTemporary":true,"sources":["/tmp/build/CMakeFiles/...", ...]}
],
"cmakeRootDirectory":"/usr/lib/cmake",
"sourceDirectory":"/home/code/src/cmake",
"cookie":"",
"inReplyTo":"cmakeInputs",
"type":"reply"
}
]== "CMake Server" ==]
Все имена файлов являются либо относительными к директории исходного кода верхнего уровня, либо абсолютными.
Список файлов, для которых «isCMake» установлено в значение true, является частью установки cmake.
Список файлов, для которых «isTemporary» установлено в значение true, является частью директории сборки и не сохранится при очистке директории сборки.
Тип «cache»
Запрос «cache» выведет значения сохранённых конфигураций.
Пример:
[== "CMake Server" ==[
{"type":"cache"}
]== "CMake Server" ==]
CMake ответит следующим выводом:
[== "CMake Server" ==[
{
"cookie":"","inReplyTo":"cache","type":"reply",
"cache":
[
{
"key":"SOMEVALUE",
"properties":
{
"ADVANCED":"1",
"HELPSTRING":"This is not helpful"
}
"type":"STRING",
"value":"TEST"}
]
}
]== "CMake Server" ==]
Вывод может быть ограничен списком ключей путём передачи массива имён ключей в необязательное поле «keys» запроса «cache».
Тип «fileSystemWatchers»
Сервер может отслеживать изменения в файловой системе. Команда «fileSystemWatchers» сообщит об отслеживаемых файлах и каталогах.
Пример:
[== "CMake Server" ==[
{"type":"fileSystemWatchers"}
]== "CMake Server" ==]
CMake ответит следующим выводом:
[== "CMake Server" ==[
{
"cookie":"","inReplyTo":"fileSystemWatchers","type":"reply",
"watchedFiles": [ "/absolute/path" ],
"watchedDirectories": [ "/absolute" ]
}
]== "CMake Server" ==]
© 2000–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.10/manual/cmake-server.7.html