But in VSCode, the build system is just another plugin that may or may not be installed, so a decoupled design seems most likely to work in many configurations.
If we could find a solution, it would of course be completely optional. Clangd would use its normal discovery mechanism of compile_commands.json, unless another plugin tells it to use a specific file or build dir. Maybe the build system extension could even give Clangd separate info for each C++ file if we want to be really flexible, but again, I don’t know exactly how that info would be sent to Clangd. I agree that it’s not reasonable that this info would be shared between different projects.
Something like this would be ideal:
User opens a folder
A compile_commands.json is generated
CMake Tools somehow tells Clangd where to find the file (this one is where the problem lies)
Repeat steps 2-4 whenever CMake needs to generate again
Clangd needs to be able to determine the compile command given a filename, at any time, within the clangd process (i.e. without exchanging LSP messages with the editor).
I’ll admit that this sounds rather tricky. But the build plugin would only need to notify Clangd when it actually generates its compile_commands.json, after which Clangd could keep and reuse that state.
It is in fact possible as a command flag (it’s spelled -compile-commands-dir).
Would this only be passed once when the process starts and then never touched again? If so, then yeah this obviously doesn’t work.
each tool (clangd, clang-tidy etc) needs to get this configuration in some appropriate way, it’s not shared (whereas all clang-based tools share discovery logic for compile_commands.json)
Yeah, this does sound like a scalability issue if a user wants to use multiple Clang tools, as the build system extension would have to communicate with every one of them.
Maybe one idea is to stick to compile_commands.json but extend the way they are discovered, e.g. let the Cmake Tools plugin notify Clangd that a certain compile_commands file is relevant and should be considered, even if it’s not in an ancestor dir of the source file.
This sounds like a fairly reasonable compromise. But then again, we would still need a way for the build system extension to communicate this to Clangd.
Given the following circumstances:
- There is always only one Clangd instance which is shared between different projects/folders
- Command line arguments can only be passed to Clangd when launching it
- Command line arguments passed to Clangd will affect all different projects/folders
- The only ways for VSCode to communicate with Clangd after launching it is via LSP or files that both VSCode and Clangd already know about
- LSP can not be used for this purpose
then this problem might not actually be possible to solve. If all of this would mean completely redesigning the way that Clangd is invoked, then yeah maybe generating a symlink is the only way to go about this. I’m still not fond of polluting the source tree with something that is not super obvious that it was generated by an IDE/editor or what generated it, but maybe this is just an inherent downside of using LSP rather than an integrated C++ library (not trying to discredit your work, it’s still a great project!)…
Then the question is how the build system extension would decide where to put the symlink. Would it always end up in the root folder? Or something like CMAKE_SOURCE_DIR (these two are often the same, but I guess it’s a good idea to be specific)? What did you mean by symlinking src/.build to build/? Sorry, I never really use symlinks so I’m not very familiar with them. It seems like CMake tool actually has a config option to place a copy (not a symlink) of compile_commands.json in a path specified by the user in the config. Though I think this has to be done automatically without the user having to go into the config and set it up, maybe after clicking a “yes” button that pops up in VSCode or something. Otherwise most users will probably just assume that the two plugins simply don’t work well together (like I did). Could even have a notification to warn the user to include the file in their VCS ignore file. Of course, this is in the hands of CMake Tools and other build system extensions, just thought it was relevant to the discussion.
It’s… not trivial. (Other clang tools don’t handle this as they tend to be batch)
So we’ll fix it, but it might take a little time
I’m not too worried about time, just good to hear that someone is working on it.