从gRPC 1.51.1升级至1.56.1出现未定义引用问题求助
升级gRPC v1.56.1遇到的编译链接问题
长期使用gRPC v1.51.1无异常,近期升级至v1.56.1时遇到问题。环境为CentOS7,GCC v9.3.0p6,处于HPC集群中无法轻易变更。通过CMake生成protobuf输出文件并构建共享库,供主应用调用。
问题1:编译需要链接更多新增依赖库
升级到v1.56.1后,编译时需要链接更多v1.51.1版本不需要的库,推测是gRPC/protobuf源码重构导致的依赖变更?
问题2:未定义引用错误
出现链接错误:
undefined reference to `google::protobuf::internal::ThreadSafeArena::thread_cache_'
在libprotobuf.so中搜索到相似符号:
/projects/common/tools/grpc/v1.56.1/lib64/libprotobuf.so:00000000001d9a68 T google::protobuf::internal::ThreadSafeArena::thread_cache() /projects/common/tools/grpc/v1.56.1/lib64/libprotobuf.so:0000000000000000 d google::protobuf::internal::ThreadSafeArena::thread_cache()::thread_cache
已尝试的排查动作:
- 搜索相关问题无结果,回退到v1.51.1后问题消失
- 用相同GCC版本重新编译v1.56.1,问题仍存在
当前使用的链接库参数:
-LDFLAGS "-L$(GRPC_INSTALL_PATH)/lib -L$(GRPC_INSTALL_PATH)/lib64" -LDFLAGS "-lgrpc -lgrpc++ -lgpr -labsl_synchronization -lprotobuf -lgrpc++_reflection" -LDFLAGS "-labsl_log_internal_message -labsl_log_internal_check_op -labsl_cord -labsl_cordz_info -labsl_cordz_functions"
protobuf生成相关的CMakeLists.txt内容:
project(genesee_protobuf LANGUAGES CXX) cmake_minimum_required(VERSION 3.15) find_package(protobuf REQUIRED) find_package(gRPC CONFIG REQUIRED) find_package(Threads REQUIRED) set(PROTO_FILES ${CMAKE_CURRENT_LIST_DIR}/genesee_protobuf/discovery/discovery.proto ${CMAKE_CURRENT_LIST_DIR}/genesee_protobuf/backdoor_memory_interface/backdoor_memory_interface.proto ${CMAKE_CURRENT_LIST_DIR}/genesee_protobuf/trace/trace.proto ) set(PROTO_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(PROTO_IMPORT_DIR ${CMAKE_CURRENT_LIST_DIR}) add_library(genesee_protobuf ${PROTO_FILES}) target_link_libraries(genesee_protobuf PUBLIC protobuf::libprotobuf gRPC::grpc gRPC::grpc++) target_include_directories(genesee_protobuf PUBLIC "$<BUILD_INTERFACE:${PROTO_BINARY_DIR}>") # # Compile protobuf and grpc files in genesee_protobuf target to cpp # get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION) protobuf_generate( TARGET genesee_protobuf IMPORT_DIRS ${PROTO_IMPORT_DIR} PROTOC_OUT_DIR ${PROTO_BINARY_DIR} LANGUAGE cpp) protobuf_generate( TARGET genesee_protobuf LANGUAGE grpc IMPORT_DIRS ${PROTO_IMPORT_DIR} PROTOC_OUT_DIR ${PROTO_BINARY_DIR} GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}")
排查方向与解决建议
针对问题1:依赖库增多
gRPC从v1.51到v1.56的版本迭代中,确实存在对Abseil库依赖的深化,以及protobuf内部模块的拆分重构,导致需要链接更多Abseil相关子库,这属于版本升级后的正常依赖变更,只需确保所有需要的Abseil库都被正确链接即可。
针对问题2:未定义引用错误
符号差异分析:报错的
thread_cache_是静态成员变量,而libprotobuf.so中存在的是thread_cache()函数及函数内部的局部静态变量thread_cache。这种差异说明:- 编译生成的protobuf代码(从.proto文件生成的.pb.cc)使用的头文件版本,和链接时使用的libprotobuf.so版本不匹配
- 可能是本地环境中存在旧版本protobuf头文件,导致生成的代码引用了旧符号定义,而链接的是新版本库
具体排查动作:
- 检查CMake的
find_package(protobuf REQUIRED)是否正确指向gRPC v1.56.1配套的protobuf版本(gRPC自带protobuf,需避免系统或其他路径的旧版本protobuf被优先找到) - 验证生成的
.pb.h文件中ThreadSafeArena::thread_cache_的定义,确认是否和libprotobuf.so中的符号一致;如果头文件中仍是thread_cache_,说明头文件版本不对 - 清理CMake缓存,重新运行配置,确保所有依赖都指向gRPC v1.56.1的安装路径
- 调整链接顺序:将
-lprotobuf移到链接参数的最后(链接器按顺序解析符号,依赖库应放在使用它的代码之后),修改后的LDFLAGS示例:-LDFLAGS "-L$(GRPC_INSTALL_PATH)/lib -L$(GRPC_INSTALL_PATH)/lib64" -LDFLAGS "-lgrpc -lgrpc++ -lgpr -labsl_synchronization -lgrpc++_reflection" -LDFLAGS "-labsl_log_internal_message -labsl_log_internal_check_op -labsl_cord -labsl_cordz_info -labsl_cordz_functions -lprotobuf"
- 检查CMake的
内容的提问来源于stack exchange,提问作者Shareef
相关产品推荐
相关产品推荐

