即使使用正确的库排序,命令行中也缺少 DSO

Ale*_*lex 5 c++ linker cmake

我遇到了一个令人难以置信的令人沮丧的链接器问题。我有两个动态.so库,一个定义gpr_log(称为libgpr.so),另一个使用它(称为libgrpc++.so)。

我正在尝试像这样链接一个可执行文件:

/usr/bin/c++
my_obj_file.o
-o my_exec
-rdynamic
lib1.a
lib2.so
libgpr.so
libgrpc++.so
Run Code Online (Sandbox Code Playgroud)

输出:

/usr/bin/ld: libgrpc++.so: undefined reference to symbol `gpr_log`
libgpr.so: error adding symbols: DSO missing from command line
Run Code Online (Sandbox Code Playgroud)

这是您想要加入并告诉我libgpr.so需要在libgrpc.so. 自然我预料到了这一点并交换了两个参数的顺序,却遇到了同样的问题:

/usr/bin/c++
my_obj_file.o
-o my_exec
-rdynamic
lib1.a
lib2.so
libgrpc++.so
libgpr.so
Run Code Online (Sandbox Code Playgroud)

我已经按要求传入了动态库,为什么看不到那里定义的符号?此外,我正在使用 CMake 生成此编译命令,而此问题似乎只影响此目标。是什么赋予了?

小智 11

当我尝试在 3 分钟内测试基本版本的 grpc gRPC C++时,我遇到了同样的问题。我从一个新的 ubuntu 开始,所以我必须安装所有依赖项和库。它以与上面相同的输出结束。

我试图查看 log_gpr 是否在任何地方使用过,但在示例的源代码中找不到。然后我调查了安装的库:

cd /usr/local/lib
readelf -s libgrpc++.so | grep gpr_log
138: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gpr_log
Run Code Online (Sandbox Code Playgroud)

有对该函数的引用,但指针似乎未定义。libgrpc.so 的类似输出产生于:

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
Run Code Online (Sandbox Code Playgroud)

所以 gpr_log 是在 libgrpc 中定义的,而不是在 libgrpc++ 中定义的。现在是检查 Makefile 的时候了:

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

LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl
Run Code Online (Sandbox Code Playgroud)

为了使它工作,我在 Makefile 中将 libgrpc 添加到 LDFLAGS:

LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl -lgrpc
Run Code Online (Sandbox Code Playgroud)

然后编译顺利,我可以运行这个例子