Search code examples
grpcgrpc-c++

gRPC for C++ on Ubuntu - protoc-gen-grpc error


I'm trying to use gRPC for a project and keep running into the following trouble: when generating grpc headers, the manual I can see instructs to execute

/usr/src/grpc/cmake/build/third_party/protobuf/protoc --proto_path=. --grpc_out=../.build/protocol \
 --plugin=protoc_gen_grpc=/usr/src/grpc/cmake/build/grpc_cpp_plugin ./Test.proto

All referenced files and folders exist, grpc_cpp_plugin is built with cmake from gRPC sources (along with the protobuf executable), lies in the provided directory and has -x- permissions. However, running the command results in

protoc-gen-grpc: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
--grpc_out: protoc-gen-grpc: Plugin failed with status code 1.

error. This problem is observed in both Ubuntu and MinGW under Windows. The version for Windows (obtained via vcpkg) does execute the similar command successfully. The command

/usr/src/grpc/cmake/build/third_party/protobuf/protoc --proto_path=. --cpp_out=../.build/protocol ./Test.proto

executes without any problems.

Ideas about what I'm doing wrong and/or how I can obtain more detailed diagnostic and/or how I can build gRPC C++ files with some other command would be appreciated.


Solution

  • As Abel pointed out in the comments, my issue was simply a matter of attention (I wrote protoc_gen_grpc instead of protoc-gen-grpc). Still, since I went through a number of questions and articles before successfully building and using gRPC for C++, might as well summarize it here for people dealing with the same issues. (Notice the date of the post, it may become outdated in the future.)

    Documentation

    There are several instructions saying roughly the same things with minor differences. For example, Quick start recommends using CMake, but the github BUILDING.md it links says Bazel is preferable. In addition there is a separate github instruction for C++ that has platforms support table and advice for using CMake.

    gRPC for Windows (MSVC)

    • Quick start does not cover Windows at all. The best practical option at the time seems to be using vcpkg - when installing gRPC it will also pick up all dependencies (like zlib and Abseil) and should compile all that without trouble.

    • If, for whatever reason, you decide to go the long way described in BUILDING.md, some potentially useful things about building with CMake:

      • Install CMake GUI and use "Configure". It will clearly show all meaningful flags and configuration-time warnings.
      • Do not "Open Project" from GUI, though. For whatever reason Visual Studio by default outputs files into wrong folders. Use knowledge from GUI to write the correct console command.
      • The build sequence is Abseil - protobuf - gRPC. You can ignore Google tests as Abseil dependency but it's important that Abseil is build corresponding to its CMakeLists.txt otherwise protobuf build will fail.
    • Either way, you should have protoc.exe (from protobuf) and grpc_cpp_plugin.exe (in tools\grpc or INSTALL_BIN_DIR of gRPC build). With that, you can compile .proto file(s), like so:

       %PROTO_COMPILER% --proto_path=. --grpc_out=..\build\protocol --plugin=protoc-gen-grpc=%PROTO_GRPC_PLUGIN% .\MyFile.proto
       %PROTO_COMPILER% --proto_path=. --cpp_out=..\build\protocol .\MyFile.proto
      
    • This assumes %PROTO_GRPC_PLUGIN% is an absolute path to the grpc_cpp_plugin.exe and does not contain spaces or non-ASCII characters. Add quotes in case of the former and either rename directories or use subst for the latter. %PROTO_COMPILER%, similarly, is a path to the protoc.exe.

    • One somewhat confusing thing here is that if the compiler can't find the plugin file for any reason, it will produce a misleading diagnostic protoc-gen-grpc: program not found or is not executable. There is no file named protoc-gen-rpc in this toolchain.

    • To compile the project using this protocol you'll need to do the following (CMake may be capable of doing this neatly by instructions like find_package but in case of any problems you should be able to do this by hand):

      • add \include folders of Abseil, protobuf and gRPC to your project includes paths;
      • add \lib or \debug\lib folders (depending on your build type, MSVC will produce linker errors if you try to link the wrong version, at least for gRPC) of Abseil, protobuf, gRPC, UPB, C-Ares, Re2, zlib and OpenSSL to your linker paths (you need only abseil_dll.lib from Abseil and only a subset of gRPC libs);
      • copy abseil_dll.dll, cares.dll, libprotobuf.dll and zlib1.dll (or their debug versions, depending on your build type) to your executable folder or make them otherwise available.

    gRPC for Linux (g++)

    • This works much easier, simply following instructions from BUILDING.md compiles everything (requires creating hardlinks, don't try to build on a network drive or in a shared folder).
    • protoc executable should be in cmake/build/third_party/protobuf/ subfolder of gRPC, C++ plugin in cmake/build/. .proto compilation commands are similar (see the post for an example).