我遇到了一个令人难以置信的令人沮丧的链接器问题。我有两个动态.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)
然后编译顺利,我可以运行这个例子