Formatting C++ Code With clang-format

Mozilla uses the Google coding style for whitespace, which is enforced using clang-format. A specific version of the binary will be installed when ./mach bootstrap is run. We build our own binaries and update them as needed.

Options are explicitly defined in clang-format itself. If the options are changed in clang upstream, this might cause some changes in the Firefox tree. For this reason, it is best to use the mozilla-provided binaries.

Manual formatting

We provide mach subcommands for running clang-format from the command-line. These wrappers handle ensuring the correct version of clang-format is installed and run.

If clang-format isn’t installed, the binaries will be automatically downloaded from taskcluster and installed into ~/.mozbuild. We build our own clang-format binaries.

Formatting local changes

$ ./mach lint -l clang-format

When run without path arguments, it will lint the files you have modified.

To automatically fix formatting issues:

$ ./mach format -l clang-format

Or equivalently:

$ ./mach lint -l clang-format --fix

Formatting specific paths

$ ./mach format <path>   # Format <path> in-place, picks the right formatter

The command accepts paths to reformat specific directories or files, automatically selecting the appropriate formatter.

Configuring the clang-format commit hook

To run clang-format at commit phase, run mach bootstrap or just add the following line in the hgrc file:

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

We use a hg extension as they are more flexible than hooks.

With git, the configuration is the following:

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

You’ll likely need to install the python-hglib package for your OS, or else you may get errors like abort: No module named hglib.client! when you try to commit.

Editor integration

It is possible to configure many editors to support running clang-format automatically on save, or when run from within the editor.

Editor plugins

Configuration

These tools generally run clang-format themselves, and won’t use ./mach lint. The binary installed by our tooling will be located at ~/.mozbuild/clang-tools/clang-tidy/bin/clang-format.

You typically shouldn’t need to specify any other special configuration in your editor besides the clang-format binary. Most of the configuration that clang-format relies on for formatting is stored inside our source tree. More specifically, using the .clang-format file located in the root of the repository. Please note that this doesn’t include the list of ignored files and directories (provided by .clang-format-ignore which is a feature provided by the mach command wrapper).

Coding style configuration is done within clang-format itself. When we change the configuration (incorrect configuration, new feature in clang, etc), we use local overrides.

Ignored files & directories

We maintain a list of ignored directories and files, which is used by ./mach lint -l clang-format. This is generally only used for code broken by clang-format, and third-party code.

Ignored code hunks

Sections of code may have formatting disabled using comments. If a section must not be formatted, the following comments will disable the reformat:

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

You can find an example of code not formatted.

Ignore lists

To make sure that the blame/annotate features of Mercurial or git aren’t affected. Two files are maintained to keep track of the reformatting commits.

With Mercurial

Commit messages should also contain the string # ignore-this-changeset

The syntax in this file is generated using the following syntax:

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

With git

The list is stored in https://searchfox.org/mozilla-central/source/.git-blame-ignore-revs and contains git revisions for both gecko-dev and the git cinnabar repository.