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» для отображения отправленного сигнала.
Конкретные сигналы
Сигнал «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.
Пример:
[== "CMake Server" ==[
{"supportedProtocolVersions":[{"major":0,"minor":1}],"type":"hello"}
]== "CMake Server" ==]
Тип «handshake»
Первый запрос, который клиент может отправить серверу, имеет тип «handshake».
Этот запрос должен передать одну из поддерживаемых версий «supportedProtocolVersions» ответа типа «hello», полученного ранее, на сервер в поле «protocolVersion».
Каждая версия протокола может запросить наличие дополнительных атрибутов.
Версия протокола 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»
Этот запрос может быть отправлен после первоначального рукопожатия. Он вернёт 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», — это «capabilities», «buildDirectory», «generator», «extraGenerator» и «sourceDirectory». Любая попытка установить их будет проигнорирована тоже.
Все остальные настройки будут изменены.
Сервер ответит пустым сообщением reply или ошибкой.
Пример:
[== "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.7/manual/cmake-server.7.html