Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 1 | # Clangd |
| 2 | |
| 3 | ## Introduction |
| 4 | |
Andrew Williams | bbc1a1e | 2021-07-21 01:51:22 | [diff] [blame] | 5 | [clangd](https://clangd.llvm.org/) is a clang-based [language server](https://langserver.org/). |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 6 | It brings IDE features (e.g. diagnostics, code completion, code navigations) to |
| 7 | your editor. |
| 8 | |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 9 | ## Quick Start |
| 10 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 11 | * [Get clangd](#getting-clangd) |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 12 | * Make sure generated ninja files are up-to-date |
| 13 | * Optional: build chrome normally to get generated headers |
| 14 | * Generate compilation database (note: it's not regenerated automatically): |
| 15 | ``` |
Orr Bernstein | 197b492a | 2023-05-31 19:26:33 | [diff] [blame] | 16 | tools/clang/scripts/generate_compdb.py -p out/Default > compile_commands.json |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 17 | ``` |
Orr Bernstein | 197b492a | 2023-05-31 19:26:33 | [diff] [blame] | 18 | |
| 19 | *** note |
| 20 | Note: If you're using a different build directory, you'll need to replace `out/Default` |
| 21 | in this and other commands with your build directory. |
| 22 | *** |
| 23 | |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 24 | * Indexing is enabled by default (since clangd 9), note that this might consume |
| 25 | lots of CPU and RAM. There's also a |
| 26 | [remote-index service](https://github.com/clangd/chrome-remote-index/blob/main/docs/index.md) |
| 27 | to have an instant project-wide index without consuming local resources |
Delan Azabani | d431ca7 | 2022-01-26 09:03:46 | [diff] [blame] | 28 | (requires clangd 12+ built with remote index support). |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 29 | * Use clangd in your favourite editor |
| 30 | |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 31 | ## Getting clangd |
| 32 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 33 | For the best results, you should use a clangd that exactly matches the version |
| 34 | of Clang used by Chromium. This avoids problems like mismatched versions of |
| 35 | compiler diagnostics. |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 36 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 37 | The easiest way to do this is to set the `checkout_clangd` var in `.gclient`: |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 38 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 39 | ``` |
| 40 | solutions = [ |
| 41 | { |
| 42 | "url": "https://chromium.googlesource.com/chromium/src.git", |
| 43 | "managed": False, |
| 44 | "name": "src", |
| 45 | "custom_deps": {}, |
| 46 | "custom_vars": { |
| 47 | "checkout_clangd": True, |
| 48 | }, |
| 49 | }, |
| 50 | ] |
| 51 | ``` |
Jesse McKenna | f454c39 | 2020-06-05 01:10:16 | [diff] [blame] | 52 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 53 | After this, `gclient` will keep the binary at |
| 54 | `third_party/llvm-build/Release+Asserts/bin/clangd` in sync with the version of |
| 55 | Clang used by Chromium. |
Jesse McKenna | f454c39 | 2020-06-05 01:10:16 | [diff] [blame] | 56 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 57 | Alternatively, you may use the `build_clang_tools_extra.py` script to build |
| 58 | clangd from source: |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 59 | |
| 60 | ``` |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 61 | tools/clang/scripts/build_clang_tools_extra.py --fetch out/Default clangd |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 62 | ``` |
| 63 | |
K. Moon | 5ecc4b1 | 2022-08-29 17:28:44 | [diff] [blame] | 64 | The resulting binary will be at |
| 65 | `out/Default/tools/clang/third_party/llvm/build/bin/clangd`. |
| 66 | |
| 67 | Once you have an appropriate clangd binary, you must configure your editor to |
| 68 | use it, either by placing it first on your `PATH`, or through editor-specific |
| 69 | configuration. |
| 70 | |
K. Moon | e7c4598 | 2022-08-31 18:49:19 | [diff] [blame] | 71 | *** note |
| 72 | Note: The clangd provided by Chromium does not support optional features like |
Delan Azabani | 9e7f4ce | 2024-05-02 11:55:18 | [diff] [blame] | 73 | remote indexing (see https://crbug.com/1358258), such that `clangd --version` |
| 74 | will not mention `grpc`, and you will see “Unknown Index key External” warnings |
| 75 | in the clangd log. |
| 76 | |
| 77 | If you want those features, you'll need to use a different build of clangd, |
| 78 | such as the [clangd/clangd releases on |
| 79 | GitHub](https://github.com/clangd/clangd/releases). |
K. Moon | e7c4598 | 2022-08-31 18:49:19 | [diff] [blame] | 80 | *** |
| 81 | |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 82 | ## Setting Up |
| 83 | |
David Benjamin | f676adb1 | 2019-05-07 07:19:10 | [diff] [blame] | 84 | 1. Make sure generated ninja files are up-to-date. |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 85 | |
| 86 | ``` |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 87 | gn gen out/Default |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 88 | ``` |
| 89 | |
| 90 | 2. Generate the compilation database, clangd needs it to know how to build a |
| 91 | source file. |
| 92 | |
| 93 | ``` |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 94 | tools/clang/scripts/generate_compdb.py -p out/Default > compile_commands.json |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 95 | ``` |
| 96 | |
Jesse McKenna | f454c39 | 2020-06-05 01:10:16 | [diff] [blame] | 97 | Note: the compilation database is not regenerated automatically. You need to |
| 98 | regenerate it manually whenever build rules change, e.g., when you have new files |
Fergal Daly | 6e02857 | 2020-06-02 09:43:05 | [diff] [blame] | 99 | checked in or when you sync to head. |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 100 | |
Jesse McKenna | 454b946f | 2020-05-08 18:23:10 | [diff] [blame] | 101 | If using Windows PowerShell, use the following command instead to set the |
| 102 | output's encoding to UTF-8 (otherwise Clangd will hit "YAML:1:4: error: Got |
| 103 | empty plain scalar" while parsing it). |
| 104 | |
| 105 | ``` |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 106 | tools/clang/scripts/generate_compdb.py -p out/Default | out-file -encoding utf8 compile_commands.json |
Jesse McKenna | 454b946f | 2020-05-08 18:23:10 | [diff] [blame] | 107 | ``` |
| 108 | |
David Benjamin | f676adb1 | 2019-05-07 07:19:10 | [diff] [blame] | 109 | 3. Optional: build chrome normally. This ensures generated headers exist and are |
| 110 | up-to-date. clangd will still work without this step, but it may give errors or |
| 111 | inaccurate results for files which depend on generated headers. |
| 112 | |
| 113 | ``` |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 114 | ninja -C out/Default chrome |
David Benjamin | f676adb1 | 2019-05-07 07:19:10 | [diff] [blame] | 115 | ``` |
| 116 | |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 117 | 4. Optional: configure clangd to use remote-index service for an instant |
| 118 | project-wide index and reduced local CPU and RAM usage. See |
| 119 | [instructions](https://github.com/clangd/chrome-remote-index/blob/main/docs/index.md). |
| 120 | |
| 121 | 5. Use clangd in your favourite editor, see detailed [instructions]( |
Andrew Williams | bbc1a1e | 2021-07-21 01:51:22 | [diff] [blame] | 122 | https://clangd.llvm.org/installation.html#editor-plugins). |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 123 | |
Victor Vianna | 41857588 | 2023-02-20 16:19:44 | [diff] [blame] | 124 | * Optional: You may want to add `--header-insertion=never` to the clangd |
Avi Drissman | d4459db | 2023-01-18 02:45:14 | [diff] [blame] | 125 | flags, so that your editor doesn't automatically add incorrect #include |
| 126 | lines. The feature doesn't correctly handle some common Chromium headers |
Lei Zhang | c5f765d5 | 2023-11-08 00:53:33 | [diff] [blame] | 127 | like `base/functional/callback_forward.h`. |
Joe Mason | ee336f8 | 2022-01-19 22:39:09 | [diff] [blame] | 128 | |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 129 | ## Background Indexing |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 130 | |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 131 | clangd builds an incremental index of your project (all files listed in the |
| 132 | compilation database). The index improves code navigation features |
| 133 | (go-to-definition, find-references) and code completion. |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 134 | |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 135 | * clangd only uses idle cores to build the index, you can limit the total amount |
| 136 | of cores by passing the *-j=\<number\>* flag; |
Henrique Ferreiro | cb65542 | 2023-12-02 09:52:23 | [diff] [blame] | 137 | * the index is saved to the `.cache/clangd/index` in the project root; index |
| 138 | shards for common headers e.g. STL will be stored in |
| 139 | *$HOME/.cache/clangd/index*; |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 140 | * background indexing can be disabled by the `--background-index=false` flag; |
| 141 | Note that, disabling background-index will limit clangd’s knowledge about your |
| 142 | codebase to files you are currently editing. |
| 143 | |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 144 | Note: the first index time may take hours (for reference, it took 2~3 hours on |
Ivan Šandrk | de3cc76 | 2020-12-02 16:55:28 | [diff] [blame] | 145 | a 48-core, 64GB machine). A full index of Chromium (including v8, blink) takes |
| 146 | ~550 MB disk space and ~2.7 GB memory in clangd. |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 147 | |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 148 | Note: [Remote-index service](https://github.com/clangd/chrome-remote-index/blob/main/docs/index.md) |
| 149 | replaces background-index with some downsides like being ~a day old (Clangd will |
| 150 | still know about your changes in the current editing session) and not covering |
| 151 | all configurations (not available for mac&windows specific code or non-main |
| 152 | branches). |
| 153 | |
Haojian Wu | aa891f17 | 2019-04-05 14:56:52 | [diff] [blame] | 154 | ## Questions |
| 155 | |
Kadir Cetinkaya | 235b714 | 2021-09-21 07:24:38 | [diff] [blame] | 156 | If you have any questions, reach out to |
| 157 | [clangd/clangd](https://github.com/clangd/clangd) or [email protected]. |