This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Pull installed gRPC and introduce clangd-remote-(server|client)
ClosedPublic

Authored by kbobyrev on Apr 9 2020, 5:28 AM.

Details

Summary

This patch allows using installed gRPC to build two simple tools which
currently provide the functionality of looking up the symbol by name.
remote-index-client is a simplified version of dexp which connects to
remote-index-server passes lookup requests.

I also significantly reduced the scope of this patch to prevent large changelist
and more bugs. The next steps would be:

  • Extending Protocol for deep copies of Symbol and inherit RemoteIndex from Index to unify the interfaces
  • Make remote-index-server more generic and merge the remote index client with dexp
  • Modify Clangd to allow using remote index instead of the local one for all global index requests

Diff Detail

Event Timeline

kbobyrev created this revision.Apr 9 2020, 5:28 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 9 2020, 5:28 AM
kbobyrev updated this revision to Diff 256263.Apr 9 2020, 5:54 AM

Rebase on top of the correct revision

kbobyrev updated this revision to Diff 256265.Apr 9 2020, 5:56 AM

Discard Dexp.cpp formatting

kbobyrev updated this revision to Diff 256267.Apr 9 2020, 5:57 AM

Rebase on top of the correct revision again

Naming throughout - sorry to be a pain. I think "shared index" is less precise than it could be. WDYT about "Remote index"?

clang-tools-extra/clangd/CMakeLists.txt
165

Can we give these slightly less weird names :-)

170

CLANGD_SHARED_INDEX unused?

clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
262 ↗(On Diff #256267)

(unrelated formatting changes to this file)

clang-tools-extra/clangd/index/shared/CMakeLists.txt
4 ↗(On Diff #256267)

generate a library wrapping those instead, for dependents to link against?

5 ↗(On Diff #256267)

used once, inline? (and grpc_hdrs)

8 ↗(On Diff #256267)

can we wrap this in a function?

13 ↗(On Diff #256267)

Needed? it doesn't import anything

clang-tools-extra/clangd/index/shared/SharedIndex.proto
1 ↗(On Diff #256267)

Please drop "Shared" from the various filenames, we're already in a directory called Shared.

nit: header has the wrong name

10 ↗(On Diff #256267)

missing package (namespace)

15 ↗(On Diff #256267)

nit: LookupRequest, no Proto suffix. (If we need namespacing, we should use a namespace)

17 ↗(On Diff #256267)

symbol_yaml.
This is the style the codegen expects, and fighting it yields ugly results.

llvm/cmake/modules/LLVMProcessSources.cmake
112 ↗(On Diff #256267)

we can't do this :-)

need to move each tool to its own directory instead, which is annoying.

sammccall added inline comments.Apr 9 2020, 3:47 PM
clang-tools-extra/clangd/CMakeLists.txt
157

We'll eventually want to move all this out of clangd I guess? Maybe add FIXMEs for that?

Oops, hit enter too soon.

Well done getting this to work, will patch it and try out locally.

clang-tools-extra/clangd/index/shared/SharedIndexServer.cpp
43 ↗(On Diff #256267)

For a prototype, I wouldn't bother doing anything fancy at all.
Either just do a fuzzyfind, or just do a lookup.

sammccall added inline comments.Apr 9 2020, 4:46 PM
clang-tools-extra/clangd/CMakeLists.txt
135

can you somewhere (shared/README.md?) write down how to get the build working on at least one platform?

e.g.

  1. install libgrpc++-dev libprotobuf-dev protobuf-compiler protobuf-compiler-grpc debian packages
  2. set -DGRPC_INSTALL_PATH=/usr/include (seems like at least in that case we shouldn't need to set it explicitly!)

But looking at the find_package line I have a sneaking suspicion that "installed" doesn't mean what I think it does. My grpc++ package didn't come with any cmake files. It has headers and static libraries though...

I was able to get this to build by:

  • installing the packages above
  • changing $GRPC_INSTALL_PATH/protoc to protoc
  • changing the dependency names to grpc++ and protobuf
  • changing the plugin line to --plugin=protoc-gen-grpc=/usr/bin/grpc_cpp_plugin (this needs detection)

This seems pretty reasonable (more so than requiring everyone to check out grpc and build from source), we're just missing the detection logic. Unless grpc provides a cmake recipe that discovers the system-installed (i.e. package manager) grpc, maybe we need to write this detection.

157

this should be controlled by a top-level LLVM_ENABLE_GRPC or LLVM_USE_GRPC or so flag (not sure what the convention is).
Using GRPC_INSTALL_PATH is tempting now but there are multiple ways to configure it so it won't scale.
And at least in some cases we should be able to autodetect it, so we'll need a dedicated enable flag.

157

GRPC_INSTALL_PATH should be set() instead of option().

clang-tools-extra/clangd/index/shared/CMakeLists.txt
21 ↗(On Diff #256267)

these targets should be called clangd-index-server etc, this is a global namespace

54 ↗(On Diff #256267)

why is the client depending on clangd?

clang-tools-extra/clangd/index/shared/SharedIndexServer.cpp
96 ↗(On Diff #256267)

you should include the header for this function. In the version of grpc I installed, it wasn't transitively included.

kbobyrev updated this revision to Diff 257240.Apr 14 2020, 2:27 AM
kbobyrev marked 19 inline comments as done.

Address a bunch of comments (still a couple left though).

kbobyrev planned changes to this revision.Apr 14 2020, 2:27 AM

Also

clang-tools-extra/clangd/CMakeLists.txt
165

Inlined everything except (newly) GRPC_CPP_PLUGIN.

170

Yep, this one was used within Dexp when I was trying to extend it in this patch, but I realized I would need to either hide a bunch of commands or support some of them which would require the full Index interface implementation, Symbol deep copy and passing it through gRPC, etc. I guess we'd need to use it at some point anyway since there will be at least _some_ path-specific code if we don't build with gRPC by default (not rational for keeping it in this patch, just a bit of context in case you're interested).

Good catch, will remove!

clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
262 ↗(On Diff #256267)

This one is super weird, I even reset the file for the revision I was basing arc diff on, but it didn't work for some reason :(

clang-tools-extra/clangd/index/shared/CMakeLists.txt
4 ↗(On Diff #256267)

Great idea, thanks!

5 ↗(On Diff #256267)

Why once? It's used at least 3 times at the moment - once in the generation command and in both targets. Maybe once I put all of it in the library that becomes twice? Let me see.

13 ↗(On Diff #256267)

I'm afraid it's needed, I tried to get by without it but protoc fails with an error:

File does not reside within any path specified using --proto_path (or -I).  You must specify a --proto_path which encompasses this file.  Note that the proto_path must be an
 exact prefix of the .proto file names -- protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think).
clang-tools-extra/clangd/index/shared/SharedIndex.proto
15 ↗(On Diff #256267)

Yep, thought this would be confusing :) We already have a bunch of *Request things but I didn't know package <...> would wrap it into the appropriate namespace. Thanks!

kbobyrev updated this revision to Diff 257270.Apr 14 2020, 3:51 AM
kbobyrev marked 6 inline comments as done.

Improve CMake infrastructure.

  • Move client and server into separate directories and enable LLVM's error logic
  • Address a bunch of comments regarding flags enabling gRPC & remote index build
  • Simplify protobuf generation script
clang-tools-extra/clangd/CMakeLists.txt
157

Do you mean moving gRPC library setup logic to llvm/CMakeLists.txt?

clang-tools-extra/clangd/index/shared/CMakeLists.txt
8 ↗(On Diff #256267)

Are you proposing making a function (e.g. generate_protos) that would emit required source files? I'd have to do some manual dependency management in this case, that's why I did add_custom_command which seems to be the idiomatic way of generating targets with the right dependencies and properties (being generated files).

Could you please explain the benefit of wrapping this into a function?

kbobyrev retitled this revision from [clangd] Pull installed gRPC and introduce shared-index-(server|client) to [clangd] Pull installed gRPC and introduce clangd-remote-(server|client).Apr 14 2020, 3:52 AM
kbobyrev edited the summary of this revision. (Show Details)
kbobyrev planned changes to this revision.Apr 14 2020, 3:55 AM

Still need to do:

  • Add documentation for enabling gRPC
  • Simplify clangd-index-(server|client) as proposed
  • Find out why lookup is working differently than in Dexp (debug a little bit, I'm pretty sure there is some minor bug)
sammccall added inline comments.Apr 14 2020, 6:50 AM
clang-tools-extra/clangd/index/remote/CMakeLists.txt
20

sorry, what I meant by "less weird names" was can we call these libraries grpc++ instead of gRPC::grpc++ and protobuf instead of protobuf::libprotobuf?
Those thare the names that the libraries are installed as on my system at least...

kbobyrev updated this revision to Diff 257334.Apr 14 2020, 7:54 AM
kbobyrev marked 3 inline comments as done.

Improve CMake machinery and cleanup code

kbobyrev updated this revision to Diff 257341.Apr 14 2020, 8:05 AM
kbobyrev marked 2 inline comments as done.

Give gRPC and Protobuf libraries better names in CMake.

clang-tools-extra/clangd/index/remote/CMakeLists.txt
20

I'm afraid those are going to be called differently depending on how they are imported. I've changed it to PROTOBUF_LIBRARY and GRPC_LIBRARY, is that OK?

kbobyrev updated this revision to Diff 257353.Apr 14 2020, 8:31 AM

Alias libraries in CMake: gRPC::grpc++ to grpc++ and protobuf::libprotobuf to protobuf.

kbobyrev marked an inline comment as done.Apr 14 2020, 8:32 AM
sammccall added inline comments.Apr 14 2020, 9:15 AM
clang-tools-extra/clangd/CMakeLists.txt
158

Having thought about this more - I think this flag should (at least for now) be called something like CLANGD_ENABLE_REMOTE and documented as requiring grpc.

159

I think this code should be moved to llvm/cmake/modules/FindGRPC.cmake and included here via include(FindGRPC)

159

can we add a comment to the top of this section describing the setup that it expects? (GRPC built from source and installed into ${GRPC_INSTALL_PATH})

165

Comment: "grpc cmakelists gives the libraries slightly odd names, make them match the conventional system-installed names"

171

Add primary function comment before the note.

this comment is a bit confusing:

  • it says callers of the function, when it means users of the proto
  • it says source directory, I think it means binary directory
  • it doesn't say why

I'd suggest:

Proto headers are generated in ${CMAKE_CURRENT_BINARY_DIR}.
Libraries that use these headers should adjust the include path.
179

this should be optional, with a parameter to generate_protos (along with the plugin and grpc_out args) - AIUI it's required for protos that define services only.

Conventional name for this param is HasServices

183

I believe this should be Protobuf_DIR or so (find_package output) to avoid getting confused if find_package found it somewhere else

192

nit: grpc++ protobuf

195

these global side-effects are pretty scary, can we limit them somehow?

clang-tools-extra/clangd/index/remote/Index.proto
12

package clang.clangd.remote, to get namespaces compatible with the c++ code

clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
13

protobuf and grpc++?

llvm/CMakeLists.txt
1112 ↗(On Diff #257341)

Sorry my thought before was incomplete - this should probably be CLANGD_USE_GRPC for now with a fixme to move up to LLVM. Especially since all the cmake code for this is in clangd for now.

1114 ↗(On Diff #257341)

This doesn't make sense - it's not a universally-usable directory, and there's almost no chance that the cmake files are in /usr/lib/cmake/... since the packages we've found don't include them.

I'd suggest for now we always require this to be set if using an installed-grpc-with-cmakelists setup, and work out how to relax later.

kbobyrev updated this revision to Diff 257658.Apr 15 2020, 3:45 AM
kbobyrev marked 14 inline comments as done.

Address the current round of comments.

kbobyrev marked an inline comment as done.Apr 15 2020, 3:45 AM
kbobyrev added inline comments.
clang-tools-extra/clangd/CMakeLists.txt
195

I'll be using target_compile_definitions() manually then. Not sure if it's much better (since users would have to manually add those defines), maybe if there are more protos in the future it'd be better to add function for setting up the target which will be linked against generated protobufs.

kbobyrev updated this revision to Diff 257659.Apr 15 2020, 3:47 AM

Trim dexp output in remote index README.

kbobyrev updated this revision to Diff 257664.Apr 15 2020, 3:56 AM

Fix protobuf & grpc_cpp_plugin settings in system-installed libs scenario and
confirm that everything works as expected with -DLLVM_OPTIMIZED_TABLEGEN=On.

Thanks, this look really close now. A few things still in the wrong place, and naming/wording nits.

clang-tools-extra/clangd/CMakeLists.txt
157

This comment belongs in the relevant section of FindGRPC, not here

163

revert this move?

clang-tools-extra/clangd/index/remote/CMakeLists.txt
8

inline these into the client/server CMakeLists?

clang-tools-extra/clangd/index/remote/Index.proto
15

nit: Lookup, without the request prefix
UpperCamelCase is conventional for protobuf functions, the user-defined names will be alongside names in the generated code that follow that convention.

20

symbol_yaml, lowercase

(this is how all the generated code looks and conventional for protobufs)

clang-tools-extra/clangd/index/remote/README.md
4

This first sentence doesn't parse (missing a verb and some commas) but should really be split. It should probably avoid so many parentheses too. Maybe:

Clangd uses a global index for project-wide code completion, navigation and other features.
For large projects, building this can take many hours and keeping it loaded uses a lot of memory.

(I don't think the last sentence is needed, it's implied)

6

("overhead" implies it's not used directly for the task at hand, so it's not really accurate here)

8

Vague references to "the best experience" sound like bad marketing, we should be more specific (or just use fewer words)

11

and shared between developers

19

However you install the dependencies, ...

(or at least "way" -> "method")

55

drop dead sentence?

63

I wouldn't lead with the same-machine limitation, the headline is this doesn't work at all with clangd yet.

I also don't think it's worth going into detail about the proof-of-concept: they aren't really interesting to anyone else and will be replaced soon.

Maybe just: the remote index isn't usable with clangd yet, but you can try the proof-of-concept tools in client/ and server/ subdirectories.

clang-tools-extra/clangd/index/remote/client/CMakeLists.txt
8

why does this link to clangdbasic?

I forget how cmake transitive deps work, but surely it either needs clangDaemon only, or clangDaemon and all of its deps?

llvm/CMakeLists.txt
378 ↗(On Diff #257664)

this code all belongs in clangd cmakelists

llvm/cmake/modules/FindGRPC.cmake
27

optional generation of protos only seems backwards - optional generation of grpc code?

29

lib name is probably the conventional first arg?
also works better if we're going to allow multiple input files in future

47

what's the effect of adding the headers to the library?

kbobyrev updated this revision to Diff 257893.Apr 15 2020, 4:41 PM
kbobyrev marked 18 inline comments as done.

Address a bunch of comments.

sammccall accepted this revision.Apr 16 2020, 1:22 AM

Awesome, ship it!

This revision is now accepted and ready to land.Apr 16 2020, 1:22 AM
kbobyrev edited the summary of this revision. (Show Details)Apr 16 2020, 2:07 AM
This revision was automatically updated to reflect the committed changes.