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».
Протокол версии 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»
Этот запрос можно отправить после начального рукопожатия. Он вернет 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.11/manual/cmake-server.7.html