C++ 单体仓库:代码组织与最佳实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么在 C++ 中需要单体仓库?



大型 C++ 项目的开发常常面临代码组织的问题。团队需要在单体仓库(所有代码在一个仓库中)和多仓库(每个库有独立的仓库)之间做出选择。在 C++ 的背景下,单体仓库提供了一系列优势:简化重构、统一的依赖版本以及集中化的构建系统。



本文将引导您了解 C++ 单体仓库组织的关键方面:从文件夹结构到 CMake 配置和依赖管理。您将学习如何使项目具有可扩展性并方便团队协作。



1. C++ 单体仓库的结构



正确的结构是成功单体仓库的基础。建议使用将库、应用程序和外部依赖项分开的层级结构。



基本结构示例



my_monorepo/├── CMakeLists.txt          # 根 CMake 文件├── cmake/                  # 辅助 CMake 模块├── libs/                   # 项目库│   ├── core/               # 核心(逻辑、工具)│   │   ├── include/│   │   │   └── core/│   │   ├── src/│   │   └── CMakeLists.txt│   ├── network/            # 网络模块│   │   ├── include/│   │   ├── src/│   │   └── CMakeLists.txt│   └── utils/              # 辅助工具│       ├── include/│       ├── src/│       └── CMakeLists.txt├── apps/                   # 可执行应用程序│   ├── server/│   │   ├── src/│   │   └── CMakeLists.txt│   └── client/│       ├── src/│       └── CMakeLists.txt├── tests/                  # 集成测试├── third_party/            # 外部依赖项(git submodules)│   ├── fmt/│   └── spdlog/└── scripts/                # CI/CD 和开发脚本


关键原则



  • libs/:每个库都是一个自包含的模块,拥有自己的 CMakeLists.txt。
  • apps/:应用程序通过 target_link_libraries 使用库。
  • third_party/:外部依赖项通过 git submodules 或 FetchContent 添加。
  • tests/:用于测试组件集成的独立目录。


2. 构建系统:用于单体仓库的 CMake



CMake 是 C++ 项目的标准工具。在单体仓库中,它允许管理库和应用程序之间的依赖关系。



根 CMakeLists.txt



创建一个包含所有子项目的根文件:



cmake_minimum_required(VERSION 3.20)project(MyMonorepo VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 包含外部依赖项add_subdirectory(third_party/fmt)add_subdirectory(third_party/spdlog)

# 包含库add_subdirectory(libs/core)add_subdirectory(libs/network)add_subdirectory(libs/utils)

# 包含应用程序add_subdirectory(apps/server)add_subdirectory(apps/client)

# 包含测试enable_testing()add_subdirectory(tests)


库的 CMakeLists.txt 示例



# libs/core/CMakeLists.txtadd_library(core    src/core_module.cpp    src/utilities.cpp)

target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

target_link_libraries(core PUBLIC fmt::fmt spdlog::spdlog)


构建和测试



要构建整个项目,请使用:



mkdir build && cd buildcmake .. -DCMAKE_BUILD_TYPE=Releasecmake --build . --parallelctest --output-on-failure


3. 单体仓库中的依赖管理



单体仓库的主要问题之一是依赖项的版本控制。在 C++ 中,有几种方法可以解决这个问题。

博客

书籍推荐