Monorepository mit C++: Code-Organisation für Anfänger

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

Was ist ein Monorepository und warum wird es in C++ benötigt?



Ein Monorepository (Monorepo) ist ein Ansatz zur Code-Verwaltung, bei dem alle Komponenten eines Projekts, Bibliotheken, Hilfsprogramme und sogar die Dokumentation in einem einzigen Repository gespeichert werden. Für Projekte in C++ ist dies besonders relevant, da die Sprache traditionell eine klare Datei- und Abhängigkeitsstruktur erfordert.



Vorteile eines Monorepositorys für C++:

  • Einheitliche Abhängigkeitsversion – alle Module verwenden dieselbe Version der Bibliotheken, was ABI-Konflikte ausschließt.
  • Vereinfachter Build – eine einzige CMakeLists.txt oder ein Build-System verwaltet das gesamte Projekt.
  • Atomare Commits – Änderungen in mehreren Modulen können in einem einzigen Commit zusammengefasst werden, was das Code-Review vereinfacht.
  • Einfaches Refactoring – eine API-Änderung an einer Stelle ist sofort in allen abhängigen Modulen sichtbar.


Allerdings ist ein Monorepository nicht für jeden geeignet: Wenn Teams völlig unabhängig sind und unterschiedliche Compiler-Versionen verwenden, ist ein Multirepository besser geeignet. Für Anfänger ist ein Monorepository jedoch eine hervorragende Möglichkeit, Kopfschmerzen bei der Einrichtung von Pfaden und Abhängigkeiten zu vermeiden.



Hauptteil: Erstellen eines Monorepositorys für ein C++-Projekt



1. Verzeichnisstruktur



Eine korrekte Struktur ist die Grundlage jedes Monorepositorys. Empfohlenes Schema für C++:



my_monorepo/├── CMakeLists.txt          # Root-CMake-Datei├── cmake/                  # Hilfs-CMake-Module│   └── helpers.cmake├── libs/                   # Bibliotheken│   ├── core/               # Projektkern│   │   ├── CMakeLists.txt│   │   ├── include/core/│   │   └── src/│   └── utils/              # Hilfsprogramme│       ├── CMakeLists.txt│       ├── include/utils/│       └── src/├── apps/                   # Ausführbare Anwendungen│   ├── main_app/│   │   ├── CMakeLists.txt│   │   └── main.cpp│   └── test_app/│       ├── CMakeLists.txt│       └── main.cpp├── tests/                  # Tests (falls nicht in Module integriert)│   └── test_core.cpp├── scripts/                # Build- und CI-Skripte│   └── build.sh├── .gitignore└── README.md


Grundregel: Jedes Modul (Bibliothek oder Anwendung) sollte in sich abgeschlossen sein. Es enthält seine eigene CMakeLists.txt, Header-Dateien in include/ und Quelldateien in src/.



2. Einrichtung der root-CMakeLists.txt



Die root-CMakeLists.txt verwaltet den gesamten Build. Sie sollte allgemeine Compiler-Einstellungen, den C++-Standard definieren und die untergeordneten Module einbinden:



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

# Einheitlichen C++17-Standard für das gesamte Projekt festlegenset(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)set(CMAKE_CXX_EXTENSIONS OFF)

# Option zum Erstellen von Testsoption(BUILD_TESTS "Build tests" OFF)

# Hilfsmodule einbindeninclude(cmake/helpers.cmake)

# Unterverzeichnisse mit Bibliotheken hinzufügenadd_subdirectory(libs/core)add_subdirectory(libs/utils)

# Anwendungen hinzufügenadd_subdirectory(apps/main_app)add_subdirectory(apps/test_app)

# Wenn Tests aktiviert sind, diese einbindenif(BUILD_TESTS) enable_testing() add_subdirectory(tests)endif()


3. Beispiel einer Bibliothek: libs/core



Betrachten wir die Bibliothek core, die eine Klasse für die Arbeit mit Zahlen enthält. Dateistruktur:



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


Inhalt von 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


Blogs

Buchempfehlungen