grpc / grpc-web

gRPC for Web Clients
https://grpc.io
Apache License 2.0
8.45k stars 760 forks source link

Difficulty building under Alpine 3.19 #1424

Closed strophy closed 1 month ago

strophy commented 1 month ago

I'm trying to build the grpc-web protoc plugin under Alpine as a part of this project using the following Dockerfile:

FROM alpine:3.19 as grpc_web
RUN apk add --no-cache \
        build-base \
        curl \
        protobuf-dev
RUN mkdir -p /grpc-web
RUN curl -sSL https://api.github.com/repos/grpc/grpc-web/tarball/1.5.0 | tar xz --strip 1 -C /grpc-web
WORKDIR /grpc-web
RUN make -j$(nproc) install-plugin

This results in an enormous error from the Abseil dependency, starting out like this:

 > [grpc_web 6/6] RUN make -j$(nproc) install-plugin:                                                                                                                                                             
0.137 cd "/grpc-web"/javascript/net/grpc/web/generator && make install                                                                                                                                            
0.138 make[1]: Entering directory '/grpc-web/javascript/net/grpc/web/generator'                                                                                                                                   
0.139 g++ -std=c++11 -I/usr/local/include -pthread  -c -o grpc_generator.o grpc_generator.cc                                                                                                                      
0.196 In file included from /usr/include/absl/base/config.h:86,                                                                                                                                                   
0.196                  from /usr/include/absl/base/attributes.h:37,
0.196                  from /usr/include/absl/strings/string_view.h:39,
0.196                  from /usr/include/google/protobuf/compiler/code_generator.h:45,
0.196                  from grpc_generator.cc:19:
0.196 /usr/include/absl/base/policy_checks.h:79:2: error: #error "C++ versions less than C++14 are not supported."
0.196    79 | #error "C++ versions less than C++14 are not supported."
0.196       |  ^~~~~
0.500 /usr/include/absl/strings/string_view.h:52:26: error: 'string_view' in namespace 'std' does not name a type
0.500    52 | using string_view = std::string_view;
0.500       |                          ^~~~~~~~~~~
0.500 /usr/include/absl/strings/string_view.h:52:21: note: 'std::string_view' is only available from C++17 onwards
0.500    52 | using string_view = std::string_view;
0.500       |                     ^~~
... omitted 7300+ lines

Adding ARG CPPFLAGS=-std=c++17 resolves the Abseil errors but instead returns the following error:

 > [grpc_web 6/6] RUN make -j$(nproc) install-plugin:                                                                                                                                                             
0.132 cd "/grpc-web"/javascript/net/grpc/web/generator && make install                                                                                                                                            
0.133 make[1]: Entering directory '/grpc-web/javascript/net/grpc/web/generator'                                                                                                                                   
0.134 g++ -std=c++11 -std=c++17 -I/usr/local/include -pthread  -c -o grpc_generator.o grpc_generator.cc                                                                                                           
1.953 grpc_generator.cc: In function 'void grpc::web::{anonymous}::PrintProtoDtsMessage(google::protobuf::io::Printer*, const google::protobuf::Descriptor*, const google::protobuf::FileDescriptor*)':           
1.953 grpc_generator.cc:844:36: warning: 'bool google::protobuf::FieldDescriptor::has_optional_keyword() const' is deprecated: Syntax is deprecated in favor of editions, please use FieldDescriptor::has_presence instead. [-Wdeprecated-declarations]
1.953   844 |     if (field->has_optional_keyword() ||
1.953       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
1.953 In file included from /usr/include/google/protobuf/compiler/retention.h:34,
1.953                  from /usr/include/google/protobuf/compiler/code_generator.h:46,
1.953                  from grpc_generator.cc:19:
1.953 /usr/include/google/protobuf/descriptor.h:2737:13: note: declared here
1.953  2737 | inline bool FieldDescriptor::has_optional_keyword() const {
1.953       |             ^~~~~~~~~~~~~~~
1.953 grpc_generator.cc:849:86: warning: 'bool google::protobuf::FieldDescriptor::has_optional_keyword() const' is deprecated: Syntax is deprecated in favor of editions, please use FieldDescriptor::has_presence instead. [-Wdeprecated-declarations]
1.953   849 |     if (field->type() == FieldDescriptor::TYPE_MESSAGE || field->has_optional_keyword() ||
1.953       |                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
1.953 /usr/include/google/protobuf/descriptor.h:2737:13: note: declared here
1.953  2737 | inline bool FieldDescriptor::has_optional_keyword() const {
1.953       |             ^~~~~~~~~~~~~~~
1.954 grpc_generator.cc:872:29: warning: 'bool google::protobuf::OneofDescriptor::is_synthetic() const' is deprecated: Syntax is deprecated in favor of editions, please use real_oneof_decl_count for now instead of is_synthetic. [-Wdeprecated-declarations]
1.954   872 |     if (!oneof->is_synthetic()) {
1.954       |          ~~~~~~~~~~~~~~~~~~~^~
1.954 /usr/include/google/protobuf/descriptor.h:2784:13: note: declared here
1.954  2784 | inline bool OneofDescriptor::is_synthetic() const {
1.954       |             ^~~~~~~~~~~~~~~
1.954 grpc_generator.cc:907:88: warning: 'bool google::protobuf::FieldDescriptor::has_optional_keyword() const' is deprecated: Syntax is deprecated in favor of editions, please use FieldDescriptor::has_presence instead. [-Wdeprecated-declarations]
1.954   907 |     if ((field->type() != FieldDescriptor::TYPE_MESSAGE && !field->has_optional_keyword()) ||
1.954       |                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
1.954 /usr/include/google/protobuf/descriptor.h:2737:13: note: declared here
1.954  2737 | inline bool FieldDescriptor::has_optional_keyword() const {
1.954       |             ^~~~~~~~~~~~~~~
3.903 g++ grpc_generator.o -L/usr/local/lib -lprotoc -lprotobuf -lpthread -ldl -static -o protoc-gen-grpc-web
3.917 /usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lprotoc: No such file or directory
3.917 /usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lprotobuf: No such file or directory
3.981 collect2: error: ld returned 1 exit status
3.982 make[1]: Leaving directory '/grpc-web/javascript/net/grpc/web/generator'
3.982 make[1]: *** [Makefile:35: protoc-gen-grpc-web] Error 1
3.982 make: *** [Makefile:9: install-plugin] Error 2

I don't think these errors are related to musl libc, is there a problem in the protobuf-dev package, or what am I missing here?

strophy commented 1 month ago

I think I tracked the problem down to the Alpine protobuf-dev package not containing the *.a files required for the static linking used by grpc-web during its build process, they're probably trying to encourage dynamic linking. I ran into a lot of trouble trying to match up protobuf and abseil versions building my own dependencies for a while, but then found the easiest way is to build and install the dependencies linked in the third party submodules directory instead. Build is now working again using the following steps:

FROM alpine:${ALPINE_IMAGE_VERSION} as grpc_web
RUN apk add --no-cache \
        autoconf \ 
        automake \
        build-base \
        git \
        libtool
ARG GRPC_WEB_VERSION
RUN git clone --recurse-submodules --branch=$GRPC_WEB_VERSION https://github.com/grpc/grpc-web.git
WORKDIR /grpc-web/third_party/protobuf
RUN ./autogen.sh && \
    ./configure && \
    make -j$(nproc) && \
    make install
WORKDIR /grpc-web
RUN make -j$(nproc) install-plugin
RUN install -Ds /usr/local/bin/protoc-gen-grpc-web /out/usr/bin/protoc-gen-grpc-web