使用 clang-format 格式化 C++ 代码

Mozilla 使用 Google 编码风格进行空白字符处理,并使用 clang-format 强制执行。运行 ./mach clang-format./mach bootstrap 时,会安装特定版本的二进制文件。我们构建自己的二进制文件,并根据需要更新它们。

选项在 clang-format 本身 中明确定义。如果 clang 上游更改了选项,则可能会导致 Firefox 代码树中的一些更改。因此,最好使用 Mozilla 提供的二进制文件。

手动格式化

我们提供了一个 mach 子命令,用于从命令行运行 clang-format。此包装器负责确保安装并运行正确版本的 clang-format。

如果 clang-format 未安装,则会自动从 taskcluster 下载二进制文件并安装到 ~/.mozbuild。我们构建自己的 clang-format 二进制文件。

格式化本地更改

$ ./mach clang-format

在不带参数运行时,它将在本地 diff 上运行。这可能会错过一些重新格式化操作(例如,当块被修改时)。(searchfox)

格式化特定路径

$ ./mach clang-format -p <path>     # Format <path> in-place
$ ./mach clang-format -p <path> -s  # Show changes

该命令还接受一个 -p 参数来重新格式化特定目录或文件,以及一个 -s 标志来显示更改而不是将其应用于工作目录 (searchfox)

格式化特定提交/修订版本

$ ./mach clang-format -c HEAD # Format a single git commit
$ ./mach clang-format -c HEAD~~..HEAD # Format a range of git commits
$ ./mach clang-format -c . # Format a single mercurial revision

该命令接受一个 -c 参数,该参数接受修订版本号或提交范围,并将格式化这些提交修改的行。(searchfox)

Clang-Format 脚本

Clang format 期望传递给它的路径是磁盘上的路径。如果不是这种情况,例如格式化临时文件时,必须指定“真实”路径。这可以通过 --assume-filename <path> 参数来完成。

配置 clang-format 提交钩子

要在提交阶段运行 clang-format,请运行 mach bootstrap 或仅在 hgrc 文件中添加以下行

[extensions]
clang-format = ~/.mozbuild/version-control-tools/hgext/clang-format

我们使用 hg 扩展,因为它们比钩子更灵活。

对于 git,配置如下

# From the root git directory:
$ ln -s $(pwd)/tools/lint/hooks_clang_format.py .git/hooks/pre-commit

您可能需要为您的操作系统安装 python-hglib 包,否则在尝试提交时可能会遇到类似 abort: No module named hglib.client! 的错误。

编辑器集成

可以配置许多编辑器以支持在保存时或从编辑器内部运行时自动运行 clang-format

编辑器插件

配置

这些工具通常自己运行 clang-format,不会使用 ./mach clang-format。我们的工具安装的二进制文件位于 ~/.mozbuild/clang-tools/clang-tidy/bin/clang-format

除了 clang-format 二进制文件之外,您通常不需要在编辑器中指定任何其他特殊配置。clang-format 依赖的大部分格式化配置都存储在我们的源代码树中。更具体地说,使用位于存储库根目录下的 .clang-format 文件。请注意,这并不包括被忽略的文件和目录列表(由 .clang-format-ignore 提供,这是一个由 mach 命令包装器提供的功能)。

编码风格配置在 clang-format 本身中完成。当我们更改配置(错误的配置、clang 中的新功能等)时,我们使用 本地覆盖

被忽略的文件 & 目录

我们维护一个 被忽略的目录和文件的列表,它由 ./mach clang-format 使用。这通常仅用于 clang-format 损坏的代码和第三方代码。

被忽略的代码块

可以使用注释禁用代码部分的格式化。如果必须不格式化某个部分,以下注释将禁用重新格式化

// clang-format off
my code which should not be reformatted
// clang-format on

您可以在 此处找到未格式化代码的示例

忽略列表

为了确保 Mercurial 或 git 的 blame/annotate 功能不受影响。维护两个文件来跟踪重新格式化提交。

使用 Mercurial

提交消息也应该包含字符串 # ignore-this-changeset

此文件中的语法使用以下语法生成

$ hg log --template '{node} - {author|person} - {desc|strip|firstline}\n'

使用 git

该列表存储在 https://searchfox.org/mozilla-central/source/.git-blame-ignore-revs 中,包含 gecko-dev 和 git cinnabar 存储库的 git 修订版本。