Introduction : Pourquoi un monorepo en C++ ?
Le développement de grands projets C++ est souvent confronté à des problèmes d'organisation du code. Les équipes choisissent entre un monorepo (un seul dépôt pour tout le code) et un multirepo (des dépôts séparés pour chaque bibliothèque). Dans le contexte du C++, un monorepo offre plusieurs avantages : simplification du refactoring, version unique des dépendances et système de build centralisé.
Cet article vous guidera à travers les aspects clés de l'organisation d'un monorepo pour le C++ : de la structure des dossiers à la configuration de CMake et à la gestion des dépendances. Vous apprendrez à rendre votre projet évolutif et pratique pour l'équipe.
1. Structure d'un monorepo pour le C++
Une structure correcte est la base d'un monorepo réussi. Il est recommandé d'utiliser une hiérarchie qui sépare les bibliothèques, les applications et les dépendances externes.
Exemple de structure de base
my_monorepo/├── CMakeLists.txt # Fichier CMake racine├── cmake/ # Modules CMake auxiliaires├── libs/ # Bibliothèques du projet│ ├── core/ # Cœur (logique, utilitaires)│ │ ├── include/│ │ │ └── core/│ │ ├── src/│ │ └── CMakeLists.txt│ ├── network/ # Modules réseau│ │ ├── include/│ │ ├── src/│ │ └── CMakeLists.txt│ └── utils/ # Utilitaires auxiliaires│ ├── include/│ ├── src/│ └── CMakeLists.txt├── apps/ # Applications exécutables│ ├── server/│ │ ├── src/│ │ └── CMakeLists.txt│ └── client/│ ├── src/│ └── CMakeLists.txt├── tests/ # Tests d'intégration├── third_party/ # Dépendances externes (git submodules)│ ├── fmt/│ └── spdlog/└── scripts/ # Scripts pour CI/CD et développementPrincipes clés
- libs/ : Chaque bibliothèque est un module autonome avec son propre CMakeLists.txt.
- apps/ : Les applications utilisent les bibliothèques via
target_link_libraries. - third_party/ : Les dépendances externes sont ajoutées via git submodules ou FetchContent.
- tests/ : Un répertoire séparé pour les tests qui vérifient l'intégration des composants.
2. Système de build : CMake pour un monorepo
CMake est l'outil standard pour les projets C++. Dans un monorepo, il permet de gérer les dépendances entre les bibliothèques et les applications.
CMakeLists.txt racine
Créez un fichier racine qui inclut tous les sous-projets :
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)
# Inclure les dépendances externesadd_subdirectory(third_party/fmt)add_subdirectory(third_party/spdlog)
# Inclure les bibliothèquesadd_subdirectory(libs/core)add_subdirectory(libs/network)add_subdirectory(libs/utils)
# Inclure les applicationsadd_subdirectory(apps/server)add_subdirectory(apps/client)
# Inclure les testsenable_testing()add_subdirectory(tests)Exemple de CMakeLists.txt pour une bibliothèque
# 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)Build et test
Pour builder l'ensemble du projet, utilisez :
mkdir build && cd buildcmake .. -DCMAKE_BUILD_TYPE=Releasecmake --build . --parallelctest --output-on-failure3. Gestion des dépendances dans un monorepo
L'un des principaux problèmes d'un monorepo est le contrôle des versions des dépendances. En C++, il existe plusieur