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>). Обратите внимание, что «именованная труба» относится к сокету домена на Unix и к именованной трубе на Windows.
При подключении к серверу (через именованную трубу или запуском в режиме --debug), сервер ответит сообщением hello:
[== "CMake Server" ==[
{"supportedProtocolVersions":[{"major":1,"minor":0}],"type":"hello"}
]== "CMake Server" ==]
Сообщения, отправляемые и принимаемые процессом, упаковываются в магические строки:
[== "CMake Server" ==[
{
... some JSON message ...
}
]== "CMake Server" ==]
Сервер теперь готов принимать дальнейшие запросы через именованную трубу или stdin.
Отладка
Режим сервера CMake можно попросить предоставить статистику по времени выполнения и т. п. или создать копию ответа в файл. Это делается путем передачи объекта «debug» JSON в качестве дочернего элемента запроса.
Объект 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», чтобы показать, какой сигнал был отправлен.
Конкретные сигналы
Сигнал «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» с массивом поддерживаемых сервером версий протокола. Это объекты 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» версии.
Протокол версии 1.0 требует установки следующих атрибутов:
- «sourceDirectory» с путем к исходным файлам
- «buildDirectory» с путем к каталогу сборки
- «generator» с именем генератора
- «extraGenerator» (необязательно!) с дополнительным генератором для использования
- «platform» с платформой генератора (если поддерживается генератором)
- «toolset» с набором инструментов генератора (если поддерживается генератором)
Протокол версии 1.2 делает все, кроме каталога сборки, необязательными, при условии, что в каталоге сборки есть действительный кэш, содержащий всю остальную информацию.
Пример:
[== "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»
- содержит имя (под-)проекта.
- «minimumCMakeVersion»
- содержит минимальную версию cmake, разрешенную для этого проекта; null, если проект её не указывает.
- «hasInstallRule»
- true, если проект содержит какие-либо правила установки, false в противном случае.
- «sourceDirectory»
- содержит текущую директорию исходного кода.
- «buildDirectory»
- содержит текущую директорию сборки.
- «targets»
- содержит список объектов целевых объектов системы сборки.
Объекты целевых объектов определяют отдельные целевые объекты сборки для определенной конфигурации.
Каждый объект целевого объекта может иметь следующие ключи:
- «name»
- содержит имя целевого объекта.
- «type»
- определяет тип сборки целевого объекта. Возможные значения: «STATIC_LIBRARY», «MODULE_LIBRARY», «SHARED_LIBRARY», «OBJECT_LIBRARY», «EXECUTABLE», «UTILITY» и «INTERFACE_LIBRARY».
- «fullName»
- содержит полное имя результата сборки (включая расширения и т.д.).
- «sourceDirectory»
- содержит текущую директорию исходного кода.
- «buildDirectory»
- содержит текущую директорию сборки.
- «isGeneratorProvided»
- true, если целевой объект автоматически создан генератором, false в противном случае.
- «hasInstallRule»
- true, если целевой объект содержит какие-либо правила установки, false в противном случае.
- «installPaths»
- полный путь к целевым каталогам, определённым правилами установки целевого объекта.
- «artifacts»
- содержит список артефактов сборки. Список отсортирован с наиболее важными артефактами в начале (например, файл .DLL перечисляется перед файлом .PDB в Windows).
- «linkerLanguage»
- содержит язык линковщика, используемого для создания артефакта.
- «linkLibraries»
- содержит список библиотек для линковки. Это значение закодировано в формате оболочки системы.
- «linkFlags»
- содержит список флагов для передачи линковщику. Это значение закодировано в формате оболочки системы.
- «linkLanguageFlags»
- содержит флаги для компилятора, использующего linkerLanguage. Это значение закодировано в формате оболочки системы.
- «frameworkPath»
- содержит путь к фреймворку (на компьютерах Apple). Это значение закодировано в формате оболочки системы.
- «linkPath»
- содержит путь линковки. Это значение закодировано в формате оболочки системы.
- «sysroot»
- содержит путь sysroot.
- «fileGroups»
- содержит исходные файлы, составляющие целевой объект.
FileGroups используются для группировки источников, использующих похожие настройки вместе.
Каждый объект fileGroup может содержать следующие ключи:
- «language»
- содержит используемый язык программирования для всех файлов в группе.
- «compileFlags»
- содержит строку со всеми флагами, передаваемыми компилятору при построении любого из файлов в этой группе. Это значение закодировано в формате оболочки системы.
- «includePath»
- содержит список путей включения. Каждый путь включения — это объект, содержащий «path» с фактическим путём включения и «isSystem» с булевым значением, указывающим, является ли это обычным или системным включением. Это значение закодировано в формате оболочки системы.
- «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" ==]
Тип «ctestInfo»
Запрос «ctestInfo» можно использовать после успешного выполнения запроса «compute».
Он отобразит полную структуру тестов проекта, как она известна cmake.
Ответ будет содержать ключ «configurations», который будет содержать список объектов конфигурации. Объекты конфигурации используются для различения различных конфигураций, которые могут быть включены в директории сборки. Хотя большинство генераторов поддерживают только одну конфигурацию, другие могут поддерживать несколько.
Каждый объект конфигурации может иметь следующие ключи:
- «name»
- содержит имя конфигурации. Имя может быть пустым.
- «projects»
- содержит список объектов проекта, по одному на каждый проект сборки.
Объекты проекта определяют один (под-)проект, определенный в системе сборки cmake.
Каждый объект проекта может иметь следующие ключи:
- «name»
- содержит имя (под-)проекта.
- «ctestInfo»
- содержит список объектов тестов.
Каждый объект теста может иметь следующие ключи:
- «ctestName»
- содержит имя теста.
- «ctestCommand»
- содержит команду теста.
- «properties»
- содержит список объектов свойств теста.
Каждый объект свойства теста может иметь следующие ключи:
- «key»
- содержит ключ свойства теста.
- «value»
- содержит значение свойства теста.
Тип «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.13/manual/cmake-server.7.html