I am trying to deploy a C++ GRPC server on docker. Unfortunately, the grpc examples use dynamically linked GRPC libraries. When copying the executables to docker (e.g. a small alpine based one) it responds "not found". The underlying problem is that the executable depends on dynamically linked GRPC libraries.
I updated the example Makefile of GRPC to [only change is adding -static]
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
CPPFLAGS += `pkg-config --cflags protobuf grpc`
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
PROTOS_PATH = ../../protos
vpath %.proto $(PROTOS_PATH)
all: system-check greeter_client greeter_server greeter_async_client greeter_async_client2 greeter_async_server
greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
$(CXX) $^ $(LDFLAGS) -o $# -static
However, this runs into
Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x43d): undefined reference to `deflateInit2_'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x44e): undefined reference to `deflate'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x4bb): undefined reference to `deflateEnd'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x5bc): undefined reference to `inflateInit2_'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x5cb): undefined reference to `inflate'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x63b): undefined reference to `inflateEnd'
How can I adjust this to get a working statically compiled GRPC client / server?
You are missing link compress library, using -lz to fix this bug.
Related
I am trying to install my C++ igraph library from https://github.com/igraph/igraph to visual studio code using the following method this is my makefile made according to this link.
CXX = g++
CXX_FLAGS = -std=c++17 -O3 -march=native -DNDEBUG
LIB = -Llib
INC = -Iinclude
.PHONY: all
all: a.out
a.out: main.cpp
$(CXX) $(CXX_FLAGS) $(INC) $(LIB) -ligraph -lm -lstdc++ -lgomp -lpthread -o $# main.cpp
.PHONY: clean
clean:
rm a.out
The compiler will always return something like:
g++ -std=c++17 -O3 -march=native -DNDEBUG -Iinclude -Llib -ligraph -lm -lstdc++ -lgomp -lpthread -o a.out main.cpp
/usr/bin/ld: /tmp/ccqJLfvi.o: in function `main':
main.cpp:(.text.startup+0x9): undefined reference to `igraph_rng_default'
/usr/bin/ld: main.cpp:(.text.startup+0x16): undefined reference to `igraph_rng_seed'
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: a.out] Error 1
If i only want to use data structures such as igraph_t graph* it will work, but if i try to call fucntion it will return error and will not generate a.out file. It would be incredablly good if someone would be able to explain why this happens cuz it really got on my nerve right now.
Please follow the instructions in the documentation to set up your package to link to igraph.
Instructions to install igraph: https://igraph.org/c/html/latest/igraph-Installation.html Note that you must both build and install the package. Make a note of the location you used to install it to (the value of CMAKE_INSTALL_PREFIX)
Instructions on compiling your first igraph program: https://igraph.org/c/html/latest/igraph-Tutorial.html Unless you are already comfortable with writing C programs and linking them to external libraries, I strongly recommend that you use CMake to set up your project, as described in the linked tutorial. CMake works the same way on all platforms (Windows/macOS/Linux) and will automatically figure out how to link your program to igraph correctly. When configuring your project, be sure to set CMAKE_PREFIX_PATH to the location where you installed igraph earlier.
There are a couple similar problems to this but they all seem to have answers that don't work.
I've installed opencv4 onto an image of Ubuntu and I know the opencv files are install correctly
$ pkg-config --cflags opencv
-I/usr/include/opencv
and have a proper .cp file
/usr/local/lib/pkgconfig$ ls
gpr.pc grpc++.pc grpc++_unsecure.pc protobuf-lite.pc
grpc.pc grpc_unsecure.pc opencv4.pc protobuf.pc
But even though it's all installed correctly it's giving me this error.
~/neuralink/neuralink-image-service-prompt/proto$ make g++ -std=c++11 `pkg-config --cflags opencv protobuf grpc` -L/usr/local/lib `pkg-config --libs opencv protobuf grpc++` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl foo.cpp -o foo
/tmp/ccnfoOEl.o: In function `main':
foo.cpp:(.text+0x48): undefined reference to `cv::imread(cv::String const&, int)'
/tmp/ccnfoOEl.o: In function `cv::String::String(char const*)':
foo.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x4d): undefined reference to `cv::String::allocate(unsigned long)'
/tmp/ccnfoOEl.o: In function `cv::String::~String()':
foo.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
/tmp/ccnfoOEl.o: In function `cv::String::operator=(cv::String const&)':
foo.cpp:(.text._ZN2cv6StringaSERKS0_[_ZN2cv6StringaSERKS0_]+0x28): undefined reference to `cv::String::deallocate()'
/tmp/ccnfoOEl.o: In function `cv::Mat::~Mat()':
foo.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
/tmp/ccnfoOEl.o: In function `cv::Mat::release()':
foo.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x4b): undefined reference to `cv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'foo' failed
make: *** [foo] Error 1
Some people have already tried answering similar questions (such as Undefined reference to cv::imread(cv::String const&, int) and linking opencv libraries with g++) however these don't help, as the user didn't add opencv to their makefile and I have.
Here is my make makefile
LDFLAGS = -L/usr/local/lib `pkg-config --libs opencv protobuf grpc++`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
CXX = g++
CPPFLAGS += `pkg-config --cflags opencv protobuf grpc`
CXXFLAGS += -std=c++11
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
all: foo
client: image.pb.o image.grpc.pb.o client.o
$(CXX) $^ $(LDFLAGS) -o $#
server: image.pb.o image.grpc.pb.o server.o
$(CXX) $^ $(LDFLAGS) -o $#
%.grpc.pb.cc: %.proto
protoc --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
%.pb.cc: %.proto
protoc --cpp_out=. $<
clean:
rm -f *.o *.pb.cc *.pb.h client server
And I wrote a simple program that still throws the error
#include <opencv2/opencv.hpp>
#include <stdio.h>
int main() {
cv::Mat frame = cv::imread("sylvania.png", cv::IMREAD_UNCHANGED);
printf("Image size is %i x %i\n", frame.rows, frame.cols);
}
Everything seems to compile fine but I keep getting this linker issue. I don't seem to get the issue when I compile it on another computer (my mac) for what it's worth. Also I have the gRPC and Protoc files because I need them for the project, I just didn't use those file as an example since they're quite long.
I agree with Micka, here is a Makefile of one of my projects:
CPPFLAGS=-g -Wall -I. -DDEBUG
LDFLAGS=-g
LDLIBS=-lopencv_core -lopencv_calib3d -lopencv_highgui -lopencv_imgproc -lopencv_stitching -lopencv_video
main: main.o AffineKalmanLP.o
g++ $(LDFLAGS) -o main main.o AffineKalmanLP.o $(LDLIBS)
main.o: main.cpp main.h
g++ $(CPPFLAGS) -c main.cpp
AffineKalmanLP.o: AffineKalmanLP.cpp AffineKalmanLP.h
g++ $(CPPFLAGS) -c AffineKalmanLP.cpp
clean:
rm main main.o AffineKalmanLP.o
You need to add it to LDLIBS.
If I remove that line, I get undefined reference for various things as well.
I am creating client-server application, using gRPC. So far I was not using TLS encryption. Now I want to enable it, and strangely I get this error. It seems, at least to me, that this is a linker error. What would be best ways to solve it?
CLion doesn't highlight anything, so I assumed everything was syntactically OK, but when compiling I got that error.
/usr/bin/ld: CMakeFiles/projectname.dir/main.cpp.o: in function `grpc::SslServerCredentials(grpc::SslServerCredentialsOptions const&)':
/home/username/projectname/third_party/grpc/include/grpcpp/security/server_credentials.h:60: undefined reference to `grpc_impl::SslServerCredentials(grpc::SslServerCredentialsOptions const&)'
collect2: error: ld returned 1 exit status
This is a makefile that I use to generate C++ code from gRPC specification:
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
CPPFLAGS += `pkg-config --cflags protobuf grpc`
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
PROTOS_PATH = ./
vpath %.proto $(PROTOS_PATH)
%.grpc.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
%.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
clean:
rm -f *.o *.pb.cc *.pb.h
Then problem was solved like this:
I had to chage grpc++_unsecure to grpc++ under target_link_libraries in CMakeLists.txt cmake build configuration file.
I had forgotten/not thought about this at first.
target_link_libraries(bita_server
pqxx
sodium
protobuf::libprotobuf
# grpc++_unsecure
grpc++
SQLiteCpp
sqlite3
pthread
dl
${_PROTOBUF_LIBPROTOBUF}
)
In CMakeLists.txt under grpc folder, there are many target_link_libraries. which one to edit in order to include the change.
I had to build ImageMagick from sources to get around a problem I was having. Having done that I can now compile my code with the new shared library, which incidentally is called libMagick++-6.Q8.so. This I can do without a problem.
What I need is to be able to easily move the binary to other machines without having to rely on the (custom built) shared library, but building my code against the libMagick++-6.Q8.a file leads to numerous undefined reference linker errors.
Here's the relevant lines from my Makefile:
CXX= g++
CFLAGS= -DRENDER_TO_TEX -DUSEMAGICK -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=8 -O2 -pthread
LIBS= -L/opt/vc/lib -L/usr/lib -lbcm_host -lEGL -lGLESv2 -lstdc++
LIBS+= /usr/lib/libjsoncpp.a /usr/lib/libboost_regex.a /usr/local/lib/libMagick++-6.Q8.a
INCS= -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -I/usr/local/include/ImageMagick-6
slideshow: slideshow.cpp $(OBJS)
$(CXX) $(CFLAGS) slideshow.cpp ${INCS} ${LIBS} ${OBJS} -o $#
When I use command "gcc .. ../../*.so", there are the following error messages:
/usr/bin/ld: /home/demonwnb/build/src/*.so: error: undefined reference to 'llvm::raw_ostream::operator<<(void const*)'
/usr/bin/ld: /home/demonwnb/build/src/*.so: error: undefined reference to 'clang::DeclarationName::printName(llvm::raw_ostream&) const'
I think that I do not link "llvm library" correctly, so how should I do?
You need to tell your compiler where to load the libraries from, which can be done using the llvm-config command.
You could set the following symbols in your makefile
CC = g++
LLVM_MODULES = core jit native
CPPFLAGS = `llvm-config --cppflags $(LLVM_MODULES)`
LDFLAGS = `llvm-config --ldflags $(LLVM_MODULES)`
LIBS = `llvm-config --libs $(LLVM_MODULES)`
all:
$(CC) *.o $(LDFLAGS) $(LIBS) -o MyOutput
main:
find -name '*.cpp' -print0 | xargs -0 $(CC) -c $(CPPFLAGS)
Did you try using g++ to do the link? Those are C++ libraries and gcc doesn't pass the C++ libraries to the linker.