本文介绍如何在 Windows 平台下的 CMake 工程中正确配置和使用 Protobuf 库,解决链接错误问题。
本文在以下环境中使用 静态 链接库测试通过:
环境配置
- Windows 10
- Visual Studio 2026
- CMake 4.1.1-msvc1
- Ninja 1.12.1
- Clang 21.1.5
- Protobuf 33.2
注:以上的 CMake 版本是 Visual Studio 2026自带的版本。在环境变量添加以下配置即可:<VisualStudio 2026 安装目录>/Common7/IDE/Com #C++ #
CMakemonExtensions/Microsoft/CMake/CMake/bin 。
操作步骤
一、初始化Protobuf配置
本文使用源码编译配置 Protobuf 库。
- 下载Protobuf源码 Protobuf 33.2 选择下载 protobuf-33.2.zip 。
- 解压 protobuf-33.2.zip 。
- 在解压后的 protobuf-33.2 目录下,创建 build.bat 写入以下内容,然后执行这个脚本。
@echo off
cmake ./ ^
-B build ^
-G "Ninja" ^
-D CMAKE_C_COMPILER=clang ^
-D CMAKE_CXX_COMPILER=clang++ ^
-D protobuf_BUILD_TESTS=OFF ^
-D CMAKE_BUILD_TYPE=Release ^
-D CMAKE_INSTALL_PREFIX=./install ^
-D CMAKE_CXX_STANDARD=17 ^
-D CMAKE_CXX_STANDARD_REQUIRED=ON
cmake --build build --config Release
cmake --install build
- 编译完成之后,会在 protobuf-33.2/install 目录下,会生成 bin 、 include 、 lib 三个目录。里面包括 Protobuf的头文件 、 库文件 和 protoc 编译工具等。
- 将 protobuf-33.2/install/bin 目录添加到环境变量中,即可全局使用 protoc 编译工具。
C 二、在CMake工程中使用Protobuf库
- 注意设置工程 CMAKE_BUILD_TYPE 为 Release , 保持和Protobuf库的编译类型一致。
- 在CMakeLists.txt 头部添加 cmake_policy(SET CMP0091 NEW) 来设置新的CMake策略。
# 在 project() 之前添加;主要是为了能成功设置 CMAKE_MSVC_RUNTIME_LIBRARY
cmake_policy(SET CMP0091 NEW)
# 在 project() 之后设置 CMAKE_MSVC_RUNTIME_LIBRARY 解决 RuntimeLibrary 链接错误
if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") else() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") endif()
# 设置 C++ 标准为 C++17 由于 Protobuf 依赖 Absl 库,而 Absl 库要求 C++17 标准
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 添加 protobuf 相关配置
# 设置 Protobuf 库的搜索路径 请替换为你自己的完整安装路径
set(CMAKE_PREFIX_PATH "D:/protobuf-33.2/install")
# 查找Protobuf及Protobuf所依赖的包
find_package(Protobuf REQUIRED)
# 以下两个都是Protobuf所依赖的库
find_package(Absl REQUIRED) find_package(utf8_range REQUIRED)
# 链接utf8_range库 解决Protobuf链接错误
target_link_libraries(${PROJECT_NAME} utf8_range::utf8_range)
# 链接Absl库 解决Protobuf链接错误
target_link_libraries(${PROJECT_NAME} absl::check absl::log_flags absl::statusor)
# 链接Protobuf库
target_link_libraries(${PROJECT_NAME} ${Protobuf_LIBRARIES})
注: 直接链接 Protobuf 库, 会有链接错误,必须要链接 utf8_range 和 Absl 库。
- 编译工程,即可成功使用Protobuf库。
三、写在最后
- 以上配置仅适用于Windows平台下的CMake工程。
- 也可以使用其他的编译器,如MSVC等,需要确保编译 Protobuf 库和 使用Protobuf 的工程都使用一样的编译器。参考编译bat脚本
cmake ./ ^
-B build ^
-G "Visual Studio 18 2026" ^
-D protobuf_BUILD_TESTS=OFF ^
-D CMAKE_BUILD_TYPE=Release ^
-D CMAKE_INSTALL_PREFIX=./install ^
-D CMAKE_CXX_STANDARD=17 ^
-D CMAKE_CXX_STANDARD_REQUIRED=ON
cmake --build build --config Release
cmake --install build
- 过程中可以遇到以下错误:
- RuntimeLibrary 不匹配错误:
[build] lld-link: error: /failifmismatch: mismatch detected for 'RuntimeLibrary':
[build] >>> CMakeFiles/test_cpp.dir/cpp/test.pb.cc.obj has value MD_DynamicRelease
[build] >>> protobuf.lib(message.cc.obj) has value MT_StaticRelease
主要检查工程 cmake_policy 和
CMAKE_MSVC_RUNTIME_LIBRARY 是否正确设置;参考文档 其他版本的 cmake 参考对应版本设置 cmake_policy 即可。
- Protobuf链接错误:
lld-link: error: undefined symbol: utf8_range_IsValid
[build] >>> referenced by protobuf.lib(generated_message_tctable_lite.cc.obj):(public: static char const * __cdecl google::protobuf::internal::TcParser::FastUS1(class google::protobuf::MessageLite *, char const *, class google::protobuf::internal::ParseContext *, struct google::protobuf::internal::TcFieldData, struct google::protobuf::internal::TcParseTableBase const *, unsigned __int64))
[build] lld-link: error: undefined symbol: public: void __cdecl absl::lts_20250512::status_internal::StatusRep::Unref(void) const [build] >>> referenced by CMakeFiles/test_cpp.dir/cpp/main.cpp.obj:(main) [build] >>> referenced by CMakeFiles/test_cpp.dir/cpp/main.cpp.obj:(public: __cdecl absl::lts_20250512::Status::~Status(void))
主要检查工程是否链接了 utf8_range 和 Absl 的相关库。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...
