Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DSO missing from commandline even with proper library ordering

Tags:

c++

linker

cmake

I'm encountering an incredibly frustrating linker issue. I'm got two dynamic .so libraries, one which defines gpr_log (called libgpr.so) and another which uses it (called libgrpc++.so).

I'm attempting to link an executable like so:

/usr/bin/c++
my_obj_file.o
-o my_exec
-rdynamic
lib1.a
lib2.so
libgpr.so
libgrpc++.so

Outputs:

/usr/bin/ld: libgrpc++.so: undefined reference to symbol `gpr_log`
libgpr.so: error adding symbols: DSO missing from command line

Here's the part where you want to jump in and tell me that libgpr.so needs to be provided after libgrpc.so. Naturally I anticipated this and swapped the order of the two parameters, only to encounter the same issue:

/usr/bin/c++
my_obj_file.o
-o my_exec
-rdynamic
lib1.a
lib2.so
libgrpc++.so
libgpr.so

I've passing in the dynamic library as required, why is it not seeing the symbols defined there? Also, I'm generating this compilation command using CMake, and this issue only seems to affect this one target. What gives?

like image 497
alexgolec Avatar asked Oct 02 '15 03:10

alexgolec


1 Answers

I experienced the same problem when I tried to to test basic version of grpc gRPC in 3 minutes C++. I started on a fresh ubuntu, so I had to install all dependencies and libraries. It ended up in the same output as above.

I tried to see whether log_gpr was used anywhere and could not find that in source code of the example. Then i investigated libraries installed:

cd /usr/local/lib
readelf -s libgrpc++.so | grep gpr_log
138: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gpr_log

There was a reference to the function, but pointer seemed to be undefined. Similar output from libgrpc.so yield in:

readelf -s libgrpc.so | grep gpr_log
394: 0000000000081810    88 FUNC    GLOBAL DEFAULT   11 gpr_log_severity_string
823: 00000000000818c0   153 FUNC    GLOBAL DEFAULT   11 gpr_log_verbosity_init
956: 0000000000081970   199 FUNC    GLOBAL DEFAULT   11 gpr_log
1065: 0000000000081870    51 FUNC    GLOBAL DEFAULT   11 gpr_log_messagee here

So gpr_log was defined in libgrpc rather than in libgrpc++. Now it was time to check the Makefile:

.../grpc/examples/cpp/helloworld/Makefile

LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl

To make it work I added libgrpc to LDFLAGS in Makefile:

LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl -lgrpc

Then compiling went fine and I could run the example

like image 55
Stanislav Simic Avatar answered Oct 19 '22 22:10

Stanislav Simic