- 性能测试
【免费下载链接】benchmark
A microbenchmark support library
本文基于 docs/releasing.md 中维护者定义的完整发布清单,逐环节拆解 Google Benchmark 项目从"验证构建"到"发布标签"再到"Python Wheel 自动构建"的整个版本发布链路,并结合 CMakeLists.txt、MODULE.bazel、pyproject.toml 等仓库文件说明每个步骤背后的工程原因。读完后,你将掌握一个同时维护 CMake、Bazel 双构建系统且附带 Python 绑定项目的标准发布操作,以及"为什么版本要提前写进配置文件""为什么 GitHub 的轻量标签必须改写成注释标签"这类关键细节。
一、发布前的总体准备
docs/releasing.md 定义的第一个前提是:确保当前处于main分支,并且已与远端 HEAD 完全同步,然后确认项目可以构建且测试能够运行。文档中给出了一个加速全量测试运行的实用技巧:
parallel -j0 exec ::: test/*_test这条命令配合 GNUparallel以"全部可用核心"(-j0)并行执行test/目录下编译出的各个*_test测试二进制。对照仓库中的测试目录 test/,其中每个*_test.cc源文件(如 test/basic_test.cc、test/filter_test.cc 等)都会编译为一个独立的可执行程序,因此test/*_test恰好覆盖全部功能测试入口。文档明确这一手段"至少能确保所有测试都能通过"——这是发布动作的第一道质量门禁,任何一项测试失败都应阻塞后续流程。
二、准备发布说明(Release Notes)
发布说明的来源是"上一个版本标签到 HEAD 之间的提交列表",文档给出的命令为:
git log $(git describe --abbrev=0 --tags)..HEAD其工作原理分两步:
git describe --abbrev=0 --tags输出"距离 HEAD 最近的一个标签名",即上一个发布版本(例如v1.8.3);- 外层的
git log <上一个标签>..HEAD列出自该标签之后到当前 HEAD 的所有提交。
维护者随后从这份提交列表中"挑选最有意义的条目"(Pick the most interesting)写入发布说明。这一做法保证了 Release Notes 与实际交付的代码差异严格对应,不遗漏、不虚构。
三、关键版本提交:同步更新 CMake 与 Bazel 两处版本号
发布流程中最容易被忽略、但影响面最大的一步是:在创建发布之前,先创建最后一个提交,把保存在CMakeLists.txt和MODULE.bazel中的版本号更新为即将发布的版本。
3.1 两个必须同步的版本位置
文档原文示例:
project (benchmark VERSION 1.8.0 LANGUAGES CXX)module(name = "com_github_google_benchmark", version="1.8.0")对照当前仓库的实际内容,这两处分别位于:
- CMakeLists.txt:
project (benchmark VERSION 1.8.4 LANGUAGES CXX) - MODULE.bazel:
module(name = "google_benchmark", version = "1.8.4")
两处分别服务不同的消费渠道:
CMakeLists.txt中的project(... VERSION ...)是 CMake 安装包的版本来源。下游通过find_package(benchmark REQUIRED)(见 README.md 中的 Usage with CMake 一节)导入库时,benchmark_VERSION就取自这里;MODULE.bazel中的version是 Bazel bzlmod 体系的模块版本声明,Bazel 模块用户在锁定依赖版本时以此为准。根目录的 WORKSPACE.bzlmod 仅标记了 Bazel workspace 的根,真正的依赖与版本信息都集中在MODULE.bazel中。
文档特别解释了这一步的必要性:
This version will be used if benchmark is installed from the archive you'll be creating in the next step.
也就是说,从 GitHub Release 页面下载的是纯源码压缩包(不含.git目录),此时只能依赖配置文件里写死的版本号。仓库源码印证了这一机制:CMakeLists.txt 中有一段版本探测逻辑——构建时先通过GetGitVersion模块读取 git 标签得到GIT_VERSION;当探测不到(GIT_VERSION为占位值v0.0.0,典型场景就是从源码归档构建、没有 git 历史)时,回退使用project()命令中的benchmark_VERSION作为VERSION。随后代码还会对版本号做归一化处理(去掉v前缀、把vX.Y-<距离数>-<hash>形式的描述式版本转成X.Y.Z),最终用于派生库的SOVERSION:
# If no git version can be determined, use the version # from the project() command if ("${GIT_VERSION}" STREQUAL "v0.0.0") set(VERSION "v${benchmark_VERSION}") else() set(VERSION "${GIT_VERSION}") endif()因此,如果发布前忘记提交这次版本更新,归档安装出来的库版本就会停留在上一个版本,属于典型的"发布事故"。这也是文档把版本提交安排在"创建 release"之前、并要求它是"最后一个提交"(one last commit)的原因。
3.2 操作要点小结
- 切换到
main并同步到 HEAD; - 确认构建与全部测试通过;
- 用
git log $(git describe --abbrev=0 --tags)..HEAD起草发布说明; - 提交版本号更新:同时修改
CMakeLists.txt的project(... VERSION ...)与MODULE.bazel的module(... version = ...),两处数值必须一致; - 进入标签与 Release 环节(下一节)。
四、创建 GitHub Release,并将轻量标签改写为注释标签
文档指出,通过 GitHub 界面创建 release 时,Git 层面实际产生的是一个轻量标签(lightweight tag)——它只是一个指向 commit 的普通引用,不携带标签者、时间戳和标签消息。为了保证后续工具链(尤其是基于标签的版本推导系统)能拿到完整元数据,需要把它改写为注释标签(annotated tag)。文档给出的完整命令序列:
git pull --tags git tag -a -f <tag> <tag> git push --force --tags origin逐步解读:
git pull --tags:先把远端刚创建的轻量标签拉取到本地;git tag -a -f <tag> <tag>:-a表示创建注释标签,-f表示强制覆盖已有的同名轻量标签。这里用"同名指向同名"的写法,等价于原地把轻量标签升级为注释标签(commit 指向不变,但引用对象由 commit 变为 tag 对象);git push --force --tags origin:由于远端已存在同名轻量标签,普通推送会被拒绝,因此必须--force强推标签引用。
这一步不能省略,它直接关系到最后一步 Python Wheel 的版本推导是否正确——下一节会解释。
五、确认 "Build and upload Python wheels" 工作流完成
本仓库为 Python 提供了基于 nanobind 的绑定(见 bindings/python/google_benchmark/BUILD 中的nanobind_extension目标),并配套了发布到 PyPI 的自动化流程。docs/releasing.md的最后一项要求:
- 确认 "Build and upload Python wheels" 这一 GitHub Actions 工作流运行完成;如果它没有自动触发,需要手动运行;
- 关键注意点(文档原文以 IMPORTANT 标出):手动重新运行工作流时,务必在 GitHub Actions 页面的 "Run workflow" 选项卡中,选择刚创建的
<tag>作为 workflow version,否则工作流会基于错误的提交/标签构建,产出的 Wheel 版本号将是错的。
这一"标签决定 Wheel 版本"的机制在仓库配置中可以找到直接证据:
- pyproject.toml 声明
dynamic = ["readme", "version"],即包版本是动态计算而非写死的; - pyproject.toml 的构建系统依赖
setuptools-scm[toml],该工具正是从git 标签推导版本号的——这解释了为什么第四节的"轻量标签改注释标签"必不可少:setuptools-scm读取标签信息时依赖完整的标签元数据,且版本数值必须来自本次发布的确切标签; - 安装后,绑定包通过 bindings/python/google_benchmark/version.py 中的
importlib.metadata.version("google-benchmark")对外暴露版本,因此工作流构建的 Wheel 版本号就是 PyPI 上用户看到的最终版本; - pyproject.toml 同时声明了
requires-python = ">=3.8",classifiers覆盖 Python 3.8~3.12,Wheel 的构建与校验应以这些约束为前提。
验证环节完成后,一次发布才算真正结束:C/C++ 用户通过源码归档 +find_package/add_subdirectory消费新版本,Bazel 模块用户通过 bzlmod 锁定新版本,Python 用户通过 PyPI 安装新 Wheel,三条渠道的版本号完全一致。
六、发布检查清单(速查)
将 docs/releasing.md 的完整流程整理为可执行的检查清单:
| 步骤 | 命令 / 操作 | 说明 |
|---|---|---|
| 1. 分支确认 | git checkout main && git pull | 确保在 main 且同步到 HEAD |
| 2. 构建与测试 | 构建项目;parallel -j0 exec ::: test/*_test | 全部测试必须通过 |
| 3. 起草发布说明 | git log $(git describe --abbrev=0 --tags)..HEAD | 取上一标签到 HEAD 的提交列表,挑选关键条目 |
| 4. 版本提交 | 更新 CMakeLists.txt 的project(... VERSION ...)与 MODULE.bazel 的version | 必须提交,且数值一致;供无 git 环境的归档安装使用 |
| 5. 创建 Release | GitHub 界面创建 release | 实际生成轻量标签 |
| 6. 升级为注释标签 | git pull --tagsgit tag -a -f <tag> <tag>git push --force --tags origin | 保证标签元数据完整,供 setuptools-scm 等工具推导版本 |
| 7. Wheel 工作流 | 确认 "Build and upload Python wheels" 运行完成 | 手动重跑时必须在 "Run workflow" 中选择新<tag>作为 workflow version |
七、适用前提与注意事项
- 适用版本范围:当前仓库
CMakeLists.txt与MODULE.bazel中的版本为1.8.4,文档示例中的1.8.0为撰写时的占位版本,实际操作时以"即将发布的下一个版本号"替换两处数值即可。 - 版本探测机制的前提:CMakeLists.txt 中"git 标签优先、
project()版本兜底"的双轨机制意味着:带完整 git 历史的克隆仓库构建时,版本由标签决定;只有归档/子模块等无标签场景才回落到project()版本。发布前提交版本号的收益主要体现在后者。 - 强制推送的安全性:
git push --force --tags仅影响标签引用(tag ref),不影响main分支的 commit 历史,但会覆盖远端同名标签,操作前应确认标签确实指向本次发布提交。 - Bazel 消费方:模块名与版本以 MODULE.bazel 为准(
google_benchmark,当前1.8.4),该文件还声明了bazel_skylib、rules_cc、googletest等构建依赖,发布时仅需改动其中的version字段,不应连带改动依赖声明。
八、总结
Google Benchmark 的发布流程看似只是几条命令,实则串联了三条版本消费渠道(CMake 归档安装、Bazel bzlmod、PyPI Wheel)和一套完整的质量门禁。其设计要点可以概括为:先验证(构建+全量测试)、再定版(双配置文件同步提交,保证归档可用)、后打标(注释标签保证元数据完整)、最后验渠道(Wheel 工作流绑定正确标签)。理解了GetGitVersion的兜底逻辑与setuptools-scm的标签驱动机制之后,文档中每一步"为什么必须这样做"就有了清晰的源码级依据。
- 性能测试
【免费下载链接】benchmark
A microbenchmark support library
相关推荐
如何3步掌握AMD处理器调试:硬件性能调优完整指南
如何3步掌握AMD处理器调试:硬件性能调优完整指南 您是否曾为AMD Ryzen处理器性能无法完全释放而苦恼?是否想要像硬件工程师一样深度掌控您的处理器,却苦于
性能测试开发工具最完整指南:notepad--版本标签管理与Git发布全流程解析
最完整指南:notepad 版本标签管理与Git发布全流程解析 作为一款支持Windows/Linux/Mac平台的国产文本编辑器,notepad 致力于提供跨
桌面应用开发者必看:battleforthenet-widget源码解析与扩展指南
开发者必看:battleforthenet widget源码解析与扩展指南 battleforthenet widget是一款用于支持网络中立性的开源工具,开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考