# Clang

Chromium ships a prebuilt [clang](http://clang.llvm.org) binary.
It's just upstream clang built at a known-good revision that we
bump every two weeks or so.

This is the only supported compiler for building Chromium.

[TOC]

## Using gcc on Linux

`is_clang = false` will make the build use system gcc on Linux. There are no
bots that test this and there is no guarantee it will work, but we accept
patches for this configuration.

## Mailing List

https://groups.google.com/a/chromium.org/group/clang/topics

## Using plugins

The
[chromium style plugin](https://dev.chromium.org/developers/coding-style/chromium-style-checker-errors)
is used by default when clang is used.

If you're working on the plugin, you can build it locally like so:

1.  Run `./tools/clang/scripts/build.py --without-android --without-fuchsia`
    to build the plugin.
1.  Run `ninja -C third_party/llvm-build/Release+Asserts/` to build
    incrementally after making changes.
1.  Run `(cd tools/clang/plugins/tests && ./test.py ../../../../third_party/llvm-build/Release+Asserts/bin/clang)`
    to test the plugin after making changes.
1.  Build Chromium with clang as usual, but, if you use reclient, disable it.

The local plugin will then be used for local builds until the next
`gclient sync` restores the default toolchain.

Since the plugin is rolled with clang changes, behavior changes to the plugin
should be guarded by flags to make it easy to roll clang without introducing
unexpected breakage. A general outline:
1.  Implement new plugin behavior behind a flag, disabled by default.
1.  Wait for a compiler roll to bring in the flag.
1.  Start passing the new flag in `GN` and verify the new behavior.
1.  Enable the new plugin behavior unconditionally and update the plugin to
    ignore the flag.
1.  Wait for another compiler roll.
1.  Stop passing the flag from `GN`.
1.  Remove the flag completely.

## Using the clang static analyzer

See [clang_static_analyzer.md](clang_static_analyzer.md).

## Windows

clang is the default compiler on Windows. It uses MSVC's SDK, so you still need
to have Visual Studio with C++ support installed.

## Using a custom clang binary

There are three main ways of using a custom clang (or lld, etc.) binary for the
build.

1. **Point the Chromium build to your custom clang.**

   Set `clang_base_path` in your args.gn to the llvm build directory
   containing `bin/clang` (i.e. the directory you ran cmake). This must be an
   absolute path. You also need to disable chromium's clang plugins.

   Here's an example that also disables debug info and enables the component
   build (both not strictly necessary, but they will speed up your build):

   ```
   clang_base_path = getenv("HOME") + "/src/llvm-build"
   clang_use_chrome_plugins = false
   is_debug = false
   symbol_level = 1
   is_component_build = true
   ```

   On Windows, for `clang_base_path` use something like this instead:

   ```
   clang_base_path = "c:/src/llvm-build"
   ```

   You can then look in `out/gn/toolchain.ninja` and check that the `rule cc` and
   `rule cxx` commands run your clang binary.  If things look good, run `ninja
   -C out/gn` to build.

   Chromium tries to be buildable with its currently pinned clang, and with clang
   trunk. Set `llvm_force_head_revision = true` in your args.gn if the clang you're
   trying to build with is closer to clang trunk than to Chromium's pinned clang
   (which `tools/clang/scripts/update.py --print-revision` prints).

2. **Bring your custom clang into the Chromium tree.**

   Chromium's clang binary lives at
   `third_party/llvm-build/Release+Asserts/bin/clang` (or `clang-cl.exe` on
   Windows). You can just copy your custom binary over that. Maybe a
   symlink works too.

   Unless your Clang includes support for Chromium's plugins, you'll still
   need to set `clang_use_chrome_plugins=false`.

   To get back to a default state when you're done, you can delete
   `third_party/llvm-build/` and re-sync.

3. **Rebuild Chromium's clang using `tools/clang/scripts/build.py`.**

   The binaries under `third_party/llvm-build/` are produced by `build.py`,
   using source code under `third_party/llvm/`. You can run the script to
   build it yourself, with modifications.

   For example, you can check out a specific revision under `third_party/llvm`,
   apply any local modifications, and build with `build.py --skip-checkout` to
   build a toolchain without overwriting your changes.

If you have access to remote execution (RBE), you can use that also with a
locally built clang binary -- as long as you're on Linux and the binary is
located inside the Chromium source tree (methods 2 and 3 above). Just set
`use_remoteexec=true` in your `gn` args.

See [crbug.com/451733085](https://crbug.com/451733085#comment7) for an example
of using the third approach to bisect over LLVM.

## Related documents

* [Toolchain support](toolchain_support.md) gives an overview of clang
  rolls, and documents when to revert clang rolls and how to file good
  toolchain bugs.

* [Updating clang](updating_clang.md) documents the mechanics of updating clang,
  and which files are included in the default clang package.

* [Clang Sheriffing](clang_sheriffing.md) contains instructions for how to debug
  compiler bugs, for clang sheriffs.

* [Clang Tool Refactoring](clang_tool_refactoring.md) has notes on how to build
  and run refactoring tools based on clang's libraries.

* [Updating Clang format binaries](updating_clang_format_binaries.md) has notes
  on how to update clang-format.

* [Toolchain Dashboard](https://commondatastorage.googleapis.com/chromium-browser-clang/toolchain-dashboard.html)
  tracks how fresh clang, rust, and libc++ are.
  (Google-internal short link: go/chrome-clang-dash)

* [Chromium Build Time](https://commondatastorage.googleapis.com/chromium-browser-clang/build-time.html)
  tracks how long Chromium takes to build.
  (Google-internal short link: go/chrome-build-time)

* [Chromium #include analysis](https://commondatastorage.googleapis.com/chromium-browser-clang/chrome_includes-index.html)
  tracks which of Chromium's headers contribute most to build time.
  (Google-internal short link: go/chrome-includes-archive, go/chrome-includes)
  NOTE: This currently does not handle module headers correctly
  ([bug](https://issues.chromium.org/issues/435303792)).

* [LLVM #include analysis](https://commondatastorage.googleapis.com/chromium-browser-clang/llvm_includes-index.html)
  tracks which of LLVM's headers contribute most to LLVM's build time.
  (LLVM does not use header modules, so it's unaffected by the bug linked to
  in the previous item.)
