diff --git a/Documentation/ClangdConfiguration.md b/Documentation/ClangdConfiguration.md new file mode 100644 index 00000000000..43b713da5f5 --- /dev/null +++ b/Documentation/ClangdConfiguration.md @@ -0,0 +1,57 @@ +# Configuring the clangd Language Server + +clangd is recommended as a C++ language server in general, as it is most likely to work on all platforms. + +CLion ships with a special build of clangd that usually works fine. Most other editors can be configured to use any build of clangd via the LSP or dedicated extensions/plugins. Refer to the editor-specific documentation on how to install and enable such extensions. + +## `.clangd` + +clangd uses `compile_commands.json` files to understand the project. CMake will generate these in directories such as Build/x86_64, Build/x86_64clang, and Build/lagom. +Depending on which configuration (architecture and toolchain) you use most, set the CompilationDatabase configuration item in the below `.clangd` file accordingly. + +The recommended `.clangd` file (at the root of your Serenity checkout) is as follows; it should work out of the box and can be adjusted as needed: + +```yaml +CompileFlags: + # Add compilation flags to remove errors, or to make clangd behave like you’re compiling a specific system configuration. + Add: [] + # You can remove unwanted flags such as those that aren't supported by the current version of clang. + Remove: [] + # Build/x86_64 is also possible if you don’t have the Clang toolchain, but doesn’t work as well. + CompilationDatabase: Build/x86_64clang + +Style: + # clangd 20+: Use correct include style. + AngledHeaders: ["AK/.*", "Userland/.*", "Kernel/.*", "Applications/.*", "Lib.*/.*"] + +Diagnostics: + UnusedIncludes: Strict + MissingIncludes: Loose +``` + +The UnusedIncludes and MissingIncludes flags are used to disable the [Include Cleaner](https://clangd.llvm.org/design/include-cleaner) feature of newer clangd releases. +It can be re-enabled if you don't mind the noisy inlay hints and problems. + +Adding and removing compiler flags can fix many bugs, but also be useful for better code comprehension. Here are some tips: + +- Add `-D__serenity__` if you are not using the Serenity toolchain clangd, so that clangd treats all code as being compiled for Serenity and not for your host system. +- Add the flags `-DKERNEL` or `-DPREKERNEL` if you want clangd to behave like the Kernel or Prekernel compilation, respectively. +- When using a GCC compilation database (e.g. Build/x86_64), clangd will frequently complain about command-line arguments at the top of files. For instance: `clang: Unknown argument: '-mpreferred-stack-boundary=3'`. To fix this, simply add `-mno-` to the `Add` list. In the example, that would be `-mno-preferred-stack-boundary`. +- There are also known issues with the GCC compilation database for the Kernel, here `-mno-sse` and `-mno-8087` may help. + +Run `./Meta/serenity.sh run` at least once to generate the `compile_commands.json` file. Every time a new source is added or the compilation commands get adjusted (through CMake) you need to rerun `./Meta/serenity.sh build` or any other build command in order to update the compile commands. Until you do so, clangd will not be aware of the new source or report incorrect compile errors. + +### clangd Command-line Arguments + +When using the system clangd, it has to be configured to find the cross-compiler’s built-in include paths. Otherwise, there will always be errors like “file \ not found”. The clangd command-line flag for this is `--query-driver=SERENITY_PATH/Toolchain/Local/**/*` where you have to replace SERENITY_PATH with the Serenity source directory. Some editors have placeholders you can use here (e.g. VSCode’s `${workspaceFolder}`). + +For clangd 19 and below, `--header-insertion=never` is strongly recommended, as this prevents clangd from inserting incorrectly-styled includes. See the [corresponding clangd issue](https://github.com/clangd/clangd/issues/1247). From clangd 20 onwards, this option is not needed anymore and replaced by the `AngledHeaders` directive that configures clangd’s include style correctly. + +## Using Serenity Toolchain clangd + +The LLVM/Clang toolchain for Serenity is capable of building a version of clangd that is aware of the Serenity targets and their configuration. In general, it is recommended to use this clangd, as it will additionally always be up-to-date. It does, however, require you to build the Clang toolchain. See [AdvancedBuildInstructions](AdvancedBuildInstructions.md#serenity-aware-clang-tools) for how to build this clangd. Then, configure your editor to use the clangd executable situated at `Toolchain/Local/clang/bin/clangd`. + +## Known Issues + +- Some distribution clangd packages still have issues identifying paths to the serenity cross-compilers' builtin include paths after supplying the `--query-driver` option. This has been seen on at least Debian. If the inlay hints suggest that `` cannot be found, first triple check your configuration matches the `.clangd` file from above, verify that you've run the OS via `Meta/serenity.sh run`, and quadruple check your clangd command-line arguments. If all of the above are correct, building `clangd` from the serenity clang toolchain is known to work. +- clangd has a tendency to crash when stressing bleeding edge compiler features. Sometimes, just opening `AK/Variant.h` is enough. You can usually just restart clangd. If that doesn't help, close currently open C++ files and/or switch branches before restarting, which helps sometimes. diff --git a/Documentation/EmacsConfiguration.md b/Documentation/EmacsConfiguration.md index 0e9f0700cf6..e7d38178ebc 100644 --- a/Documentation/EmacsConfiguration.md +++ b/Documentation/EmacsConfiguration.md @@ -4,29 +4,13 @@ Emacs can be configured with `lsp-mode` and `clangd` to work well. ### clangd -The official clangd extension can be used for C++ comprehension. You -can use the following `.clangd` file placed in the project root: +The official clangd extension can be used for C++ comprehension. Refer to [ClangdConfiguration](ClangdConfiguration.md) for how to configure clangd. -```yaml -CompileFlags: - CompilationDatabase: Build/x86_64 - Add: - - "-D__serenity__" - - "-UNO_TLS" - - "-I/path/to/serenity/Toolchain/Local/x86_64/x86_64-pc-serenity/include/c++/13.1.0" - - "-I/path/to/serenity/Toolchain/Local/x86_64/x86_64-pc-serenity/include/c++/13.1.0/x86_64-pc-serenity" +There are a few different ways to specify which clangd to use: -Diagnostics: - UnusedIncludes: None - MissingIncludes: None -``` - -You will need to change `/path/to/serenity` and change `13.1.0` to -whatever your GCC toolchain version at the time is. - -Run cmake (`Meta/serenity.sh run` or similar) at least once for this -to work, as it will generate the `Build/x86_64/compile_commands.json` -that is needed by `clangd`. +- By default, without configuration `lsp-mode` will try to find and use your system `clangd`. This is the easiest solution, but your system clangd might be out of date. +- You can manually specify any `clangd` binary with `lsp-clangd-binary-path`. +- You can have `lsp-mode` manage your `clangd` installation with emacs' `lsp-install-server`. This will install a `clangd` binary for you. ### lsp-mode @@ -35,21 +19,12 @@ that is needed by `clangd`. :hook ((c++-mode) . lsp-deferred) :commands lsp :config + ;; clangd arguments, refer to ClangdConfiguration.md for what other arguments may be needed. (setq lsp-clients-clangd-args '("-j=4" "-background-index" "--log=error" "--clang-tidy" "--enable-config")) - ;; Optionally, set the location of clangd -- See notes below for options. + ;; Optionally, set the location of clangd -- See above for options. (setq lsp-clangd-binary-path "/usr/bin/clangd")) - ``` -### clangd - -There are a few different ways to specify which clangd to use: - -- By default, without configuration `lsp-mode` will try to find and use your system `clangd`. This is the easiest solution, but your system clangd might be out of date. -- You can manually specify any `clangd` binary with `lsp-clangd-binary-path`, as shown in the use-package example above. -- You can have `lsp-mode` manage your `clangd` installation with emacs' `lsp-install-server`. This will install a `clangd` binary for you. -- You can build the LLVM toolchain, including `clangd`, from Serenity's repository. This is an advanced option that is not currently documented. - ### clang-format There are multiple packages to handle auto formatting with diff --git a/Documentation/HelixConfiguration.md b/Documentation/HelixConfiguration.md index 74106dd9a07..dd7c4f01695 100644 --- a/Documentation/HelixConfiguration.md +++ b/Documentation/HelixConfiguration.md @@ -1,29 +1,16 @@ # Helix Configuration -Helix comes with support for `clangd` and `clang-format` out of the box! However, a small bit of configuration is needed for it to work correctly with SerenityOS. +Helix comes with support for `clangd` and `clang-format` out of the box! Refer to [ClangdConfiguration](ClangdConfiguration.md) for how to configure clangd. -The following `.clangd` should be placed in the project root: - -```yaml -CompileFlags: - CompilationDatabase: Build/x86_64 # Or whatever architecture you're targeting, e.g. aarch64 - Add: [-D__serenity__] - -Diagnostics: - UnusedIncludes: None - MissingIncludes: None -``` - -You also need to configure the clangd server to detect headers properly from the Serenity toolchain. To do this, create a `.helix/languages.toml` file in the project root: +To configure clangd command-line arguments, create a `.helix/languages.toml` file in the project root: ```toml [language-server.serenity] command = "clangd" -args = ["--query-driver=/path/to/serenity/Toolchain/Local/**/*", "--header-insertion=never"] +# clangd arguments, refer to ClangdConfiguration.md for what may be needed. +args = [] [[language]] name = "cpp" language-servers = ["serenity"] ``` - -> Make sure to replace `/path/to/serenity` with the actual path in the snippet above! diff --git a/Documentation/NvimConfiguration.md b/Documentation/NvimConfiguration.md index cf4858ea889..a22998ef662 100644 --- a/Documentation/NvimConfiguration.md +++ b/Documentation/NvimConfiguration.md @@ -183,14 +183,4 @@ nmap gs :CocCommand clangd.switchSourceHeader vsplit # Configure .clangd -> **Note**: Every time a new source is added or the compilation commands get adjusted -> (through CMake) you need to rerun `./Meta/serenity.sh rebuild`. - -Link `ln -s /path/to/serenity/Build/x86_64/compile_commands.json /path/to/serenity/compile_commands.json`. - -Create `/path/to/serenity/.clangd` (replace `/path/to/serenity` -with your SerenityOS directory) with content of the clangd section in the -[VSCodeConfiguration.md](./VSCodeConfiguration.md). - -> **Note**: You can add a `Remove` part, where you can remove unwanted flags -> such as those that aren't supported by the current version of clang. +Configure `.clangd` as explained in [ClangdConfiguration](ClangdConfiguration.md). diff --git a/Documentation/README.md b/Documentation/README.md index 8c03b8713f3..31e72fc85d1 100644 --- a/Documentation/README.md +++ b/Documentation/README.md @@ -30,8 +30,9 @@ Make sure to read the basic [Build Instructions](BuildInstructions.md) first. - [Running On Raspberry Pi](RunningOnRaspberryPi.md) - [Known Hardware Compatibility](HardwareCompatibility.md) -## Configuring Editors +## Configuring Editors and Language Servers +- [clangd (all editors)](ClangdConfiguration.md) - [CLion](CLionConfiguration.md) - [Emacs](EmacsConfiguration.md) - [Helix](HelixConfiguration.md) diff --git a/Documentation/VSCodeConfiguration.md b/Documentation/VSCodeConfiguration.md index 5e3c57caf30..a9d118433b5 100644 --- a/Documentation/VSCodeConfiguration.md +++ b/Documentation/VSCodeConfiguration.md @@ -14,35 +14,7 @@ The recommended extensions for VS Code include: Clangd has the best support for cross-compiling workflows, especially if configured as noted below. The Microsoft C/C++ tools can work, but require a lot more configuration and may not understand the sysroot in use. -### clangd - -The official clangd extension can be used for C++ comprehension. It is recommended in general, as it is most likely to work on all platforms. - -clangd uses `compile_commands.json` files to understand the project. CMake will generate these in either Build/x86_64, Build/x86_64clang, and Build/lagom. -Depending on which configuration you use most, set the CompilationDatabase configuration item in the below `.clangd` file accordingly. It goes at the root of your checkout (`serenity/.clangd`): - -```yaml -CompileFlags: - Add: [-D__serenity__] - CompilationDatabase: Build/x86_64 - -Diagnostics: - UnusedIncludes: None - MissingIncludes: None -``` - -The UnusedIncludes and MissingIncludes flags are used to disable the [Include Cleaner](https://clangd.llvm.org/design/include-cleaner) feature of newer clangd releases. -It can be re-enabled if you don't mind the noisy inlay hints and problems in the problem view. - -Run `./Meta/serenity.sh run` at least once to generate the `compile_commands.json` file. - -In addition to the `.clangd` file, the `settings.json` file below has a required `clangd.arguments` entry for `--query-driver` that allows clangd to find the cross-compiler's built-in include paths. - -#### Known issues - -- Some distribution clangd packages still have issues identifying paths to the serenity cross-compilers' builtin include paths after supplying the `--query-driver` option from `settings.json`. This has been seen on at least Debian. If the inlay hints suggest that `` cannot be found, first triple check your configuration matches the `.clangd` file from this section, verify that you've run the OS via `Meta/serenity.sh run`, and quadruple check your `clangd.arguments` section in the project-local `settings.json` file. If all of the above are correct, building `clangd` from the serenity clang toolchain is known to work. See [AdvancedBuildInstructions](AdvancedBuildInstructions.md#serenity-aware-clang-tools) for steps on how to build it from source. After building from source, be sure to set `clangd.path` in your `settings.json` to `${workspaceFolder}/Toolchain/Local/clang/bin/clangd`. - -- clangd has a tendency to crash when stressing bleeding edge compiler features. You can usually just restart it via the command palette. If that doesn't help, close currently open C++ files and/or switch branches before restarting, which helps sometimes. +See [ClangdConfiguration](ClangdConfiguration.md) for information on how to configure clangd. ### DSL syntax highlighting @@ -149,11 +121,10 @@ These belong in the `.vscode/settings.json` of Serenity. // git commit message length "git.inputValidationLength": 72, "git.inputValidationSubjectLength": 72, - // Tell clangd to ask the cross-compilers for their builtin include paths - "clangd.arguments": [ - "--query-driver=${workspaceFolder}/Toolchain/Local/**/*", - "--header-insertion=never" // See https://github.com/clangd/clangd/issues/1247 - ] + // See ClangdConfiguration.md for arguments that may be needed. + "clangd.arguments": [], + // Set if needed. + "clangd.path": "..." } ```