1===================================== 2Formatting C++ Code With clang-format 3===================================== 4 5Mozilla uses the Google coding style for whitespace, which is enforced 6using `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__. A 7specific version of the binary will be installed when 8``./mach clang-format`` or ``./mach bootstrap`` are run. We build our 9own binaries and update them as needed. 10 11Options are explicitly defined `in clang-format 12itself <https://github.com/llvm-mirror/clang/blob/e8a55f98df6bda77ee2eaa7f7247bd655f79ae0e/lib/Format/Format.cpp#L856>`__. 13If the options are changed in clang upstream, this might cause some 14changes in the Firefox tree. For this reason, it is best to use the 15mozilla-provided binaries. 16 17Manual formatting 18----------------- 19 20We provide a mach subcommand for running clang-format from the 21command-line. This wrapper handles ensuring the correct version of 22clang-format is installed and run. 23 24If clang-format isn’t installed, the binaries will be automatically 25downloaded from taskcluster and installed into ~/.mozbuild. We build our 26own clang-format binaries. 27 28 29Formatting local changes 30~~~~~~~~~~~~~~~~~~~~~~~~ 31 32:: 33 34 $ ./mach clang-format 35 36When run without arguments, it will run on a local diff. This could miss 37some reformatting (for example, when blocks are touched). 38(`searchfox <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/python/mozbuild/mozbuild/code-analysis/mach_commands.py#1620>`__) 39 40 41Formatting specific paths 42~~~~~~~~~~~~~~~~~~~~~~~~~ 43 44:: 45 46 $ ./mach clang-format -p <path> # Format <path> in-place 47 $ ./mach clang-format -p <path> -s # Show changes 48 49The command also accepts a ``-p`` argument to reformat a specific 50directory or file, and a ``-s`` flag to show the changes instead of 51applying them to the working directory 52(`searchfox <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/python/mozbuild/mozbuild/code-analysis/mach_commands.py#1633>`__) 53 54 55Formatting specific commits / revisions 56~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 58:: 59 60 $ ./mach clang-format -c HEAD # Format a single git commit 61 $ ./mach clang-format -c HEAD~~..HEAD # Format a range of git commits 62 $ ./mach clang-format -c . # Format a single mercurial revision 63 64The command accepts a ``-c`` argument that takes a revision number or 65commit range, and will format the lines modified by those commits. 66(`searchfox <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/python/mozbuild/mozbuild/code-analysis/mach_commands.py#1635>`__) 67 68 69Scripting Clang-Format 70~~~~~~~~~~~~~~~~~~~~~~ 71 72Clang format expects that the path being passed to it is the path 73on-disk. If this is not the case, for example when formatting a 74temporary file, the "real" path must be specified. This can be done with 75the ``--assume-filename <path>`` argument. 76 77 78Configuring the clang-format commit hook 79~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80 81To run clang-format at commit phase, run ``mach boostrap`` or just add 82the following line in the ``hgrc`` file: 83 84.. code:: ini 85 86 [extensions] 87 clang-format = ~/.mozbuild/version-control-tools/hgext/clang-format 88 89We use a hg extension as they are more flexible than hooks. 90 91With git, the configuration is the following: 92 93:: 94 95 # From the root git directory: 96 $ ln -s $(pwd)/tools/lint/hooks_clang_format.py .git/hooks/pre-commit 97 98You'll likely need to install the ``python-hglib`` package for your OS, 99or else you may get errors like ``abort: No module named hglib.client!`` 100when you try to commit. 101 102 103Editor integration 104------------------ 105 106It is possible to configure many editors to support running 107``clang-format`` automatically on save, or when run from within the 108editor. 109 110 111Editor plugins 112~~~~~~~~~~~~~~ 113 114- `Atom <https://atom.io/packages/clang-format>`__ 115- `BBEdit <http://clang.llvm.org/docs/ClangFormat.html#bbedit-integration>`__ 116 117 - `clang-format-bbedit.applescript <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format-bbedit.applescript>`__ 118 119- Eclipse 120 121 - Install the 122 `CppStyle <https://marketplace.eclipse.org/content/cppstyle>`__ 123 plugin 124 - In Preferences -> C/C++ -> CppStyle, set the clang-format path to 125 ~/.mozbuild/clang-tools/clang-tidy/bin/clang-format 126 - (Optional) check "Run clang-format on file save" 127 128- `Emacs <http://clang.llvm.org/docs/ClangFormat.html#emacs-integration>`__ 129 130 - `clang-format.el <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format.el>`__ 131 (Or install 132 `clang-format <http://melpa.org/#/clang-format>`__ from MELPA) 133 - `google-c-style <http://melpa.org/#/google-c-style>`__ from MELPA 134 135- `Sublime Text <https://packagecontrol.io/packages/Clang%20Format>`__ 136 137 - `alternative 138 tool <https://github.com/rosshemsley/SublimeClangFormat>`__ 139 140- `Vim <http://clang.llvm.org/docs/ClangFormat.html#vim-integration>`__ 141 142 - `clang-format.py <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format.py>`__ 143 - `vim-clang-format <https://github.com/rhysd/vim-clang-format>`__ 144 145- `Visual 146 Studio <https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat>`__ 147 148 - `llvm.org plugin <http://llvm.org/builds/>`__ 149 - `Integrated support in Visual Studio 150 2017 <https://blogs.msdn.microsoft.com/vcblog/2018/03/13/clangformat-support-in-visual-studio-2017-15-7-preview-1/>`__ 151 152- `Visual Studio 153 Code <https://marketplace.visualstudio.com/items?itemName=xaver.clang-format>`__ 154- `XCode <https://github.com/travisjeffery/ClangFormat-Xcode>`__ 155- `Script for patch 156 reformatting <http://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting>`__ 157 158 - `clang-format-diff.py <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format-diff.py>`__ 159 160 161Configuration 162~~~~~~~~~~~~~ 163 164These tools generally run clang-format themselves, and won't use 165``./mach clang-format``. The binary installed by our tooling will be 166located at ``~/.mozbuild/clang-tools/clang-tidy/bin/clang-format``. 167 168You typically shouldn't need to specify any other special configuration 169in your editor besides the clang-format binary. Most of the 170configuration that clang-format relies on for formatting is stored 171inside our source tree. More specifically, using the .clang-format file 172located in the root of the repository. Please note that this doesn't 173include the list of ignored files and directories (provided by 174.clang-format-ignore which is a feature provided by the mach command 175wrapper). 176 177Coding style configuration is done within clang-format itself. When we 178change the configuration (incorrect configuration, new feature in clang, 179etc), we use `local 180overrides <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/.clang-format>`__. 181 182 183Ignored files & directories 184~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 186We maintain a `list of ignored directories and 187files <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/.clang-format-ignore>`__, 188which is used by ``./mach clang-format``. This is generally only used 189for code broken by clang-format, and third-party code. 190 191 192Ignored code hunks 193~~~~~~~~~~~~~~~~~~ 194 195Sections of code may have formatting disabled using comments. If a 196section must not be formatted, the following comments will disable the 197reformat: 198 199:: 200 201 // clang-format off 202 my code which should not be reformated 203 // clang-format on 204 205You can find an `example of code not 206formatted <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/xpcom/io/nsEscape.cpp#22>`__. 207 208 209Merging formatted and unformatted code 210-------------------------------------- 211 212During the transition to using chromium style enforced by clang-format 213for all code in tree, it will often be necessary to rebase non-formatted 214code onto a formatted tree. 215 216 217Mercurial 218~~~~~~~~~ 219 220The ``format-source`` extension, now bundled with 221``version-control-tools``, and installed by ``./mach bootstrap``, may be 222used to seamlessly handle this situation. More details may be found in 223this 224`document <https://docs.google.com/document/d/13AwAsvKMhH0mflDlfatBqn6LmZHiQih76oxM4zfrPl4/edit>`__. 225 226The parent changeset of the reformat has been tagged as 227``PRE_TREEWIDE_CLANG_FORMAT``. 228 229 230Git 231~~~ 232 233To perform a rebase onto mozilla-central after the merge, a handy merge 234driver, ``clang-format-merge``, has been written: 235 236.. code:: shell 237 238 $ git clone https://github.com/emilio/clang-format-merge 239 $ /path/to/clang-format-merge/git-wrapper rebase <upstream> 240 241The wrapper should clean up after itself, and the clone may be deleted 242after the rebase is complete. 243 244 245Ignore lists 246------------ 247 248To make sure that the blame/annotate features of Mercurial or git aren't 249affected. Two files are maintained to keep track of the reformatting 250commits. 251 252 253With Mercurial 254~~~~~~~~~~~~~~ 255 256| The list is stored in 257 `https://searchfox.org/mozilla-central/source/.hg-annotate-ignore-revs </en-US/docs/>`__ 258| Commit messages should also contain the string ``# ignore-this-changeset`` 259 260The syntax in this file is generated using the following syntax: 261 262:: 263 264 $ hg log --template '{node} - {author|person} - {desc|strip|firstline}\n' 265 266With git 267~~~~~~~~ 268 269The list is stored in 270`https://searchfox.org/mozilla-central/source/.git-blame-ignore-revs </en-US/docs/>`__ 271and contains git revisions for both gecko-dev and the git cinnabar 272repository. 273