请求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
相关产品推荐
相关产品推荐

