Monorepository mit C++: Code-Organisation und Best Practices

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Monorepo mit C++: Code-Organisation und Best Practices



Die Entwicklung großer C++-Projekte steht oft vor dem Problem der Code-Fragmentierung: Bibliotheken sind über verschiedene Repositories verstreut, Versionen sind nicht synchronisiert und die Integration wird zum Kopfschmerz. Die Lösung ist ein Monorepo. Dies ist ein Ansatz, bei dem der gesamte Code, einschließlich Bibliotheken, Hilfsprogrammen und Tests, in einem einzigen Repository gespeichert wird. In diesem Artikel werden wir untersuchen, wie man ein Monorepo für C++-Projekte richtig organisiert, moderne Tools (CMake, Conan, Git) verwendet und typische Fehler vermeidet.



1. Verzeichnisstruktur: Die Grundlage der Ordnung



Der erste Schritt besteht darin, eine einheitliche, klare Ordnerstruktur zu erstellen. Hier ist ein empfohlenes Schema für ein C++-Monorepo:



my-monorepo/├── cmake/                  # Gemeinsame CMake-Module├── libs/                   # Bibliotheken│   ├── core/               # Kern (Logging, Allokatoren)│   ├── math/               # Mathematik-Bibliothek│   └── network/            # Netzwerk-Bibliothek├── apps/                   # Ausführbare Anwendungen│   ├── server/             # Server-Anwendung│   └── client/             # Client-Anwendung├── tests/                  # Integrationstests├── scripts/                # Build- und Deployment-Skripte├── third_party/            # Externe Abhängigkeiten (Submodules)├── CMakeLists.txt          # Root-CMake-Datei├── conanfile.txt           # Abhängigkeitsmanager (optional)└── .github/                # CI/CD (GitHub Actions)


Warum funktioniert das?

  • libs/ — alle Bibliotheken an einem Ort, leicht wiederverwendbar.
  • apps/ — Anwendungen, die von libs abhängen.
  • third_party/ — externe Abhängigkeiten (über git submodules oder CMake FetchContent).
  • cmake/ — benutzerdefinierte Funktionen (z.B. add_library_with_tests).


2. CMake: Einrichtung des Root-Projekts



CMake ist der Standard für C++-Builds in Monorepos. Konfigurieren Sie die root CMakeLists.txt so, dass sie alle Unterprojekte einbindet:



cmake_minimum_required(VERSION 3.20)project(MyMonorepo LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Gemeinsame Optionenoption(BUILD_TESTS "Build tests" ON)

# Bibliotheken einbindenadd_subdirectory(libs/core)add_subdirectory(libs/math)add_subdirectory(libs/network)

# Anwendungen einbindenadd_subdirectory(apps/server)add_subdirectory(apps/client)

# Tests einbindenif(BUILD_TESTS) enable_testing() add_subdirectory(tests)endif()


Wichtige Punkte:

  • Verwenden Sie target_link_libraries, um Abhängigkeiten zwischen Bibliotheken explizit anzugeben.
  • Verwenden Sie für externe Abhängigkeiten (z.B. Boost, fmt) FetchContent oder Conan.
  • Vermeiden Sie globale include_directories — verwenden Sie target_include_directories mit PUBLIC oder PRIVATE.


3. Abhängigkeitsmanagement innerhalb des Monorepos



Eines der Hauptprobleme eines Monorepos sind zirkuläre Abhängigkeiten. Lösung: eine strenge Hierarchie. Zum Beispiel:



  • core (hängt von nichts außer der Standardbibliothek ab)
  • math (hängt von core ab)
  • network (hängt von core und math ab)
  • server (hängt von core, math, network ab)


Beispiel einer CMakeLists.txt für die Bibliothek math:



add_library(math    src/vector.cpp    src/matrix.cpp    include/math/vector.h    include/math/matrix.h)

target_include_directories(math PUBLIC include PRIVATE src)

target_link_libraries(math PUBLIC core # Abhängigkeit explizit angeben

Blogs

Buchempfehlungen