如何在C++中通过CMake(FetchContent/find_package)配置Protocol Buffers
在C++项目中正确配置Protocol Buffers(使用find_package或FetchContent)
需求与问题
需要在C++项目中通过find_package或FetchContent完整配置Protocol Buffers,当前尝试的CMake配置无法导入头文件#include "google/protobuf/runtime_version.h",请求正确的配置方法。
当前尝试的CMake配置
cmake_minimum_required(VERSION 3.28) project(ProtoCPP) set(CMAKE_CXX_STANDARD 20) include(FetchContent) include_directories(src/proto) file(GLOB PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/proto/*.cc") file(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") set(ABSL_PROPAGATE_CXX_STD ON) FetchContent_Declare( abseil GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git GIT_TAG 20240116.2 ) FetchContent_MakeAvailable(abseil) FetchContent_Declare( protobuf GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git GIT_TAG v27.1 ) FetchContent_Declare(protobuf) add_executable(ProtoCPP ${SOURCE_FILES} ${PROTO_FILES}) target_link_libraries(ProtoCPP)
项目结构
ProtoCPP/ ├── src/ │ ├── proto/ │ │ ├── 自定义.proto文件 │ │ └── 生成的.cc/.h文件 │ └── 业务代码文件(如main.cpp) └── CMakeLists.txt
正确配置方案
方案一:使用FetchContent拉取并配置Protobuf
该方案无需提前安装Protobuf,直接从GitHub拉取源码构建:
cmake_minimum_required(VERSION 3.28) project(ProtoCPP) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(ABSL_PROPAGATE_CXX_STD ON) # 让Abseil继承项目C++标准 include(FetchContent) # 配置Abseil(Protobuf 27+版本依赖) FetchContent_Declare( abseil GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git GIT_TAG 20240116.2 ) FetchContent_MakeAvailable(abseil) # 拉取并配置Protobuf FetchContent_Declare( protobuf GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git GIT_TAG v27.1 OVERRIDE_FIND_PACKAGE # 让find_package优先使用拉取的版本 ) FetchContent_MakeAvailable(protobuf) # 加载Protobuf配置 find_package(protobuf REQUIRED) # 指定自定义.proto文件路径(替换为你的实际文件) set(PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/proto/your_protobuf.proto") # 自动编译.proto生成C++代码 protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES}) # 收集业务源代码 file(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") # 创建可执行文件 add_executable(ProtoCPP ${SOURCE_FILES} ${PROTO_SRCS}) # 添加头文件包含路径 target_include_directories(ProtoCPP PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # 生成的proto头文件默认输出到构建目录 ${CMAKE_CURRENT_SOURCE_DIR}/src/proto ) # 链接依赖库 target_link_libraries(ProtoCPP PRIVATE protobuf::libprotobuf # Protobuf核心库 absl::base absl::strings # 按需添加Abseil组件 )
方案二:使用find_package调用系统已安装的Protobuf
如果已通过包管理器(如apt、brew)或手动编译安装了Protobuf,可直接使用:
cmake_minimum_required(VERSION 3.28) project(ProtoCPP) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 查找系统中已安装的Protobuf find_package(protobuf REQUIRED) # 指定自定义.proto文件路径 set(PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/proto/your_protobuf.proto") # 自动编译.proto生成C++代码 protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES}) # 收集业务源代码 file(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") # 创建可执行文件 add_executable(ProtoCPP ${SOURCE_FILES} ${PROTO_SRCS}) # 添加头文件包含路径 target_include_directories(ProtoCPP PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/proto ) # 链接Protobuf库 target_link_libraries(ProtoCPP PRIVATE protobuf::libprotobuf )
关键说明
- 头文件问题解决:
google/protobuf/runtime_version.h是Protobuf核心头文件,只要正确链接protobuf::libprotobuf目标,CMake会自动将Protobuf的头文件目录加入项目包含路径,无需手动指定。 - .proto文件处理:使用
protobuf_generate_cpp函数可自动编译.proto文件生成对应C++代码,生成的文件默认输出到CMake构建目录,因此需要将该目录加入包含路径。 - FetchContent注意事项:Protobuf 21+版本依赖Abseil,需先配置Abseil;
OVERRIDE_FIND_PACKAGE参数可避免系统已安装的Protobuf与拉取版本冲突。
内容的提问来源于stack exchange,提问作者Advik
相关产品推荐
相关产品推荐

