cmake-instrumentation(7)

4.0 版本新增。

简介

注意

此功能仅在已通过 CMAKE_EXPERIMENTAL_INSTRUMENTATION 门启用实验性检测支持时可用。

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

此功能仅适用于使用 Makefile 生成器Ninja 生成器 的项目。

所有与 CMake 检测 API 的交互都必须指定 API 版本和数据版本。目前,每个只有一个版本:API v1数据 v1

数据收集

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

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

索引

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

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

回调

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

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

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

启用检测

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

在项目级别启用检测

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

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

在用户级别启用检测

可以通过将查询文件放置在 CMAKE_CONFIG_DIR<config_dir>/instrumentation/<version>/query/ 下来在用户级别配置检测。

为 CDash 提交启用检测

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

下表显示了每种类型的检测命令如何映射到相应类型的 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 版本指定检测数据的子目录布局以及查询文件的格式。

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

query/

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

query/generated/

保存由 CMake 项目通过 cmake_instrumentation() 命令生成的查询文件。这些文件由 CMake 拥有,并在 CMake 配置步骤中自动删除和重新生成。

data/

保存项目上收集的检测数据。CMake 拥有所有数据文件,它们不应由其他进程删除。此处收集的数据会一直保留,直到 索引 发生并且所有 回调 执行完毕。

cdash/

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

v1 查询文件

instrumentation/v1/query/ 目录下所有带有 .json 扩展名的文件都被识别为检测数据的查询。

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

版本

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

回调

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

钩子

一个字符串列表,指定何时自动进行 索引。这些是应该整理检测数据并调用用户 回调 来处理数据的时间间隔。此列表中的元素应为以下之一

  • postGenerate

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

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

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

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

  • postInstall

  • postTest

查询

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

staticSystemInformation

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

dynamicSystemInformation

启用收集关于运行 CMake 的主机的动态信息。为 CMake 生成的每个 v1 代码片段文件 收集数据,并包含命令执行前后的信息。

列出的 callbacks 将在指定的 hooks 期间被调用,至少如此。当有多个查询文件时,它们之间的 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 数据。一旦两个回调都完成,索引文件及其列出的所有片段文件将从项目构建树中删除。

数据 v1

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

v1 代码片段文件

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

  • CMake 配置步骤

  • CMake 生成步骤

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

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

  • 每次 ctest 调用

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

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

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

版本

片段文件的数据版本,一个整数。目前版本始终是 1

命令

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

workingDir

执行 command 的工作目录。

结果

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

角色

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

  • 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 执行的单个测试

目标

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

targetType

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

targetLabels

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

timeStart

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

持续时间

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

输出

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

outputSizes

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

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

语言

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

testName

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

配置

构建类型,例如 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 代码片段文件 列表。它作为导航检测数据的入口点。它们在 索引 发生时生成,并在执行任何用户指定 回调 后删除。

版本

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

buildDir

CMake 项目的构建目录。

dataDir

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

钩子

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

代码片段

包含一个 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",
  ]
}