Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration Provider API #436

Open
A2va opened this issue Jan 9, 2023 · 13 comments
Open

Configuration Provider API #436

A2va opened this issue Jan 9, 2023 · 13 comments
Labels
enhancement New feature or request

Comments

@A2va
Copy link

A2va commented Jan 9, 2023

The cpptools extension provide an API to consume a custom configuration provider.
For example the cmake-tools extension take advantage of that to have C++ completion without compile_commands file.

Could be possible to implement the same thing in vscode-clangd ?

@A2va A2va added the enhancement New feature or request label Jan 9, 2023
@i-ky
Copy link

i-ky commented Jan 9, 2023

That API is specific to cpptools, so clangd extension will need its own API. It will also need to be supported by "configuration providers" including cmake-tools. Assuming that both cpptools and cmake-tools are now maintained by Microsoft, guess how likely it is to happen... VS Code docs don't even mention any alternative to cpptools.

@A2va
Copy link
Author

A2va commented Jan 9, 2023

Of course, I didn't expect clangd to have the same API, but to replicate the general idea.

I only created this issue to improve xmake-vscode, this extension already support cpptools and codelldb debugger, so I'm thinking to do the same for the C++ completion, with cpptools and clangd.

Some users only use VSCodium, and cpptools cannot be installed in this IDE, so a combo of clangd/code-lldb could work. This can help to reduce the minimal amount of configuration.

@HighCommander4
Copy link
Contributor

At the protocol level, clangd does support the client specifying compile commands via workspace/didChangeConfiguration messages (see https://clangd.llvm.org/extensions#compilation-commands for details), as an alternative to using compile_commands.json.

The part I'm less sure about is whether another vscode extension can just get its hands on the LanguageClient instance created by vscode-clangd and use it to send such messages, or if vscode-clangd would need to expose an API to allow other extensions to do this. In the latter case, I imagine we'd be open to adding an such an API.

@A2va
Copy link
Author

A2va commented Jan 10, 2023

I made some test/research and actually this not possible to access to variables inside the extension. However I find how to expose an API:

// clangd extension
const api = new API();

export async function activate(context: vscode.ExtensionContext) {
return api;
}

// other extension
const clangd = vscode.extensions.getExtension("llvm-vs-code-extensions.vscode-clangd");

if (clangd) {
    let extension = undefined;
    if (!clangd.isActive) {
        extension = await cpptools.activate();
    } else {
        extension = clangd.exports;
    }

    const api = extension;
}

It's based on cpptools activation and cpptools npm package

@HighCommander4
Copy link
Contributor

Thanks for checking.

Are you interested in writing a patch that implements the desired API?

@A2va
Copy link
Author

A2va commented Jan 11, 2023

Of course I can do it, but I have no idea when it will be ready.

@cameron-martin
Copy link

cameron-martin commented Oct 2, 2023

This would be useful for bazel integration. Currently we generate a large compile commands file for our whole repository, but requesting this information on demand for individual files would be nice for performance.

Generating the compile commands uses a separate command rather than as part of the build, so this has to be manually re-run when something that affects the compile commands changes. Possibly if the editor requested this it would be easier to keep up-to-date, although exactly when the editor re-requests this is presumably an open question.

@cameron-martin
Copy link

cameron-martin commented Jan 13, 2024

Another possible direction would be to use the build server protocol. If a BSP connection file exists and supports cpp, this extension could launch a BSP, get the target for the currently-open file, gather the compiler flags etc, and send this to clangd.

Or, clangd could support this natively: clangd/clangd#1903

@torshepherd
Copy link

@HighCommander4 another issue here I'm interested in tackling 😅

Context: at work we have a massive C++ bazel monorepo, which leads to two issues:

  1. You have to manually extract and merge compile_commands.json with a bespoke extractor
  2. As you merge more and more of the project, the json file grows extraordinarily large, leading to clangd having untenable RSS usage.

I suspect this is actually the indexer doing this, but regardless compile_commands.json is simply not a scalable approach to massive monorepos. We need to plug clangd directly into getting compile commands.

@torshepherd
Copy link

torshepherd commented Sep 12, 2024

The reason I bring this up now is that buck2 and rust-analyzer have created a good integration:

buck2-side

r-a-side

@lmerynda
Copy link

We're running big repos too in my organization, including bazel based setups. With some scripting and talks with architects we were able to narrow down a few rules as to how the project is structured, which allows us to build our own heuristic based configuration setup which we lunch on startup and it delivers 95% accuracy which works very well for most of our users. The rest can be tweaked with repo persistent project configuration, or included in build system to access

One thing which we concluded in our jorney is that generating a series of .clangd files on a "module" basis yields much better experience than working with compile_commands.json. It's better for new files, it's better for test files, it's much smaller so we don't need clangd to spend the first 5-8s just reading the file for the first time. We basically went from 300k lines compile_commands.json to 300 lines "repo level" .clangd and 30-50 lines "module level" .clangd which gets generated dynamically.

In any case, by not relying on bazel build to deliver compile_commands.json we managed to get down to 10s setup instead of 5 minutes, definitely worth it in scale.

Chopping down compile_commands.json to see what's common across areas is an interesting excercise of itself, it could be used for security audits and activities around making sure we include (or not) certain compiler flags across the project, and/or we put good defaults in common locations

@torshepherd
Copy link

Wow, thats a great insight! I'll 100% be trying this.

I do still think long term it would be nice to create these integrations within vscode, bazel, and/or clangd.

@HighCommander4
Copy link
Contributor

HighCommander4 commented Sep 12, 2024

Following up on this earlier comment:

At the protocol level, clangd does support the client specifying compile commands via workspace/didChangeConfiguration messages (see https://clangd.llvm.org/extensions#compilation-commands for details), as an alternative to using compile_commands.json.

The part I'm less sure about is whether another vscode extension can just get its hands on the LanguageClient instance created by vscode-clangd and use it to send such messages, or if vscode-clangd would need to expose an API to allow other extensions to do this. In the latter case, I imagine we'd be open to adding an such an API.

As of version 0.1.29, vscode-clangd now has an API that exposes the LanguageClient object to other plugins: https://github.com/clangd/vscode-clangd/tree/master/api.

So, I think everything is now in place for other vscode extensions (e.g. a bazel one) to provide compile commands to clangd as an alternative to using compile_commands.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants