Try auto-finding the directory with compile_commands.json for lsp-clangd
Running current version of lsp-clangd with a cmake based out-of-source builds, I set set(CMAKE_EXPORT_COMPILE_COMMANDS ON), which results in a compile_commands.json file in my build directory.
After that I need to copy or symlink it to project root every time I re-configure top-level CML (add a new file, new dependency etc) for clangd to pick up info about my includes and successfully resolve goto-def queries. Symlinking doesn't work when I use Docker for Desktop with a WSL volume mounted to Docker, so I have to manually copy it every time.
I noticed from clangd-10 --help that it takes the following flag to specify a directory for clangd to find compile_commands.json.
clangd compilation flags options:
--compile-commands-dir=<string> - Specify a path to look for compile_commands.json. If path is invalid, clangd will look in the current directory and parent paths of each source file
The heuristic used by clangd
If path is invalid, clangd will look in the current directory and parent paths of each source file
seems quite useless in out-of-source builds.
I wanted to suggest running a 1-level deep search for a compile_commands.json file from the project root and setting this flag with the directory name for this flag eg. "--compile-commands-dir=build/".
I don't know if lsp currently has hooks for lsp-server specific project initialisation routines, but I think it would help. Happy to take a crack at it, if it's possible with the current API and is in line with what you have in mind about easy to use default options.
Amazing work - i appreciate your efforts.
Perhaps https://github.com/rpav/cmake-build.el would help for your use case too, as it manages symlinking compile-commands.json
Thanks for your swift reply. cmake-build.el looks good, however, i actually build in a separate terminal, so care less about cmake integration and more about clangd finding compile_commands.json out of the box. lsp-mode has been brilliant at working OOTB so far and I thought this might be a worthy addition.
I was driving at adding "--compile-commands-dir=my_esoteric_build_dir/" to clangd arguments when you start clangd in a given workspace by running a quick search (could even use bash for it) for compile_commands.json instead of making users symlink or copy the file to project root every time it changes.
Additionally, symlinks don't seem to work between Docker for Desktop and WSL1, so I would like to avoid them.
I don't know if lsp currently has hooks for lsp-server specific project initialisation routines, but I think it would help. Happy to take a crack at it, if it's possible with the current API and is in line with what you have in mind about easy to use default options.
This is supported. The core framework supports passing a function which returns the program to start.
Thanks for your swift reply. cmake-build.el looks good, however, i actually build in a separate terminal, so care less about cmake integration and more about clangd finding compile_commands.json out of the box. lsp-mode has been brilliant at working OOTB so far and I thought this might be a worthy addition.
Supporting this makes sense to me. We should support disabling this feature and log that we have automatically found the compile_commands when automatic discovery works out.
Are you ok with me taking a crack at this?
From my looking around at the code, clangd currently doesn't use the :initialization-options property instead creating the whole command with the following snippet, where clangd args are set through a variable.
https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-clangd.el#L175-L193
What I don't quite understand is how to force the evaluation of my potential lsp-clangd--find-compile-commands-dir function before starting a connection.
aha, realising initialisation-options is unnecessary here, we can do everything in the lsp-clients--clangd-command
aha, realising initialisation-options is unnecessary here, we can do everything in the
lsp-clients--clangd-command
Yes. The tricky part is that workspace root is not available in the initial import of the project but we will change that.
I was experimenting with using lsp--suggest-project-root - is that bad?
you should use lsp-workspace-root but it will return nil before you have imported the project. But again, this will change.
how far in the future is this change? It sounds like I should wait until it lands and proceed after that?
how far in the future is this change? It sounds like I should wait until it lands and proceed after that?
I can't tell - I will be inactive for some time. You can implement your feature and it will be merged once lsp-workspace-root is fixed to work all the time.
hope you are ok in these interesting times.
I have mostly been testing my function in an already loaded project, so I would have not noticed this chronological dependency had you not mentioned it.
after clangd-11, we’ll also be looking for directories named build to find compile_commands.json from https://llvm.discourse.group/t/clangd-lsp-with-emacs-external-library/1593/4
I guess we could replicate this heuristic
Just found this by googling... did this ever happen?
Also interested in how this should be managed
Just found this by googling... did this ever happen?
I can confirm that if you call your cmake build directory build then clangd will look there for compile_commands.json.
@dabrahams However this will not work if you are using cmake-presets with various configurePresets, because now compile_commands.json is under e.g. build/debug. In that case you do have to use a symlink with:
ln -s build/debug/compile_commands.json .
Also make sure to restart lsp with M-x lsp-workspace-restart.