You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求CMake示例:先编译Protobuf IDL再构建静态库(子模块场景)

多静态库+Protobuf预编译的CMake配置示例

典型项目结构

my_libs_repo/
├── CMakeLists.txt
├── proto/
│   ├── common.proto
│   └── module_a.proto
├── module_a/
│   ├── CMakeLists.txt
│   ├── src/
│   │   └── module_a_core.cpp
│   └── include/
│       └── module_a/
│           └── module_a_core.h
└── module_b/
    ├── CMakeLists.txt
    ├── src/
    │   └── module_b_core.cpp
    └── include/
        └── module_b/
            └── module_b_core.h

根目录CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(my_libs VERSION 1.0.0 LANGUAGES CXX)

# 指定C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找系统预安装的Protocol Buffers
find_package(Protobuf REQUIRED)
message(STATUS "Found Protobuf: ${Protobuf_VERSION}")

# 统一设置Protobuf生成文件的输出目录(避免污染源码树)
set(PROTO_GENERATED_DIR ${CMAKE_BINARY_DIR}/generated/protobuf)
file(MAKE_DIRECTORY ${PROTO_GENERATED_DIR})

# 列出所有需要编译的.proto文件
set(PROTO_FILES
    proto/common.proto
    proto/module_a.proto
)

# 调用CMake内置函数编译Protobuf IDL,生成C++源码
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS
    OUT_DIR ${PROTO_GENERATED_DIR}
    ${PROTO_FILES}
)

# 将生成的Protobuf源码打包为独立静态库,供其他模块依赖
add_library(my_libs_protobuf STATIC ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(my_libs_protobuf PUBLIC ${Protobuf_LIBRARIES})
target_include_directories(my_libs_protobuf PUBLIC
    ${PROTO_GENERATED_DIR}
    ${Protobuf_INCLUDE_DIRS}
)

# 添加子模块,每个子模块对应一个业务静态库
add_subdirectory(module_a)
add_subdirectory(module_b)

子模块(静态库)CMakeLists.txt(以module_a为例)

# 定义module_a静态库
add_library(module_a STATIC
    src/module_a_core.cpp
)

# 依赖Protobuf静态库,CMake会自动保证先编译Protobuf再编译当前模块
target_link_libraries(module_a PUBLIC my_libs_protobuf)

# 暴露模块自身的头文件目录,方便父项目引用
target_include_directories(module_a PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

module_b的配置与module_a完全一致,只需替换对应文件名即可。

父项目引入方式

父项目中若已通过git submodule add将此仓库引入到third_party/my_libs,只需在父项目的CMakeLists.txt中添加:

add_subdirectory(third_party/my_libs)

# 构建可执行文件时依赖子模块的静态库
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE module_a module_b)

核心逻辑说明

  • 编译顺序保障:通过将生成的Protobuf源码打包为独立静态库my_libs_protobuf,让所有业务静态库依赖它,CMake的依赖解析机制会自动确保:先执行Protobuf编译步骤生成源码,再编译my_libs_protobuf,最后编译业务静态库,彻底避免缺失生成文件的编译错误。
  • 源码目录干净:生成的Protobuf文件统一输出到构建目录下的generated/protobuf,不会污染源码仓库。
  • 子模块友好:所有静态库的头文件目录通过PUBLIC暴露,父项目引入后可直接#include对应模块的头文件。

内容的提问来源于stack exchange,提问作者user12066

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:43:10