ما هو المستودع الواحد (monorepo) ولماذا هو ضروري في C++؟
المستودع الواحد (monorepo) هو نهج لإدارة الكود يتم فيه تخزين جميع مكونات المشروع والمكتبات والأدوات وحتى التوثيق في مستودع واحد. بالنسبة لمشاريع C++، هذا مهم بشكل خاص، لأن اللغة تتطلب تقليديًا هيكلًا واضحًا للملفات والتبعيات.
مزايا المستودع الواحد لـ C++:
- إصدار موحد للتبعيات — تستخدم جميع الوحدات نفس إصدار المكتبات، مما يلغي تعارضات ABI.
- بناء مبسط — ملف CMakeLists.txt واحد أو نظام بناء واحد يدير المشروع بأكمله.
- تغييرات ذرية (Atomic commits) — يمكن دمج التغييرات في وحدات متعددة في commit واحد، مما يبسط مراجعة الكود.
- إعادة هيكلة سهلة — تغيير 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