Windows平台下CMake工程中使用protobuf

Windows平台下的CMake工程中使用protobuf

本文档介绍如何在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/CommonExtensions/Microsoft/CMake/CMake/bin

操作步骤

一、初始化Protobuf配置

本文使用源码编译配置Protobuf库。

  1. 下载Protobuf源码Protobuf 33.2 选择下载 protobuf-33.2.zip
  2. 解压 protobuf-33.2.zip
  3. 在解压后的protobuf-33.2目录下,创建 build.bat 写入以下内容,然后执行这个脚本。
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
  1. 编译完成之后,会在 protobuf-33.2/install 目录下,会生成 binincludelib 三个目录。里面包括Protobuf的头文件库文件protoc 编译工具等。

  2. protobuf-33.2/install/bin 目录添加到环境变量中,即可全局使用 protoc 编译工具。

二、在CMake工程中使用Protobuf库

  1. 注意设置工程CMAKE_BUILD_TYPERelease, 保持和Protobuf库的编译类型一致。

  2. 在CMakeLists.txt 头部添加 cmake_policy(SET CMP0091 NEW) 来设置新的CMake策略。

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_rangeAbsl库。

  1. 编译工程,即可成功使用Protobuf库。

三、写在最后

  1. 以上配置仅适用于Windows平台下的CMake工程。
  2. 也可以使用其他的编译器,如MSVC等,需要确保编译Protobuf库和使用Protobuf的工程都使用相同的编译器。参考编译bat脚本
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
  1. 过程中可以遇到以下错误:
  • RuntimeLibrary 不匹配错误:
txt 复制代码
[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_policyCMAKE_MSVC_RUNTIME_LIBRARY是否正确设置;参考文档

其他版本的cmake参考对应版本设置cmake_policy即可。

  • Protobuf链接错误:
txt 复制代码
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_rangeAbsl的相关库。

相关推荐
码匠许师傅1 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
小小龙学IT2 小时前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
知无不研4 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
C++ 老炮儿的技术栈5 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qz_Serene7 小时前
C++:类和对象(上)
开发语言·c++
郝学胜-神的一滴9 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
hetao17338379 小时前
2026-08-09~08-14 hetao1733837 的刷题记录
c++·算法
间歇性努力持续性发呆的野生快乐选手11 小时前
栈的性质(进栈,出栈,访问)
数据结构·c++
旖旎夜光12 小时前
LeetCode 904:水果成篮(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
hansang_IR12 小时前
【题解】P14468 [COCI 2025/2026 #1] 和谐 / Harmonija(线段树 DDP 版本)
c++·算法·动态dp