مقدمة: لماذا نحتاج إلى مستودع أحادي في C++؟
\n\nفي عالم تطوير C++، يظهر السؤال عاجلاً أم آجلاً: كيف ننظم الكود عندما يكون لدينا العديد من المشاريع؟ المكتبات، الأدوات المساعدة، الملفات التنفيذية - كل هذا يحتاج إلى ربط، وإدارة إصدارات، وبناء. غالبًا ما يؤدي النهج التقليدي مع العديد من المستودعات المنفصلة (المستودعات المتعددة) إلى مشاكل: صعوبة مزامنة التغييرات، صعوبة اختبار التكامل، وتصبح التبعيات بين المشاريع كابوسًا.
\n\nالبديل هو المستودع الأحادي. وهو مستودع واحد يتم فيه تخزين جميع مكونات مشروعك: المكتبات، التطبيقات، الاختبارات، التوثيق. يُستخدم هذا النهج بنشاط في Google وFacebook وMicrosoft والعديد من الشركات الأخرى. بالنسبة لـ C++، يوفر المستودع الأحادي عددًا من المزايا:
\n\n- \n
- إصدار موحد للتبعيات - أنت تعرف دائمًا أي إصدار من المكتبة يُستخدم في جميع المشاريع. \n
- التزامات ذرية - تغيير API للمكتبة وتحديث جميع مستخدميها يحدث في التزام واحد. \n
- CI/CD مبسط - خط أنابيب واحد لجميع المكونات. \n
- الشفافية - من السهل رؤية كيفية تنظيم المشروع بأكمله. \n
في هذه المقالة، سنناقش التنظيم العملي للمستودع الأحادي لـ C++ باستخدام CMake، ونعرض هيكل المجلدات وأمثلة على الكود.
\n\n1. هيكل المجلدات: أساس النظام
\n\nالخطوة الأولى نحو مستودع أحادي ناجح هي هيكل دليل مدروس جيدًا. إليك قالب موصى به لمشروع C++:
\n\nmy_project/\n├── CMakeLists.txt # ملف CMake الجذر\n├── README.md\n├── .gitignore\n├── .clang-format\n├── cmake/ # وحدات CMake المساعدة\n│ └── FindMyLib.cmake\n├── libs/ # المكتبات\n│ ├── core/ # مكتبة core\n│ │ ├── CMakeLists.txt\n│ │ ├── include/\n│ │ │ └── core/\n│ │ │ ├── math.h\n│ │ │ └── string_utils.h\n│ │ └── src/\n│ │ ├── math.cpp\n│ │ └── string_utils.cpp\n│ └── network/ # مكتبة network\n│ ├── CMakeLists.txt\n│ ├── include/\n│ │ └── network/\n│ │ └── http_client.h\n│ └── src/\n│ └── http_client.cpp\n├── apps/ # التطبيقات التنفيذية\n│ ├── server/\n│ │ ├── CMakeLists.txt\n│ │ └── src/\n│ │ └── main.cpp\n│ └── cli_tool/\n│ ├── CMakeLists.txt\n│ └── src/\n│ └── main.cpp\n├── tests/ # الاختبارات\n│ ├── CMakeLists.txt\n│ ├── test_core/\n│ │ ├── CMakeLists.txt\n│ │ └── test_math.cpp\n│ └── test_network/\n│ ├── CMakeLists.txt\n│ └── test_http_client.cpp\n└── third_party/ # التبعيات الخارجية (وحدات git الفرعية أو FetchContent)\n └── googletest/\n\n\nالمبادئ الأساسية:
\n- \n
- libs/ - جميع المكتبات. كل مكتبة هي مجلد منفصل مع ملف CMakeLists.txt الخاص بها. \n
- apps/ - جميع الملفات التنفيذية. تعتمد على المكتبات من libs/. \n
- tests/ - الاختبارات، منظمة حسب المكتبات. \n
- third_party/ - التبعيات الخارجية. استخدم
git submodulesأوFetchContentلتضمينها. \n
2. CMake: إعداد بناء المستودع الأحادي
\n\nCMake هي الأداة المثالية للمستودع الأحادي. دعنا ننظر في كيفية إعداد ملف CMakeLists.txt الجذر وملفات المكتبات.
ملف CMakeLists.txt الجذر
\n\ncmake_minimum_required(VERSION 3.20)\nproject(MyProject VERSION 1.0.0 LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# خيارات لتمكين/تعطيل المكونات\noption(BUILD_TESTS "Build tests" ON)\noption(BUILD_APPS "Build applications" ON)\n\n# تضمين التبعيات الخارجية\ninclude(FetchConte