clangd / clangd

clangd language server
https://clangd.llvm.org
Apache License 2.0
1.5k stars 63 forks source link

Documentation about .clangd configuration file feels a bit incomplete #649

Open ell1e opened 3 years ago

ell1e commented 3 years ago

I am struggling to figure out how to write a config file, because the documentation about the .clangd configuration file found here https://clangd.llvm.org/config.html feels a bit incomplete. Here is the things that I missed:

  1. No useful example for If in combination with something else. Can I change the Index settings inside an If? How does that look like, especially if I want to globally enable it but then disable it on some files? I'm not sure
  2. Where are these "clangd logs" that are mentioned but not linked to some article for their location to check for config errors? Isn't there some tool like clangd --config-test ...path.../.clangd that can just tell me if the config is faulty?
  3. Can I exclude files from errors in general, even when opened directly? I have some files that do not compile as singled out object files, so when I open them in VS Code I get a christmas tree of irrelevant errors. While the config documentation shows how to specify different flags for a file, it neither shows an example of how to exclude it from the background index nor from "foreground" errors when opened
  4. There is no example for a more complex example config file given, with maybe some more complex real world examples of If conditional blocks and such. It is a bit challenging to figure out if what I have in mind to possibly combine is actually possible or not.
sam-mccall commented 3 years ago

I agree, we should improve this.

Quick answers though:

  1. The Index block is a sibling to If, not nested in it. If applies to the whole config fragment. So if you want anything to not be conditional, you split the file into multiple fragments with a --- line.
  2. Logs are the stderr of the clangd process, different editors expose this in different ways, this is documented in the per-editor instructions on the setup page. clangd --check does exist and should do what you want, but isn't yet documented on the site. (It's new in clangd 12)
  3. No, there's no config option yet to disable diagnostics. It's on my list to get in before the 12 release cut.
  4. Yeah, there's probably too much describing the system and not enough examples, I'll try to add some soon.
laurynas-biveinis commented 3 years ago

Re. 2, I am trying to troubleshoot a .clangd file, but clangd --check does not appear to print any information about it, and remains silent even if I deliberately break the config file:

$ cat .clangd
# -Wunused-member-function false positive:
# https://github.com/clangd/clangd/issues/363
Diagnosticswithatypo:
  Suppress: [-Wunused-macros, -Wunused-member-function, -Wunused-template]
---
If:
  PathMatch: .*\.hpp
Diagnostics:
  Suppress: -Wunused-function
$ /usr/local/opt/llvm/bin/clangd --enable-config --check
I[07:23:48.187] clangd version 12.0.0
I[07:23:48.188] PID: 8235
I[07:23:48.188] Working directory: /Users/laurynas/unodb/llvm-12
I[07:23:48.188] argv[0]: /usr/local/opt/llvm/bin/clangd
I[07:23:48.188] argv[1]: --enable-config
I[07:23:48.188] argv[2]: --check
I[07:23:48.188] Entering check mode (no LSP server)
I[07:23:48.189] Testing on source file /var/folders/t2/k0br2w_j78zdnf6gnz5b4xgr0000gn/C/test.cc
I[07:23:48.189] Loading compilation database...
I[07:23:48.211] Failed to find compilation database for /var/folders/t2/k0br2w_j78zdnf6gnz5b4xgr0000gn/C/test.cc
I[07:23:48.211] Generic fallback command is: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang /var/folders/t2/k0br2w_j78zdnf6gnz5b4xgr0000gn/C/test.cc -fsyntax-only -resource-dir=/usr/local/Cellar/llvm/12.0.0/lib/clang/12.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
I[07:23:48.211] Imaginary source file contents:

      #include <stddef.h>
      #include <string>

      size_t N = 50;
      auto xxx = std::string(N, 'x');

I[07:23:48.211] Parsing command...
I[07:23:48.214] internal (cc1) args are: -cc1 -triple x86_64-apple-macosx11.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -fsyntax-only -disable-free -disable-llvm-verifier -discard-value-names -main-file-name test.cc -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fno-rounding-math -munwind-tables -target-sdk-version=11.1 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -tune-cpu generic -debugger-tuning=lldb -target-linker-version 609.8 -resource-dir /usr/local/Cellar/llvm/12.0.0/lib/clang/12.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -stdlib=libc++ -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /usr/local/Cellar/llvm/12.0.0/lib/clang/12.0.0/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -fdeprecated-macro -fdebug-compilation-dir /var/folders/t2/k0br2w_j78zdnf6gnz5b4xgr0000gn/C -ferror-limit 19 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fmax-type-align=16 -x c++ /var/folders/t2/k0br2w_j78zdnf6gnz5b4xgr0000gn/C/test.cc
I[07:23:48.215] Building preamble...
I[07:23:48.605] Indexing headers...
I[07:23:48.859] Building AST...
I[07:23:48.877] Indexing AST...
I[07:23:48.878] Testing features at each token (may be slow in large files)
I[07:23:48.885] All checks completed, 0 errors
sam-mccall commented 3 years ago

.clangd only applies to files that appears in your source tree, but --check without args tests a random temporary file (/var/folders/t2/...) so never even attempts to load your .clangd file. Pass an argument to --check instead.

laurynas-biveinis commented 3 years ago

Thanks @sam-mccall, I tried passing an arg to --check, but the output still says nothing about (a deliberately broken) .clangd:

$ cat .clangd
If:
  PathMatch: .*\.hpp
CompileFlags:
  Add: -Wno-unused-function
---
# -Wunused-member-function false positive:
# https://github.com/clangd/clangd/issues/363
CompileFlagsButNotReally: # broken here
  Add: [-Wno-unused-macros,-Wno-unused-member-function,-Wno-unused-template]
Diagnostics:
  ClangTidy:
    Add: *
$ /usr/local/opt/llvm/bin/clangd --enable-config --check=art.cpp
I[20:23:11.275] clangd version 12.0.0
I[20:23:11.275] PID: 20033
I[20:23:11.275] Working directory: /Users/laurynas/unodb/llvm-12
I[20:23:11.275] argv[0]: /usr/local/opt/llvm/bin/clangd
I[20:23:11.275] argv[1]: --enable-config
I[20:23:11.275] argv[2]: --check=art.cpp
I[20:23:11.275] Entering check mode (no LSP server)
I[20:23:11.275] Testing on source file /Users/laurynas/unodb/llvm-12/art.cpp
I[20:23:11.276] Loading compilation database...
I[20:23:11.296] Loaded compilation database from /Users/laurynas/unodb/llvm-12/compile_commands.json
I[20:23:11.297] Compile command from CDB is: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ --driver-mode=g++ -I/Users/laurynas/unodb/llvm-12/. -I/Users/laurynas/unodb/llvm-12/build.debug -isystem /Users/laurynas/unodb/llvm-12/3rd_party/GSL/include -isystem /usr/local/include -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -Werror -Wall -Wextra -Wconversion -Wdelete-non-virtual-dtor -Wdeprecated -Wgnu -Wimplicit -Wloop-analysis -Wparentheses -Wpedantic -Wpragmas -Wself-assign -Wshadow-all -Wabstract-vbase-init -Warray-bounds-pointer-arithmetic -Wassign-enum -Watomic-implicit-seq-cst -Wbad-function-cast -Wc++2a-compat -Wc++2a-extensions -Wcast-align -Wcast-qual -Wclass-varargs -Wcomma -Wconditional-uninitialized -Wcovered-switch-default -Wdate-time -Wdeprecated-implementations -Wdisabled-macro-expansion -Wdouble-promotion -Wduplicate-decl-specifier -Wduplicate-enum -Wduplicate-method-arg -Wduplicate-method-match -Wextra-semi-stmt -Wfloat-equal -Wformat-pedantic -Wformat=2 -Wheader-hygiene -Widiomatic-parentheses -Wimplicit-fallthrough -Wmain -Wmethod-signatures -Wmissing-noreturn -Wmissing-prototypes -Wmissing-variable-declarations -Wnewline-eof -Wnon-virtual-dtor -Wnonportable-system-include-path -Wold-style-cast -Wover-aligned -Wpacked -Wpointer-arith -Wprofile-instr-missing -Wredundant-parens -Wreserved-id-macro -Wshift-sign-overflow -Wstatic-in-inline -Wstrict-prototypes -Wsuper-class-method-mismatch -Wswitch-enum -Wtautological-compare -Wtautological-constant-in-range-compare -Wundef -Wundefined-func-template -Wundefined-reinterpret-cast -Wunreachable-code-aggressive -Wunused-exception-parameter -Wunused-macros -Wunused-member-function -Wunused-template -Wused-but-marked-unused -Wvector-conversion -Wvla -Wweak-template-vtables -Wweak-vtables -Wzero-as-null-pointer-constant -g -msse4.1 -O0 -std=c++17 -o CMakeFiles/unodb.dir/art.cpp.o -c /Users/laurynas/unodb/llvm-12/art.cpp -fsyntax-only -resource-dir=/usr/local/Cellar/llvm/12.0.0/lib/clang/12.0.0
I[20:23:11.297] Parsing command...
I[20:23:11.299] internal (cc1) args are: -cc1 -triple x86_64-apple-macosx11.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -fsyntax-only -disable-free -disable-llvm-verifier -discard-value-names -main-file-name art.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fno-rounding-math -munwind-tables -target-sdk-version=11.1 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -target-feature +sse4.1 -tune-cpu generic -debug-info-kind=standalone -dwarf-version=4 -debugger-tuning=lldb -target-linker-version 609.8 -resource-dir /usr/local/Cellar/llvm/12.0.0/lib/clang/12.0.0 -isystem /Users/laurynas/unodb/llvm-12/3rd_party/GSL/include -isystem /usr/local/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -I /Users/laurynas/unodb/llvm-12/. -I /Users/laurynas/unodb/llvm-12/build.debug -stdlib=libc++ -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/local/include -internal-isystem /usr/local/Cellar/llvm/12.0.0/lib/clang/12.0.0/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/include -O0 -Werror -Wall -Wextra -Wconversion -Wdelete-non-virtual-dtor -Wdeprecated -Wgnu -Wimplicit -Wloop-analysis -Wparentheses -Wpedantic -Wpragmas -Wself-assign -Wshadow-all -Wabstract-vbase-init -Warray-bounds-pointer-arithmetic -Wassign-enum -Watomic-implicit-seq-cst -Wbad-function-cast -Wc++2a-compat -Wc++2a-extensions -Wcast-align -Wcast-qual -Wclass-varargs -Wcomma -Wconditional-uninitialized -Wcovered-switch-default -Wdate-time -Wdeprecated-implementations -Wdisabled-macro-expansion -Wdouble-promotion -Wduplicate-decl-specifier -Wduplicate-enum -Wduplicate-method-arg -Wduplicate-method-match -Wextra-semi-stmt -Wfloat-equal -Wformat-pedantic -Wformat=2 -Wheader-hygiene -Widiomatic-parentheses -Wimplicit-fallthrough -Wmain -Wmethod-signatures -Wmissing-noreturn -Wmissing-prototypes -Wmissing-variable-declarations -Wnewline-eof -Wnon-virtual-dtor -Wnonportable-system-include-path -Wold-style-cast -Wover-aligned -Wpacked -Wpointer-arith -Wprofile-instr-missing -Wredundant-parens -Wreserved-id-macro -Wshift-sign-overflow -Wstatic-in-inline -Wstrict-prototypes -Wsuper-class-method-mismatch -Wswitch-enum -Wtautological-compare -Wtautological-constant-in-range-compare -Wundef -Wundefined-func-template -Wundefined-reinterpret-cast -Wunreachable-code-aggressive -Wunused-exception-parameter -Wunused-macros -Wunused-member-function -Wunused-template -Wused-but-marked-unused -Wvector-conversion -Wvla -Wweak-template-vtables -Wweak-vtables -Wzero-as-null-pointer-constant -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /Users/laurynas/unodb/llvm-12/build.debug -ferror-limit 19 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fmax-type-align=16 -x c++ /Users/laurynas/unodb/llvm-12/art.cpp
I[20:23:11.299] Building preamble...
I[20:23:11.885] Indexing headers...
I[20:23:12.273] Building AST...
I[20:23:12.512] Indexing AST...
I[20:23:12.516] Testing features at each token (may be slow in large files)
I[20:23:21.642] All checks completed, 0 errors
bgamari commented 3 years ago

@sam-mccall, I am also struggling to understand how .clangd is supposed to be used. Specifically, I have

$ mkdir include
$ touch include/testing.h
$ echo "#include <testing.h>" > test.c
$ cat >.clangd <<EOF
CompileFlags:
    Add: -Iinclude
EOF
$ clangd --version
clangd version 12.0.1
$ clangd --check=test.c --enable-config
...
E[16:39:21.746] [pp_file_not_found] Line 1: 'testing.h' file not found

Furthermore, if I replace .clangd with garbage the output from clangd is unchanged, suggesting that clangd made no attempt to parse the file.

I will also note that neither the motivation nor the semantics of the --enable-config flag are clear from the documentation (e.g. why isn't this the default behavior? does it only affect --check mode?)

HighCommander4 commented 3 years ago

@bgamari: CompileFlags: Add: modifies the command from the CDB (compile_commands.json) entry used for a file. The entry (and thus the compile_commands.json file) still needs to exist. [Edit: I was mistaken about this. Add: works fine even without a compile_commands.json, adding the flags to the fallback command that clangd uses to process the file.]

Have a look at the "Project Setup" section of this page for how to set up a CDB.

Alternatively, you can use the compile_flags.txt approach described in the same section to just use a simple set of flags for all files without a CDB.

kadircet commented 3 years ago

@bgamari thanks! this actually looks like a bug to me. We only load global config fragment (e.g. the one in ~/.config/clangd/config.yaml) in --check mode. I definitely don't remember the reasoning, so sent out https://reviews.llvm.org/D107130. Maybe there is a particular reason for not loading local configs, we shall see.

laurynas-biveinis commented 2 years ago

@kadircet is https://reviews.llvm.org/D107130 a part of 13.0.0 release? I have retested my setup from https://github.com/clangd/clangd/issues/649#issuecomment-822963908, but I get the exact same results - a project .clangd file seems to be ignored

HighCommander4 commented 2 years ago

is https://reviews.llvm.org/D107130 a part of 13.0.0 release?

Looks like it just missed it -- it was commited on Jul 30, and 13.0 branched on Jul 28.

grigorig commented 2 years ago

FWIW I also think the documentation for the configuration file is very confusing. A lot of details are missing and there are too few examples. Currently trying to figure out how to configure clang-tidy integration to my liking, but I can't figure out how to add multiple globs of checks! Please improve this, it shouldn't be hard to add a few more practical examples, for instance.

zeroxia commented 2 years ago

The documentation is too concise. It'd be much better to have a template with all available options in it. So a user can just customize it per their needs.

Today I put a .clangd file at project root, but the verbose message just show:

V[14:48:07.633] Config fragment: compiling .../.clangd:8 -> 0x00007EFF780144B0 (trusted=false)

If I move the exactly same .clangd file to ~/.config/clangd/config.yaml, then the log shows:

V[14:53:11.489] Config fragment: compiling .../.config/clangd/config.yaml:8 -> 0x00007F973C003710 (trusted=true)

And it worked.

But I don't know how to make the .clangd file being trusted...

HighCommander4 commented 2 years ago

Today I put a .clangd file at project root, but the verbose message just show:

V[14:48:07.633] Config fragment: compiling .../.clangd:8 -> 0x00007EFF780144B0 (trusted=false)

If I move the exactly same .clangd file to ~/.config/clangd/config.yaml, then the log shows:

V[14:53:11.489] Config fragment: compiling .../.config/clangd/config.yaml:8 -> 0x00007F973C003710 (trusted=true)

And it worked.

But I don't know how to make the .clangd file being trusted...

It looks like the only difference this "trusted" flag makes is whether one specific setting (to configure a remote index server) is respected. This setting can only be specified in the user config for security reasons.

So, assuming you're not using a remote index, the config file should work in the project directory as well.

zeroxia commented 2 years ago

This is the arguments used to launch clangd:

    "clangd.arguments": [
        "--compile-commands-dir=${workspaceFolder}",
        "--print-options",
        "--background-index",
        "--clang-tidy",
        // "--enable-config",
        "--pch-storage=memory",
        "--header-insertion=never",
        "--header-insertion-decorators",
        "--all-scopes-completion",
        "--completion-style=detailed",
        "-j=4",
        "--log=verbose"
    ],

No idea about the "remote index".

HighCommander4 commented 2 years ago

Remote index is a feature to consume the project's index from a remote machine instead of indexing locally; if you're not familiar with it it's safe to say you're not using it (and therefore you don't need to care about the "trusted" flag).


Anyways, from this comment it sounded like you tried using a .clangd config file in the project directory and something didn't work, but it's not clear to me what -- can you be more specific?

zeroxia commented 2 years ago

Remote index is a feature to consume the project's index from a remote machine instead of indexing locally; if you're not familiar with it it's safe to say you're not using it (and therefore you don't need to care about the "trusted" flag).

Anyways, from this comment it sounded like you tried using a .clangd config file in the project directory and something didn't work, but it's not clear to me what -- can you be more specific?

My setup is as follows:

  1. Windows 10, installed VirtualBox 6.1
  2. In virtual box, guest OS is Ubuntu 18.04, and VS code is running in this Ubuntu.
  3. In Ubuntu 18.04, docker image is ubuntu 18.04 based. VS Code use Docker container extension to do development inside this docker container.
  4. At ${workspaceFolder}, there is compile_commands.json
  5. clangd launch arguments:
    "clangd.arguments": [
        "--compile-commands-dir=${workspaceFolder}",
        "--print-options",
        "--background-index",
        "--clang-tidy",
        // "--enable-config",
        "--pch-storage=memory",
        "--header-insertion=never",
        "--header-insertion-decorators",
        "--all-scopes-completion",
        "--completion-style=detailed",
        "-j=4",
        "--log=verbose"
    ],
  6. Initiallly, I created ${workspaceFolder}/.clangd as follows:
    
    ---
    CompileFlags:
    Remove:
    - '-fno-canonical-system-headers'
    Add:
    - '-isystem'
    - '...(omitted).../external/data_engine/include'
    ...
And clangd extension log shows: `.clangd:2 -> 0x00007FD064002A20 (trusted=false)`
Some headers are not found and marked by red squiggles.
7. If I move this `.clangd` to be `~/.config/clangd/config.yaml`, and restart `clangd`, then log shows: `config.yaml:2 -> 0x00007FE8C4002610 (trusted=true)`, and `#include` error is dismissed (the header is correctly located)

* VS Code version: 1.63.2
* C/C++ extension version: 1.8.0 Pre-Release (I have `"C_Cpp.intelliSenseEngine": "Disabled",` setting applied)
* clangd extension version: v0.1.13
* clangd binary version:

$ find .vscode-server -name clangd -type f .vscode-server/data/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/13.0.0/clangd_13.0.0/bin/clangd ecarx@elvis: ~ $ .vscode-server/data/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/13.0.0/clangd_13.0.0/bin/clangd --version clangd version 13.0.0 (https://github.com/llvm/llvm-project d7b669b3a30345cfcdb2fde2af6f48aa4b94845d) Features: linux+grpc Platform: x86_64-unknown-linux-gnu

HighCommander4 commented 2 years ago

Thanks for the details.

Some headers are not found and marked by red squiggles.

Is the file containing the unresolved includes located in the directory tree of ${workspaceFolder}?

I ask because one difference between a project config and a user config that could potentially explain what you're seeing, is that the project config is scoped to files in the project's directory tree, meaning it is applied when you open a file contained inside ${workspaceFolder}, but not when you open a file outside of ${workspaceFolder}. By contrast, a user config is applied to any file you open.

zeroxia commented 2 years ago

@HighCommander4

Thanks. I believe you are right. I work on a project using very obsolete "bazel" (v0.5.3), and I cannot update the bazel (project won't build).

The project uses some third-party sources, and the sources are extracted to somewhere like ~/.cache/bazel/_bazel_<USERNAME>/f428e7e9652043d7b22f6d4c02d3b711/external/

Then sym links are created inside the project directory hierarchy.

Is there any measure to disable this security measure from clangd?

HighCommander4 commented 2 years ago

Is there any measure to disable this security measure from clangd?

The part about a config file being scoped to its directory is not a security measure, it's just how clangd searches for config files. When opening a file, it looks for a .clangd config file to apply in the directory containing the file and its ancestor directories; additionally, it looks at the user config (~/.config/clangd/config.yaml).

So, if you're opening a file in ~/.cache/bazel/_bazel_<USERNAME>/f428e7e9652043d7b22f6d4c02d3b711/external/, then {workspaceFolder}/.clangd is not a config file it encounters during the search.

You could put a .clangd file into ~/.cache/bazel/_bazel_<USERNAME>/f428e7e9652043d7b22f6d4c02d3b711/external/ (or an ancestor, like ~/.cache/bazel), which would be used for these files.

Alternatively, you can put the flags into the user config. (Was there something that originally made this approach problematic for you?)

zeroxia commented 2 years ago

For this specific project, it is OK to put config at user level (.config/clangd/config.yaml). I just feel this loses some flexibility: if I have ProjectA and ProjectB, they depend on two different external libraries LibM and LibN, then I may have to put both LibM and LibN include paths in the user-level config.yaml.

Another example, I now have this interesting finding:

I removed the user level config, and put it to project root as .clangd file, then inside this project config, include path is changed from: ~/.cache/bazel/_bazel_<USERNAME>/f428e7e9652043d7b22f6d4c02d3b711/external/data_engine/include to it's sym-linked version inside the project: ${workspaceFolder}/<symbol_link>/external/data_engine/include

Suppose in this include directory, there are three headers: A, B, C.

Note A, B, C have relative paths, they are not bare filenames.

And there is my source X, it #includes A.

With this setup, in source X, I can "go to definition" on #include A, and it brings me to source A as its sym-linked path: <symbol_link>/external/data_engine/include/A

with this A open in my VS Code editor, #include B and #include C lines are OK (no red squiggled), and I can further "go to definition" with header B and C.

But B is opened as its real path under ~/.cache/... ....

So when in B's editor, it's dependent #include C is now marked by red squiggle, as under ~/.cache/... ..., there is no further config file.

My suggestion is, could clangd keep using the symlink path, or at least give this symlink path higher priority, if so, all A, B, C headers would be located correctly. While actually the observed situation is, A is opened using the symlink path, so A can find B and C because that symlink path is added in project-leve .clangd, but B and C are opened using the real path, the project .clangd is not used, so for B, C is not found.

HighCommander4 commented 2 years ago

My suggestion is, could clangd keep using the symlink path, or at least give this symlink path higher priority, if so, all A, B, C headers would be located correctly.

I think that would be nice to have (perhaps as an option). I believe #413 is about the same issue.

hinell commented 1 year ago

It would be nice to have --dump-config flag, just like one we have for clang-tidy:

$ clang-tidy --dump-config 
...
$ clangd --dump-config # Fails in `v12`

I think I've found examples of config here, in clangd/unittests/ConfigYAMLTests.cpp file, .e.g (an excerpt):

Diagnostics:
  ClangTidy:
    CheckOptions:
      IgnoreMacros: true
      example-check.ExampleOption: 0
  UnusedIncludes: Strict
ell1e commented 1 year ago

CompileFlags: Add: modifies the command from the CDB (compile_commands.json) entry used for a file. The entry (and thus the compile_commands.json file) still needs to exist.

Why does it behave like that? Couldn't it just assume an empty compile_commands.txt when there is no such file? Seems weird to me that the Add is just silently ignored, especially when clangd clearly is using some default compile command on its own even with no such file present - so why not just add the flags to that? That seems like a more intuitive thing to do.

HighCommander4 commented 1 year ago

CompileFlags: Add: modifies the command from the CDB (compile_commands.json) entry used for a file. The entry (and thus the compile_commands.json file) still needs to exist.

Why does it behave like that? Couldn't it just assume an empty compile_commands.txt when there is no such file? Seems weird to me that the Add is just silently ignored, especially when clangd clearly is using some default compile command on its own even with no such file present - so why not just add the flags to that? That seems like a more intuitive thing to do.

I think I was mistaken when I wrote that. Add: does seem to work even in the absence of a compile_commands.json, it adds the flag to the "fallback command" that clangd uses to process the file.

71GA commented 1 year ago

I agree, we should improve this.

It is 2023. Nothing improved...

jimmychoo91011 commented 10 months ago

Documentation on this is terrible lol there's no clear guide on how to actually configure this thing

abzrg commented 9 months ago

Is there a way to point to the root of the project with some variable like workspaceFolder. For -I flags I can't just specify a relative path. Could be nice for it to recognize the workspaceFolder as the place the file .clangd is located. This way there is no need to hardcode some ugly absolute path.

HighCommander4 commented 9 months ago

Is there a way to point to the root of the project with some variable like workspaceFolder. For -I flags I can't just specify a relative path. Could be nice for it to recognize the workspaceFolder as the place the file .clangd is located. This way there is no need to hardcode some ugly absolute path.

There is an issue on file for this (https://github.com/clangd/clangd/issues/1038) but it's not currently supported.

A workaround in the meantime could be to generate .clangd from a script which does the environment variable expansion (possibly called by the build system, or alternatively have the build system put the desired flags into compile_commands.json in the first place).

ShelpAm commented 8 months ago

Eager for the documentation!

jobinnthomas commented 8 months ago

Yea documentation on this would be better..Better if somebody posted a big complete config.yaml file here https://clangd.llvm.org/installation.html

For windows this works in config.yaml in %localappdata%/clangd folder CompileFlags: Add:

Brand-Frank commented 5 months ago

Remote index is a feature to consume the project's index from a remote machine instead of indexing locally; if you're not familiar with it it's safe to say you're not using it (and therefore you don't need to care about the "trusted" flag).

Anyways, from this comment it sounded like you tried using a .clangd config file in the project directory and something didn't work, but it's not clear to me what -- can you be more specific?

I think the configuration guidance for .clangd file is too rudimentary, and I don't even know if the configuration method below is correct. Because what I've seen from multiple issues is basically the way it works under Linux.

CompileFlags:
  Add: 
  - "--include-directory=D:/Development/MSYS2/ucrt64/include/c++/13.2.0/"
  - "--include-directory=D:/Development/MSYS2/ucrt64/include/c++/13.2.0/x86_64-w64-mingw32/bits/"

In the Windows system, I have various questions:

  1. How should the -I parameter be configured?
  2. What should be the form of adding multiple includes?
  3. What should be done with slashes in absolute paths, / or \ ? There are no useful examples listed in clangd configuration, so I have to spend a lot of time looking at various issues that may seem useful but cannot meet the requirements of my Windows system.
HighCommander4 commented 5 months ago

I agree that, in addition to better documentation in general, better documentation on Windows in particular (and more generally, a more polished experience on Windows) is very much a need the clangd project has.

One challenge here is that I believe the most of the main clangd contributors are not Windows users. For my part, I neither have access to a Windows machine, nor have much familiarity with Windows' peculiarities (Linux has been my daily driver for almost a decade, and for development-related tasks I've only ever used Linux).

For using clangd to be a better experience on Windows, we really need members of the Windows user community to step up and contribute to making that happen.

That said, I'll answer your questions the best I can.

1. How should the `-I` parameter be configured?
2. What should be the form of adding multiple includes?

First, since your example involves system include paths such as include/c++/13.2.0/: it should not be necessary to specify these manually at all. Clangd should be able to find these automatically using --query-driver, as discussed at https://clangd.llvm.org/troubleshooting#cant-find-standard-library-headers-map-stdioh-etc (last paragraph) and https://clangd.llvm.org/guides/system-headers#query-driver.

For project include paths, the best way to specify them is using compile_commands.json, set up in one of the ways discussed at https://clangd.llvm.org/installation#project-setup. This shifts the burden of getting the syntax of the compile flags right to the tool that generates the compile_commands.json file.

Specifying include paths using CompileFlags: Add:, where you have to worry about the syntax of the flags yourself, should really be a mechanism of last resort.

I believe the syntax in your example is correct. I believe using -I in place of --include-directory= (with no space separating the -I from the path) should also work.

I believe the syntax for specifying multiple flags in your example is also correct. An alternative syntax is to use square brackets (e.g. Add: [-Ifoo, -Ibar]).

That said, I'm not 100% confident either without trying it, and particularly may be overlooking Windows-specific considerations. If it's not working for you, please feel free to post clangd logs (preferably in a new issue) and we can help figure out what's going wrong.

3. What should be done with slashes in absolute paths, `/` or `\` ?

I believe either should work. However, please keep in mind that \ is an escape character in many contexts, and so often needs to be doubled as \\. (One more reason why compile_commands.json is preferable to writing down paths manually in .clangd.)

Brand-Frank commented 4 months ago

I agree that, in addition to better documentation in general, better documentation on Windows in particular (and more generally, a more polished experience on Windows) is very much a need the clangd project has.

One challenge here is that I believe the most of the main clangd contributors are not Windows users. For my part, I neither have access to a Windows machine, nor have much familiarity with Windows' peculiarities (Linux has been my daily driver for almost a decade, and for development-related tasks I've only ever used Linux).

For using clangd to be a better experience on Windows, we really need members of the Windows user community to step up and contribute to making that happen.

That said, I'll answer your questions the best I can.

1. How should the `-I` parameter be configured?
2. What should be the form of adding multiple includes?

First, since your example involves system include paths such as include/c++/13.2.0/: it should not be necessary to specify these manually at all. Clangd should be able to find these automatically using --query-driver, as discussed at https://clangd.llvm.org/troubleshooting#cant-find-standard-library-headers-map-stdioh-etc (last paragraph) and https://clangd.llvm.org/guides/system-headers#query-driver.

For project include paths, the best way to specify them is using compile_commands.json, set up in one of the ways discussed at https://clangd.llvm.org/installation#project-setup. This shifts the burden of getting the syntax of the compile flags right to the tool that generates the compile_commands.json file.

Specifying include paths using CompileFlags: Add:, where you have to worry about the syntax of the flags yourself, should really be a mechanism of last resort.

I believe the syntax in your example is correct. I believe using -I in place of --include-directory= (with no space separating the -I from the path) should also work.

I believe the syntax for specifying multiple flags in your example is also correct. An alternative syntax is to use square brackets (e.g. Add: [-Ifoo, -Ibar]).

That said, I'm not 100% confident either without trying it, and particularly may be overlooking Windows-specific considerations. If it's not working for you, please feel free to post clangd logs (preferably in a new issue) and we can help figure out what's going wrong.

3. What should be done with slashes in absolute paths, `/` or `\` ?

I believe either should work. However, please keep in mind that \ is an escape character in many contexts, and so often needs to be doubled as \\. (One more reason why compile_commands.json is preferable to writing down paths manually in .clangd.)

Thank you for your response to my question. It has now been resolved, and I have ultimately used the configuration of .clangd. I think this is a better solution for a certain project. The method to add a parameter(--query-driver) can also solve the problem, but modifications may need to be made on different projects, so it was not ultimately adopted.

popoaichuiniu commented 4 months ago

I agree, we should improve this.

Quick answers though:

  1. The Index block is a sibling to If, not nested in it. If applies to the whole config fragment. So if you want anything to not be conditional, you split the file into multiple fragments with a --- line.
  2. Logs are the stderr of the clangd process, different editors expose this in different ways, this is documented in the per-editor instructions on the setup page. clangd --check does exist and should do what you want, but isn't yet documented on the site. (It's new in clangd 12)
  3. No, there's no config option yet to disable diagnostics. It's on my list to get in before the 12 release cut.
  4. Yeah, there's probably too much describing the system and not enough examples, I'll try to add some soon.

Have you write more detail doc? and could you give me the code of that resolve these config?

noahmbright commented 3 months ago

Would it be possible to move this issue to the clang-www repo and start taking pull requests over there? https://github.com/llvm/clangd-www/blob/main/config.md

HighCommander4 commented 3 months ago

Would it be possible to move this issue to the clang-www repo and start taking pull requests over there? https://github.com/llvm/clangd-www/blob/main/config.md

I can't move an issue across organizations (this repo is in the "clangd" org and the clangd-www repo is in the "llvm" org), but PRs for documentation improvements in the clangd-www repo are of course welcome.

findurance commented 1 month ago

Also, for the initial part of Files-section, it would be useful to have a multi-fragment example. Everything is said eventually in the text, but it's really difficult to graps when you first read it.

Basically it took me quite a bit of time to realize that global config can indeed have multiple If: sections.... but they need to be separated as fragments with ---

Documentation in general should be written in a bit of a mindset that "would I be able to do this, if I did not know what I know already".

If:
    PathMatch: /home/myhome/projects/fooproject/.*
CompileFlags:
    Add:
        - -I/usr/include/x86_64-linux-gnu
        - -I./foobar/foo

---

If:
    PathMatch: /home/myhome/projects/barproject/.*
CompileFlags:
        Add:
            # More -I flags here

---

If:
    PathMatch: /home/myhome/projects/foobar/.*
CompileFlags:
    Add:
        # And here some other compiler flags