使用C++的单一代码仓库:面向初学者的代码组织

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

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

开始课程

什么是单一代码仓库,为什么在C++中需要它?



单一代码仓库(monorepo)是一种代码管理方法,项目的所有组件、库、工具甚至文档都存储在一个仓库中。对于C++项目来说,这尤其重要,因为该语言传统上需要清晰的文件和依赖关系结构。



单一代码仓库对C++的优势:

  • 统一的依赖版本 — 所有模块使用相同版本的库,从而消除ABI冲突。
  • 简化的构建 — 一个CMakeLists.txt或构建系统管理整个项目。
  • 原子提交 — 多个模块的更改可以合并到一个提交中,从而简化代码审查。
  • 轻松重构 — 在一个地方更改API会立即在所有依赖模块中可见。


然而,单一代码仓库并不适合所有人:如果团队完全独立并使用不同版本的编译器,最好考虑多仓库。对于初学者来说,单一代码仓库是避免路径和依赖配置麻烦的绝佳方式。



主要部分:为C++项目创建单一代码仓库



1. 目录结构



正确的结构是任何单一代码仓库的基础。推荐的C++模板:



my_monorepo/├── CMakeLists.txt          # 根CMake文件├── cmake/                  # 辅助CMake模块│   └── helpers.cmake├── libs/                   # 库│   ├── core/               # 项目核心│   │   ├── CMakeLists.txt│   │   ├── include/core/│   │   └── src/│   └── utils/              # 工具│       ├── CMakeLists.txt│       ├── include/utils/│       └── src/├── apps/                   # 可执行应用程序│   ├── main_app/│   │   ├── CMakeLists.txt│   │   └── main.cpp│   └── test_app/│       ├── CMakeLists.txt│       └── main.cpp├── tests/                  # 测试(如果未内置于模块中)│   └── test_core.cpp├── scripts/                # 构建和CI脚本│   └── build.sh├── .gitignore└── README.md


关键规则:每个模块(库或应用程序)都应该是自包含的。它包含自己的CMakeLists.txt、include/中的头文件和src/中的源文件。



2. 配置根CMakeLists.txt



根CMakeLists.txt管理整个构建。它应定义通用的编译器设置、C++标准并包含子模块:



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

# 为整个项目设置统一的C++17标准set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)set(CMAKE_CXX_EXTENSIONS OFF)

# 构建测试的选项option(BUILD_TESTS "Build tests" OFF)

# 包含辅助模块include(cmake/helpers.cmake)

# 添加包含库的子目录add_subdirectory(libs/core)add_subdirectory(libs/utils)

# 添加应用程序add_subdirectory(apps/main_app)add_subdirectory(apps/test_app)

# 如果启用了测试,则包含它们if(BUILD_TESTS) enable_testing() add_subdirectory(tests)endif()


3. 库示例:libs/core



考虑core库,它包含一个用于数字运算的类。文件结构:



libs/core/├── CMakeLists.txt├── include/core/│   └── calculator.h└── src/    └── calculator.cpp


include/core/calculator.h的内容:



#ifndef CORE_CALCULATOR_H#define CORE_CALCULATOR_H

namespace core {

class Calculator {public: Calculator() = default; int add(int a, int b); int multiply(int a, int b);};

} // namespace core

#endif // CORE_CALCULATOR_H


博客

书籍推荐