`protoc-gen-grpc: program not found or is not executable`
kotx opened this issue ยท 16 comments
get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
message(STATUS "Found gRPC C++ plugin at ${grpc_cpp_plugin_location}")
...
protobuf_generate(TARGET maid_proto LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cpp PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}")
yields the output:
-- Found gRPC C++ plugin at /usr/bin/grpc_cpp_plugin
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/src/maid/bin
[ 12%] Running grpc protocol buffer compiler on remote.proto
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.
make[2]: *** [protos/CMakeFiles/maid_proto.dir/build.make:90: protos/remote.grpc.pb.h] Error 1
make[1]: *** [CMakeFiles/Makefile2:141: protos/CMakeFiles/maid_proto.dir/all] Error 2
make: *** [Makefile:149: all] Error 2
Why doesn't this build? grpc_cpp_plugin is available in PATH, since it's in /usr/bin.
This is from your own project, right? Have you tried running the unchanged example from this repo first?
I haven't come across error this myself, so not sure when/why it pops up. I do wonder though if the "not found" error message is actually correct or if the --grpc_out: protoc-gen-grpc: Plugin failed with status code 1.
part is the more important one. Looks like it did find and execute something if it got a status code back...
Try executing protoc
manually on your files and see if that works. Or check the generated makefile to see which commands are generated by cmake and would actually be run.
I tried running the example from this repo, only changing
find_package(protobuf REQUIRED)
to
include(FindProtobuf)
find_package(Protobuf REQUIRED)
at the top of proto/CMakeLists.txt- CMake couldn't find the system protobuf otherwise.
Manually running protoc
works fine.
I get the same error.
This might be an issue with the Dockerfile I am using to run the project:
FROM alpine:latest AS base
WORKDIR /maid
EXPOSE 80
FROM alpine:latest AS build
# Build deps
RUN apk --no-cache add cmake build-base \
grpc grpc-dev protobuf-dev c-ares-dev
WORKDIR /usr/src/app
COPY . /usr/src/app
# RUN mkdir bin
# This runs fine
# RUN protoc --proto_path=protos --grpc_out=bin/ --plugin=protoc-gen-grpc=/usr/bin/grpc_cpp_plugin protos/remote.proto
RUN cmake -B bin -S . \
&& cmake --build bin && cmake --install bin # fails here
...
The generated Makefile is here https://paste.mod.gg/fujiyazeli.makefile
It seems like the PLUGIN
argument isn't recognized?
Update: it runs cd /usr/src/maid/build/proto && /usr/bin/protoc --grpc_out /usr/src/maid/build/proto -I /usr/src/maid/proto /usr/src/maid/proto/remote.proto
, which does not include --plugin
. Including --plugin
manually works. I'm using protobuf 3.13, and the PLUGIN
argument was added in 3.12 here. Weird.
I resolved this with ln -s $(which grpc_cpp_plugin) /usr/bin/protoc-gen-grpc
. Dumb workaround, but it works for now.
I think this was caused by me using the system install of protobuf/grpc
You should not have to use include(FindProtobuf)
. It looks like protobuf was not properly installed and is missing its cmake files. In that case, you are probably using the outdated FindProtobuf.cmake
that is installed together with cmake, rather than the protobuf-config.cmake
that comes with protobuf.
Try installing protobuf yourself from source, via cmake, and see if that fixes it.
If you want to learn more about *-config.cmake
vs Find*.cmake
have a look at this article and its "Resources" section at the end: Installing a Config.cmake file
I have the same issue with original example but with grpc/protobuf from conan
include(${CMAKE_CURRENT_SOURCE_DIR}/../conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
find_package(Protobuf REQUIRED)
include(${CONAN_LIB_DIRS_GRPC}/cmake/grpc_cpp_plugin.cmake)
find_package(Threads)
#
# Protobuf/Grpc source files
#
set(PROTO_FILES
myproto/address.proto
myproto/addressbook.proto
)
#
# Add Library target with protobuf sources
#
add_library(myproto ${PROTO_FILES})
target_link_libraries(myproto
PUBLIC CONAN_PKG::grpc
PUBLIC CONAN_PKG::protobuf
)
target_include_directories(myproto PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
#
# Compile protobuf and grpc files in myproto target to cpp
#
#grpc_cpp_plugin_location
get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
message(STATUS "PLUGIN: " ${grpc_cpp_plugin_location})
protobuf_generate(TARGET myproto LANGUAGE cpp)
protobuf_generate(TARGET myproto LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}")
Cmake printed:
...
PLUGIN: /home/user/.conan/data/grpc/1.37.1/_/_/package/c6934006d4c320ee1a1fb24a7853e896b2448a0d/bin/grpc_cpp_plugin
Configuring done
But when try to build:
13:24:49: Running steps for project example-grpc...
13:24:49: Starting: "/home/user/Qt/Tools/CMake/bin/cmake" --build . --target all
[1/11 143.8/sec] Running grpc protocol buffer compiler on myproto/address.proto
FAILED: proto/myproto/address.grpc.pb.h proto/myproto/address.grpc.pb.cc proto/myproto/addressPLUGIN proto/myproto/addressprotoc-gen-grpc=/home/user/.conan/data/grpc/1.37.1/_/_/package/c6934006d4c320ee1a1fb24a7853e896b2448a0d/bin/grpc_cpp_plugin
cd /home/user/source/build-exmpl-cmake-grpc-Desktop_Static_Clang_11_C_x86_64bit_in_usr_bin-Debug/proto && /home/user/.conan/data/protobuf/3.15.5/_/_/package/82b72b71ebffd9953ea98f1c4a04285d3ab84af2/bin/protoc --grpc_out /home/user/source/build-exmpl-cmake-grpc-Desktop_Static_Clang_11_C_x86_64bit_in_usr_bin-Debug/proto -I /home/user/source/exmpl-cmake-grpc/proto /home/user/source/exmpl-cmake-grpc/proto/myproto/address.proto
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.
[2/11 267.4/sec] Running grpc protocol buffer compiler on myproto/addressbook.proto
FAILED: proto/myproto/addressbook.grpc.pb.h proto/myproto/addressbook.grpc.pb.cc proto/myproto/addressbookPLUGIN proto/myproto/addressbookprotoc-gen-grpc=/home/user/.conan/data/grpc/1.37.1/_/_/package/c6934006d4c320ee1a1fb24a7853e896b2448a0d/bin/grpc_cpp_plugin
cd /home/user/source/build-exmpl-cmake-grpc-Desktop_Static_Clang_11_C_x86_64bit_in_usr_bin-Debug/proto && /home/user/.conan/data/protobuf/3.15.5/_/_/package/82b72b71ebffd9953ea98f1c4a04285d3ab84af2/bin/protoc --grpc_out /home/user/source/build-exmpl-cmake-grpc-Desktop_Static_Clang_11_C_x86_64bit_in_usr_bin-Debug/proto -I /home/user/source/exmpl-cmake-grpc/proto /home/user/source/exmpl-cmake-grpc/proto/myproto/addressbook.proto
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.
ninja: build stopped: subcommand failed.
13:24:49: The process "/home/user/Qt/Tools/CMake/bin/cmake" exited with code 1.
Error while building/deploying project example-grpc (kit: Desktop Static Clang 11 (C++, x86 64bit in /usr/bin))
When executing step "CMake Build"
Do you have any ideas what i did wrong?
Thanks so much for this repository, it's extremely helpful!
Try installing protobuf yourself from source, via cmake, and see if that fixes it.
This issue is reproducible even when installing protobuf from source, e.g. with this Dockerfile:
FROM debian:bullseye-slim
RUN apt update && apt install -y build-essential autoconf libtool pkg-config git cmake libc-ares-dev libre2-dev libssl-dev zlib1g-dev curl
RUN mkdir -p /build/abseil-cpp && cd /build/abseil-cpp && \
curl -sSL https://github.com/abseil/abseil-cpp/archive/refs/tags/20210324.2.tar.gz | tar -xzf - --strip=1 && \
mkdir build && cd build && \
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=yes && \
make -j64 install && \
ldconfig
RUN mkdir -p /build/protobuf && cd /build/protobuf && \
curl -sSL https://github.com/google/protobuf/archive/v3.17.3.tar.gz | tar -xzf - --strip=1 && \
mkdir build && cd build && \
cmake ../cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=yes \
-Dprotobuf_BUILD_TESTS=OFF && \
make -j64 install && \
ldconfig
RUN mkdir -p /build/grpc && cd /build/grpc && \
curl -sSL https://github.com/grpc/grpc/archive/refs/tags/v1.39.0-pre1.tar.gz| tar -xzf - --strip=1 && \
mkdir build && cd build && \
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DgRPC_ABSL_PROVIDER=package \
-DgRPC_CARES_PROVIDER=package \
-DgRPC_PROTOBUF_PROVIDER=package \
-DgRPC_RE2_PROVIDER=package \
-DgRPC_SSL_PROVIDER=package \
-DgRPC_ZLIB_PROVIDER=package && \
make -j64 install && \
ldconfig
RUN cd / && \
git clone https://github.com/faaxm/exmpl-cmake-grpc.git && \
cd exmpl-cmake-grpc && \
mkdir build && cd build && \
cmake .. && \
make -j64
Strangely, when using a module provider build for gRPC instead, it's working. I'm not sure whether that's due to a slight difference in versions or something else. Here's a corresponding Dockerfile:
FROM debian:bullseye-slim
RUN apt update && apt install -y build-essential autoconf libtool pkg-config git cmake libc-ares-dev libre2-dev libssl-dev zlib1g-dev curl
RUN git clone --recurse-submodules -b v1.39.0-pre1 https://github.com/grpc/grpc && \
cd /grpc/third_party/abseil-cpp && \
cmake . && \
make -j64 install && \
cd /grpc && mkdir build && cd build && \
cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF .. && \
make -j64 install && \
ldconfig
RUN cd / && \
git clone https://github.com/faaxm/exmpl-cmake-grpc.git && \
cd exmpl-cmake-grpc && \
mkdir build && cd build && \
cmake .. && \
make -j64
The repro case can also be "fixed" by deleting /usr/share/cmake-3.18/Modules/FindProtobuf.cmake
before running cmake
for exmpl-cmake-grpc
.
It's like FindProtobuf.cmake
is used preferentially to protobuf-config.cmake
, despite their being no include(FindProtobuf)
in exmpl-cmake-grpc
's CMakeLists.txt
. Maybe the gRPC
dependency pulls this in?
Yes, you are right @lgruen, gRPC
can pull in the wrong FindProtobuf.cmake
as part of its gRPCConfig.cmake
.
Adding -DgRPC_PROTOBUF_PACKAGE_TYPE=CONFIG
when configuring/building gRPC
fixes the issue.
As to the why:
I had a look at https://github.com/grpc/grpc/blob/master/cmake/protobuf.cmake and there, when gRPC_PROTOBUF_PROVIDER
is package
, it uses gRPC_PROTOBUF_PACKAGE_TYPE
as additional flags to find_package
.
This would not be too bad if that only happened when installing gRPC
. But the issue is then created further down:
At https://github.com/grpc/grpc/blob/master/cmake/protobuf.cmake#L93 they store a recipe to find protobuf in the variable _gRPC_FIND_PROTOBUF
. This variable is then inserted into their gRPCConfig.cmake
here:
https://github.com/grpc/grpc/blob/master/cmake/gRPCConfig.cmake.in#L6
If it's ok with you, I'd take parts of your Dockerfile and turn it into a github workflow for this repo as an example build and to see if future grpc/protobuf/cmake releases break stuff.
Impressive debugging, @faaxm! -DgRPC_PROTOBUF_PACKAGE_TYPE=CONFIG
works perfectly, thanks very much for that tip!
If it's ok with you, I'd take parts of your Dockerfile and turn it into a github workflow for this repo as an example build and to see if future grpc/protobuf/cmake releases break stuff.
Of course, that would be great! You could even have a scheduled GitHub Action and clone the dependencies at HEAD
each time you run.
You have probably wrong (outdated) version of FindProtobuf.cmake file distributed with the version of CMake you use.
Just replace it with the latest one supporting PLUGIN param taken from here for instance. Your version of FindProtobuf.cmake has to have PLUGIN param name in this line.
Upgrading from cmake version 3.20 to 3.22.5 solved this problem for me
I resolved this with
ln -s $(which grpc_cpp_plugin) /usr/bin/protoc-gen-grpc
. Dumb workaround, but it works for now.I think this was caused by me using the system install of protobuf/grpc
These kinds of workarounds are fine for local testing but they don't work on CI/Docker images.
I resolved this with
ln -s $(which grpc_cpp_plugin) /usr/bin/protoc-gen-grpc
. Dumb workaround, but it works for now.I think this was caused by me using the system install of protobuf/grpc
i really f**king love you!