gRPC v1.50编译C++客户端出现core未定义引用链接错误
gRPC客户端链接错误排查与解决
我从源码用CMake构建了gRPC,之后用CMake构建基于gRPC的客户端时出现链接错误。我判断这不是源码问题,而是配置问题——更奇怪的是,报错里的未定义符号本该属于libgrpc++.a。
失败的编译命令
/usr/bin/c++ -Werror -g xxxx/my/client/CMakeFiles/my_client.dir/my_client.cc.o \ -o /tmp/my_client -W xxxx/my/proto/libmy_core.a /usr/local/lib/libgrpc++_reflection.a \ /usr/local/lib/libgrpc++.a /usr/local/lib/libprotobuf.a
错误日志
/usr/bin/ld: /usr/local/lib/libgrpc++.a(client_context.cc.o): in function `grpc::ClientContext::set_call(grpc_call*, std::shared_ptr<grpc::Channel> const&)': client_context.cc:(.text+0x213): undefined reference to `absl::lts_20220623::Mutex::Lock()' /usr/bin/ld: client_context.cc:(.text+0x2e0): undefined reference to `grpc_call_cancel' /usr/bin/ld: client_context.cc:(.text+0x2e8): undefined reference to `absl::lts_20220623::Mutex::Unlock()' /usr/bin/ld: client_context.cc:(.text+0x31a): undefined reference to `grpc_call_cancel_with_status' /usr/bin/ld: client_context.cc:(.text+0x382): undefined reference to `gpr_log' ... # 剩余日志因篇幅省略
问题分析与解决方法
从报错信息能看出,缺失的符号分三类:
- Abseil库符号:比如
absl::lts_20220623::Mutex::Lock(),gRPC依赖Abseil,你没把Abseil的库加入链接列表 - gRPC核心C库符号:比如
grpc_call_cancel,libgrpc++.a是C++封装层,底层依赖C核心库libgrpc.a,你漏了这个库 - gPR基础工具库符号:比如
gpr_log,这是gRPC的基础工具库,同样需要显式链接
推荐解决方式:用gRPC提供的CMake目标
gRPC源码构建后会导出标准的CMake目标,这些目标会自动处理所有依赖(包括Abseil、libgrpc、libgpr等),不用手动维护库列表。修改客户端的CMake配置:
# 先找到gRPC和Protobuf find_package(gRPC REQUIRED) find_package(Protobuf REQUIRED) # 生成可执行文件 add_executable(my_client my_client.cc) # 链接目标,顺序不重要,CMake会自动处理 target_link_libraries(my_client PRIVATE my_core # 对应你的libmy_core.a的CMake目标 gRPC::grpc++ gRPC::grpc++_reflection protobuf::libprotobuf )
手动指定库的补救方式(不推荐)
如果一定要手动写链接库,需要把所有依赖库都加上,且注意顺序(依赖库要放在被依赖库后面),完整的链接参数大概是:
/usr/bin/c++ -Werror -g xxxx/my/client/CMakeFiles/my_client.dir/my_client.cc.o \ -o /tmp/my_client xxxx/my/proto/libmy_core.a \ /usr/local/lib/libgrpc++_reflection.a /usr/local/lib/libgrpc++.a \ /usr/local/lib/libgrpc.a /usr/local/lib/libgpr.a \ # 这里加上所有Abseil的库文件,比如libabsl_*.a /usr/local/lib/libprotobuf.a
这种方式容易出错,gRPC版本更新后依赖可能变化,不建议长期使用。
额外检查点
确认构建gRPC时是否正确编译并安装了所有依赖:gRPC默认会从源码构建依赖的Abseil,要确保这些库都安装到了同一个路径(比如/usr/local/lib),避免链接时找不到。
内容的提问来源于stack exchange,提问作者jsofri
相关产品推荐
相关产品推荐

