使用vcpkg+CMake+protobuf构建C++项目遇链接错误求助
核心问题是使用vcpkg管理高版本protobuf时,生成的proto代码与系统库(如abseil)产生符号不匹配,导致链接错误。以下是整理后的项目信息及修复步骤:
项目文件
main.cpp
#include "message.pb.h" #include <iostream> // 原代码缺失该头文件,需补充 int main() { std::cout << "hello world" << std::endl; PersonMessage person_message; person_message.set_name("henry"); std::cout << person_message.name() << std::endl; std::cout << person_message.DebugString() << std::endl; return 0; }
message.proto
syntax = "proto3"; message PersonMessage { string name = 1; }
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(vcpkg-project-test CXX) find_package(Protobuf REQUIRED) set(CMAKE_CXX_STANDARD 23) set(PROTO_FILES message.proto) set(PROTO_GENERATE_DIR ${CMAKE_BINARY_DIR}/generated) file(MAKE_DIRECTORY ${PROTO_GENERATE_DIR}) protobuf_generate_cpp( PROTO_SRCS PROTO_HDRS ${PROTO_FILES} ) add_library( lib_proto STATIC ${PROTO_SRCS} ) target_include_directories( lib_proto PUBLIC ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries( lib_proto PUBLIC ${Protobuf_LIBRARIES} ) add_executable( a.out main.cpp ) target_link_libraries( a.out PRIVATE lib_proto ${Protobuf_LIBRARIES} )
vcpkg.json
{ "dependencies": [ "protobuf" ] }
构建命令(修正重复参数)
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake cmake --build build
编译器版本
g++ (Ubuntu 14.2.0-4ubuntu2) 14.2.0
翻译后的首条错误信息
/usr/bin/ld: liblib_proto.a(message.pb.cc.o): 警告:在只读段
.text._ZN4absl12lts_2025012712log_internal9NullGuardIPKcE5GuardES4_[_ZN4absl12lts_2025012712log_internal9NullGuardIPKcE5GuardES4_]'中针对_ZN4absl12lts_2025012712log_internal9kCharNullE'的重定位
/usr/bin/ld: vcpkg_installed/x64-linux/lib/libprotobuf.a(arena.cc.o): 在函数`google::protobuf::internal::(匿名命名空间)::AllocateBlock(google::protobuf::internal::AllocationPolicy const*, unsigned long, unsigned long)'中:
修复步骤
强制使用vcpkg的protoc工具
在find_package(Protobuf REQUIRED)后添加代码,确保proto生成工具来自vcpkg:set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})简化链接依赖传递
可执行文件无需重复链接${Protobuf_LIBRARIES},lib_proto已通过PUBLIC传递依赖,修改可执行文件的链接逻辑:target_link_libraries( a.out PRIVATE lib_proto )指定proto代码生成目录
修改protobuf_generate_cpp,将生成文件放到独立目录,避免与系统头文件冲突:protobuf_generate_cpp( PROTO_SRCS PROTO_HDRS OUT_DIR ${PROTO_GENERATE_DIR} ${PROTO_FILES} )同步更新
lib_proto的include目录:target_include_directories( lib_proto PUBLIC ${Protobuf_INCLUDE_DIRS} ${PROTO_GENERATE_DIR} )完全清理重建
删除旧构建目录,重新执行构建命令:rm -rf build cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake cmake --build build
内容的提问来源于stack exchange,提问作者user2138149

