cmake-instrumentation(7)

在版本 4.0 中添加。

简介

注意

此功能仅在通过 CMAKE_EXPERIMENTAL_INSTRUMENTATION 门控启用 instrumentation 的实验性支持时可用。

CMake Instrumentation API 允许在 CMake 项目的配置、生成、构建、测试和安装步骤期间收集定时数据、目标信息和系统诊断信息。

此功能仅适用于使用 Makefile GeneratorsNinja Generators 的项目。

与 CMake instrumentation API 的所有交互都必须指定 API 版本和 Data 版本。目前,这些都只有一个版本:API v1Data v1

数据收集

每当在启用 instrumentation 的情况下执行命令时,都会在项目构建树中创建一个 v1 代码段文件,其中包含特定于该命令的数据。这些文件会一直保留到 索引 发生之后。

CMake 设置 RULE_LAUNCH_COMPILERULE_LAUNCH_LINKRULE_LAUNCH_CUSTOM 全局属性,以使用 ctest --instrument 启动器来分别捕获每个编译、链接和自定义命令的详细信息。如果项目已使用 CTestUseLaunchers 配置,则 ctest --instrument 还将包括通常由 ctest --launch 执行的行为。

索引

索引是整理生成的 instrumentation 数据的过程。索引发生在特定的时间间隔,称为钩子(hooks),例如每次构建之后。这些钩子在 v1 查询文件 中配置。每当触发钩子时,都会生成一个索引文件,其中包含比上次索引更新的代码段文件列表。

索引也可以通过手动调用 ctest --collect-instrumentation <build> 来执行。

回调

作为 v1 查询文件 的一部分,用户可以提供回调列表,用于处理由此功能收集的数据。

每当 索引 发生时,都会执行每个提供的回调,并将生成的索引文件的路径作为参数传递。

这些回调(在用户级别或项目级别定义)应读取 instrumentation 数据并执行任何期望的处理。一旦所有回调完成,CMake 会自动删除索引文件及其列出的代码段。请注意,回调绝不应手动移动或删除这些数据文件,因为其他回调可能需要它们。

启用 Instrumentation

可以为单个 CMake 项目启用 Instrumentation,也可以为用户配置和构建的所有 CMake 项目启用。对于这两种情况,请参阅 v1 查询文件 以了解有关配置此功能的详细信息。

在项目级别启用 Instrumentation

项目代码可以使用 cmake_instrumentation() 命令包含 instrumentation 查询。

此外,查询文件可以手动放置在构建树顶部的 <build>/.cmake/instrumentation/<version>/query/ 下。此版本的 CMake 仅支持一个版本架构,API v1

在用户级别启用 Instrumentation

可以通过将查询文件放置在 CMAKE_CONFIG_DIR 下的 <config_dir>/instrumentation/<version>/query/ 中,在用户级别配置 Instrumentation。

为 CDash 提交启用 Instrumentation

当在 Dashboard Client 模式下使用 CTest 时,可以通过将 CTEST_USE_INSTRUMENTATION 环境变量设置为 CMAKE_EXPERIMENTAL_INSTRUMENTATION 功能的当前 UUID 来启用 instrumentation。这样做会自动启用 dynamicSystemInformation 查询。

下表显示了每种类型的 instrumented 命令如何映射到相应类型的 CTest XML 文件。

代码段角色

CTest XML 文件

配置

Configure.xml

生成

Configure.xml

编译

Build.xml

链接

Build.xml

自定义

Build.xml

构建

未使用!

cmakeBuild

Build.xml

cmakeInstall

Build.xml

安装

Build.xml

ctest

Build.xml

测试

Test.xml

默认情况下,报告给 CDash 的命令行在第一个空格处被截断。您可以选择通过将 CTEST_USE_VERBOSE_INSTRUMENTATION 设置为 1 来报告完整命令行(包括参数)。

API v1

API 版本指定 instrumentation 数据的子目录布局和查询文件的格式。

Instrumentation API v1 位于 instrumentation/v1/ 目录下,该目录位于 <build>/.cmake/(用于输出数据和项目级查询)或 <config_dir>/(用于用户级查询)下。此目录的 v1 组件表示 API 版本。它具有以下子目录

query/

保存用户或客户端编写的查询文件。任何带有 .json 文件扩展名的文件都将被识别为查询文件。这些文件归创建它们的客户端或用户所有。

query/generated/

保存由 CMake 项目使用 cmake_instrumentation() 命令生成的查询文件。这些文件归 CMake 所有,并在 CMake 配置步骤期间自动删除和重新生成。

data/

保存项目上收集的 instrumentation 数据。CMake 拥有所有数据文件,其他进程永远不应删除它们。此处收集的数据将一直保留到 索引 发生且所有 回调 都执行完毕之后。

cdash/

保存内部用于生成 XML 内容以提交到 CDash 的临时文件。

v1 查询文件

任何带有 .json 扩展名的文件,位于 instrumentation/v1/query/ 目录下,都被识别为 instrumentation 数据的查询。

这些文件必须包含一个带有以下键的 JSON 对象。version 键是必需的,但所有其他字段都是可选的。

version

要生成的代码段文件的数据版本,一个整数。当前唯一支持的版本是 1

callbacks

用于处理收集的 instrumentation 数据的 回调 的命令行字符串列表。每当执行这些回调时,v1 索引文件 的完整路径将附加到字符串中包含的参数。

hooks

指定何时应自动发生 索引 的字符串列表。这些是应整理 instrumentation 数据并调用用户 回调 以处理数据的时间间隔。此列表中的元素应为以下之一

  • postGenerate

  • preBuild(在调用 ninjamake 时调用;在 Windows 上不可用)

  • postBuild(在 ninjamake 完成时调用;在 Windows 上不可用)

  • preCMakeBuild(在调用 cmake --build 时调用)

  • postCMakeBuild(在 cmake --build 完成时调用)

  • postInstall

  • postTest

queries

指定在 instrumentation 期间要收集的其他可选数据的字符串列表。此列表中的元素应为以下之一

staticSystemInformation

启用收集运行 CMake 的主机计算机的静态信息。此数据在 索引 期间收集,并包含在生成的 v1 索引文件 中。

dynamicSystemInformation

启用收集运行 CMake 的主机计算机的动态信息。为 CMake 生成的每个 v1 代码段文件 收集数据,包括命令执行前后立即获得的信息。

列出的 callbacks至少在指定的钩子期间被调用。当有多个查询文件时,它们之间的 callbackshooksqueries 将被合并。因此,如果任何查询文件包含任何 hooks,则所有查询文件中的每个 callback 都将在所有查询文件中的每个 hook 处执行。此外,如果任何查询文件包含任何可选的 queries,则可选的查询数据将存在于所有数据文件中。

示例

{
  "version": 1,
  "callbacks": [
    "/usr/bin/python callback.py",
    "/usr/bin/cmake -P callback.cmake arg",
  ],
  "hooks": [
    "postCMakeBuild",
    "postInstall"
  ],
  "queries": [
    "staticSystemInformation",
    "dynamicSystemInformation"
  ]
}

在此示例中,在每次调用 cmake --buildcmake --install 后,将在 <build>/.cmake/instrumentation/v1/data 中生成一个索引文件 index-<timestamp>.json,其中包含自上次索引以来创建的数据代码段文件列表。命令 /usr/bin/python callback.py index-<timestamp>.json/usr/bin/cmake -P callback.cmake arg index-<timestamp>.json 将按顺序执行。索引文件将包含 staticSystemInformation 数据,并且索引中列出的每个代码段文件将包含 dynamicSystemInformation 数据。一旦两个回调都完成,索引文件和它列出的所有代码段文件将从项目构建树中删除。

Data v1

Data 版本指定 CMake instrumentation API 生成的输出文件的内容,作为 数据收集索引 的一部分。生成两种类型的数据文件:v1 代码段文件v1 索引文件。当使用 API v1 时,这些文件位于项目构建树下的 <build>/.cmake/instrumentation/v1/data/ 中。

v1 代码段文件

为作为 CMake 构建或安装步骤一部分调用的每个编译、链接和自定义命令生成代码段文件,并包含有关执行命令的 instrumentation 数据。此外,还为以下项创建代码段文件

  • CMake 配置步骤

  • CMake 生成步骤

  • 整个构建步骤(使用 cmake --build 执行)

  • 整个安装步骤(使用 cmake --install 执行)

  • 每次 ctest 调用

  • ctest 执行的每个单独的测试。

这些文件保留在构建树中,直到 索引 发生并且任何用户指定的 回调 都已执行。

代码段文件的文件名语法为 <role>-<hash>-<timestamp>.json,并包含以下数据

version

代码段文件的数据版本,一个整数。当前版本始终为 1

command

执行的完整命令。当 rolebuild 时排除。

workingDir

执行 command 的工作目录。

result

命令的退出值,一个整数。

role

执行的命令类型,将是以下值之一

  • configure:CMake 配置步骤

  • generate:CMake 生成步骤

  • compile:构建期间调用的单个编译步骤

  • link:构建期间调用的单个链接步骤

  • custom:构建期间调用的单个自定义命令

  • build:完整的 makeninja 调用。仅当启用 preBuildpostBuild 钩子时生成。

  • cmakeBuild:完整的 cmake --build 调用

  • cmakeInstall:完整的 cmake --install 调用

  • install:单个 cmake -P cmake_install.cmake 调用

  • ctest:完整的 ctest 调用

  • test:由 CTest 执行的单个测试

target

与命令关联的 CMake 目标。仅当 rolecompilelink 时包含。

targetType

目标的 TYPE。仅当 rolelink 时包含。

targetLabels

目标的 LABELS。仅当 rolelink 时包含。

timeStart

命令开始的时间,表示为自系统纪元以来的毫秒数。

duration

命令运行的持续时间,以毫秒为单位表示。

outputs

命令的输出文件,一个数组。仅当 role 是以下之一时包含:compilelinkcustom

outputSizes

outputs 的大小(以字节为单位),一个数组。对于不存在的文件,大小为 0。包含条件与 outputs 字段相同。

source

正在编译的源文件。仅当 rolecompile 时包含。

language

正在编译的源文件的语言。仅当 rolecompile 时包含。

testName

正在执行的测试的名称。仅当 roletest 时包含。

config

构建类型,例如 ReleaseDebug。仅当 rolecompilelinktest 时包含。

dynamicSystemInformation

指定有关运行 CMake 的主机计算机的动态信息收集。为 CMake 生成的每个代码段文件收集数据,其中包含命令执行前后立即获得的数据。仅在 v1 查询文件 启用时包含。

beforeHostMemoryUsed

timeStart 时的主机内存使用量(KiB)。

afterHostMemoryUsed

timeStop 时的主机内存使用量(KiB)。

beforeCPULoadAverage

timeStart 时的平均 CPU 负载。

afterCPULoadAverage

timeStop 时的平均 CPU 负载。

示例

{
  "version": 1,
  "command" : "\"/usr/bin/c++\" \"-MD\" \"-MT\" \"CMakeFiles/main.dir/main.cxx.o\" \"-MF\" \"CMakeFiles/main.dir/main.cxx.o.d\" \"-o\" \"CMakeFiles/main.dir/main.cxx.o\" \"-c\" \"<src>/main.cxx\"",
  "role" : "compile",
  "return" : 1,
  "target": "main",
  "language" : "C++",
  "outputs" : [ "CMakeFiles/main.dir/main.cxx.o" ],
  "outputSizes" : [ 0 ],
  "source" : "<src>/main.cxx",
  "config" : "Debug",
  "dynamicSystemInformation" :
  {
    "afterCPULoadAverage" : 2.3500000000000001,
    "afterHostMemoryUsed" : 6635680.0
    "beforeCPULoadAverage" : 2.3500000000000001,
    "beforeHostMemoryUsed" : 6635832.0
  },
  "timeStart" : 1737053448177,
  "duration" : 31
}

v1 索引文件

索引文件包含 v1 代码段文件 的列表。它充当导航 instrumentation 数据的入口点。它们在 索引 发生时生成,并在任何用户指定的 回调 执行后删除。

version

索引文件的数据版本,一个整数。当前版本始终为 1

buildDir

CMake 项目的构建目录。

dataDir

<build>/.cmake/instrumentation/v1/data/ 目录的完整路径。

hook

负责生成索引文件的钩子的名称。除了可以通过 v1 查询文件 之一指定的钩子之外,如果通过调用 ctest --collect-instrumentation <build> 执行索引,则此值可以设置为 manual

snippets

包含 v1 代码段文件 的列表。这包括自上次创建索引文件以来生成的所有代码段文件。文件路径相对于 dataDir

staticSystemInformation

指定有关运行 CMake 的主机计算机的静态信息收集。仅在 v1 查询文件 启用时包含。

  • OSName

  • OSPlatform

  • OSRelease

  • OSVersion

  • familyId

  • hostname

  • is64Bits

  • modelId

  • numberOfLogicalCPU

  • numberOfPhysicalCPU

  • processorAPICID

  • processorCacheSize

  • processorClockFrequency

  • processorName

  • totalPhysicalMemory

  • totalVirtualMemory

  • vendorID

  • vendorString

示例

{
  "version": 1,
  "hook": "manual",
  "buildDir": "<build>",
  "dataDir": "<build>/.cmake/instrumentation/v1/data",
  "snippets": [
    "configure-<hash>-<timestamp>.json",
    "generate-<hash>-<timestamp>.json",
    "compile-<hash>-<timestamp>.json",
    "compile-<hash>-<timestamp>.json",
    "link-<hash>-<timestamp>.json",
    "install-<hash>-<timestamp>.json",
    "ctest-<hash>-<timestamp>.json",
    "test-<hash>-<timestamp>.json",
    "test-<hash>-<timestamp>.json",
  ]
}