مقدمة: لماذا نحتاج إلى مستودع واحد (Monorepo) في C++؟
غالبًا ما يواجه تطوير مشاريع C++ الكبيرة مشكلة تنظيم الكود. تختار الفرق بين المستودع الواحد (Monorepo) (مستودع واحد لكل الكود) و المستودعات المتعددة (Multirepo) (مستودعات منفصلة لكل مكتبة). في سياق C++، يقدم المستودع الواحد (Monorepo) عددًا من المزايا: تبسيط إعادة الهيكلة (Refactoring)، إصدار موحد للتبعيات، ونظام بناء مركزي.
ستأخذك هذه المقالة عبر الجوانب الرئيسية لتنظيم المستودع الواحد (Monorepo) لـ C++: من هيكل المجلدات إلى إعداد CMake وإدارة التبعيات. ستتعلم كيفية جعل المشروع قابلاً للتوسع ومناسبًا للفريق.
1. هيكل المستودع الواحد (Monorepo) لـ C++
الهيكل الصحيح هو أساس المستودع الواحد (Monorepo) الناجح. يُوصى باستخدام تسلسل هرمي يفصل بين المكتبات والتطبيقات والتبعيات الخارجية.
مثال على الهيكل الأساسي
my_monorepo/├── CMakeLists.txt # ملف CMake الجذري├── cmake/ # وحدات CMake المساعدة├── libs/ # مكتبات المشروع│ ├── core/ # النواة (المنطق، الأدوات المساعدة)│ │ ├── include/│ │ │ └── core/│ │ ├── src/│ │ └── CMakeLists.txt│ ├── network/ # وحدات الشبكة│ │ ├── include/│ │ ├── src/│ │ └── CMakeLists.txt│ └── utils/ # الأدوات المساعدة│ ├── include/│ ├── src/│ └── CMakeLists.txt├── apps/ # التطبيقات القابلة للتنفيذ│ ├── server/│ │ ├── src/│ │ └── CMakeLists.txt│ └── client/│ ├── src/│ └── CMakeLists.txt├── tests/ # اختبارات التكامل├── third_party/ # التبعيات الخارجية (git submodules)│ ├── fmt/│ └── spdlog/└── scripts/ # نصوص برمجية للتكامل المستمر/التسليم المستمر والتطويرالمبادئ الأساسية
- libs/: كل مكتبة هي وحدة قائمة بذاتها مع ملف CMakeLists.txt الخاص بها.
- apps/: تستخدم التطبيقات المكتبات من خلال
target_link_libraries. - third_party/: تُضاف التبعيات الخارجية عبر git submodules أو FetchContent.
- tests/: دليل منفصل للاختبارات التي تتحقق من تكامل المكونات.
2. نظام البناء: CMake للمستودع الواحد (Monorepo)
CMake هي الأداة القياسية لمشاريع C++. في المستودع الواحد (Monorepo)، تسمح بإدارة التبعيات بين المكتبات والتطبيقات.
ملف CMakeLists.txt الجذري
أنشئ ملفًا جذريًا يربط جميع المشاريع الفرعية:
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)
# ربط التبعيات الخارجيةadd_subdirectory(third_party/fmt)add_subdirectory(third_party/spdlog)
# ربط المكتباتadd_subdirectory(libs/core)add_subdirectory(libs/network)add_subdirectory(libs/utils)
# ربط التطبيقاتadd_subdirectory(apps/server)add_subdirectory(apps/client)
# ربط الاختباراتenable_testing()add_subdirectory(tests)مثال على CMakeLists.txt لمكتبة
# 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)البناء والاختبار
لبناء المشروع بأكمله، استخدم:
mkdir build && cd buildcmake .. -DCMAKE_BUILD_TYPE=Releasecmake --build . --parallelctest --output-on-failure3. إدارة التبعيات في المستودع الواحد (Monorepo)
إحدى المشكلات الرئيسية للمستودع الواحد (Monorepo) هي التحكم في إصدارات التبعيات. في C++، هناك عدة