
في الجزء السابق من هذه القصة المسلية ، تحدثنا عن تنظيم مكتبة رأس كجزء من مولد نظام التجميع CMake.
هذه المرة نضيف مكتبة مترجمة إليها ، ونتحدث أيضًا عن تخطيط الوحدات مع بعضها البعض.
كما كان من قبل ، يمكن لأولئك الذين لا يستطيعون الانتظار ، الانتقال على الفور إلى المستودع المحدث ولمس كل شيء بأيديهم.
محتوى
- فرق
- قهر
أول شيء يجب القيام به لتحقيق هدفنا النبيل هو تقسيم البرنامج قيد التطوير إلى كتل معزولة عالمية موحدة من وجهة نظر المستخدم.
الجزء الأول وصف هذه الكتلة القياسية - مشروع مع مكتبة رأس. الآن دعنا نضيف مكتبة مترجمة لمشروعنا.
للقيام بذلك ، نأخذ تنفيذ وظيفة myfunc
في ملف .cpp
منفصل:
diff --git a/include/mylib/myfeature.hpp b/include/mylib/myfeature.hpp index 43db388..ba62b4f 100644 --- a/include/mylib/myfeature.hpp +++ b/include/mylib/myfeature.hpp @@ -46,8 +46,5 @@ namespace mylib \~ \see mystruct */ - inline bool myfunc (mystruct) - { - return true; - } + bool myfunc (mystruct); } diff --git a/src/mylib/myfeature.cpp b/src/mylib/myfeature.cpp new file mode 100644 index 0000000..abb5004 --- /dev/null +++ b/src/mylib/myfeature.cpp @@ -0,0 +1,9 @@ +#include <mylib/myfeature.hpp> + +namespace mylib +{ + bool myfunc (mystruct) + { + return true; + } +}
ثم نقوم بتعريف المكتبة المترجمة ( myfeature
) ، والتي ستتألف من ملف .cpp
تم الحصول عليه في الخطوة السابقة. من الواضح أن المكتبة الجديدة تتطلب رؤوسًا حالية ، ومن أجل ضمان ذلك ، من الممكن والضروري mylib
بالغرض الحالي من mylib
. علاوة على ذلك ، يكون الرابط بينهما عامًا ، مما يعني أن كل شيء سيتم ربط هدف myfeature
به myfeature
تلقائيًا هدف mylib
في التحميل ( المزيد حول كيفية الاتصال ).
diff --git a/CMakeLists.txt b/CMakeLists.txt index 108045c..0de77b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,17 @@ target_compile_features(mylib INTERFACE cxx_std_17) add_library(Mylib::mylib ALIAS mylib) +################################################################################################### +## +## +## +################################################################################################### + +add_library(myfeature src/mylib/myfeature.cpp) +target_link_libraries(myfeature PUBLIC mylib) + +add_library(Mylib::myfeature ALIAS myfeature) +
بعد ذلك ، سنجعل المكتبة الجديدة مثبتة أيضًا على النظام:
@@ -72,7 +83,7 @@ add_library(Mylib::mylib ALIAS mylib) install(DIRECTORY include/mylib DESTINATION include) -install(TARGETS mylib EXPORT MylibConfig) +install(TARGETS mylib myfeature EXPORT MylibConfig) install(EXPORT MylibConfig NAMESPACE Mylib:: DESTINATION share/Mylib/cmake) include(CMakePackageConfigHelpers)
تجدر الإشارة إلى أنه لغرض myfeature
، وكذلك mylib
، تم myfeature
الاسم المستعار بالبادئة Mylib::
. يتم ذكر الشيء نفسه لكلا الغرضين عند تصديرهما للتثبيت في النظام. هذا يجعل من الممكن العمل بشكل موحد مع أهداف لأي نظام ربط .
بعد ذلك ، يظل myfunc
اختبارات الوحدة والمكتبة الجديدة (تمت myfunc
وظيفة myfunc
من الرأس ، لذا تحتاج الآن إلى الارتباط):
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5620be4..bc1266c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable(mylib-unit-tests test_main.cpp) target_sources(mylib-unit-tests PRIVATE mylib/myfeature.cpp) target_link_libraries(mylib-unit-tests PRIVATE - Mylib::mylib + Mylib::myfeature doctest::doctest )
لا تحتاج الرؤوس ( Mylib::mylib
) الآن إلى أن تكون متصلاً بشكل منفصل ، لأنه ، كما ذكر سابقًا ، يتم توصيلها تلقائيًا مع المكتبة ( Mylib::myfeature
).
وأضف بضعًا من الفروق الدقيقة لضمان قياسات التغطية مع مراعاة المكتبة التي وصلت حديثًا:
@@ -15,11 +15,16 @@ if(MYLIB_COVERAGE AND GCOVR_EXECUTABLE) target_compile_options(mylib-unit-tests PRIVATE --coverage) target_link_libraries(mylib-unit-tests PRIVATE gcov) + target_compile_options(myfeature PRIVATE --coverage) + target_link_libraries(myfeature PRIVATE gcov) + add_custom_target(coverage COMMAND ${GCOVR_EXECUTABLE} - --root=${PROJECT_SOURCE_DIR}/include/ - --object-directory=${CMAKE_CURRENT_BINARY_DIR} + --root=${PROJECT_SOURCE_DIR}/ + --filter=${PROJECT_SOURCE_DIR}/include + --filter=${PROJECT_SOURCE_DIR}/src + --object-directory=${PROJECT_BINARY_DIR} DEPENDS check )
يمكنك إضافة المزيد من المكتبات ، الملفات التنفيذية ، إلخ. لا يهم بالضبط كيف يتم ربطهم معًا في إطار المشروع. الشيء الوحيد المهم هو ما الأهداف هي واجهة وحدة لدينا ، وهذا هو ، الخروج.
الآن لدينا وحدات نمطية قياسية ، ويمكننا السيطرة عليها: تكوين هيكل من أي تعقيد منها ، وتثبيتها في نظام أو ربطها داخل نظام تجميع واحد.
تركيب النظام
طريقة واحدة لاستخدام الوحدة النمطية هي تثبيت الوحدة النمطية لدينا في النظام.
cmake --build /// --target install
بعد ذلك ، يتصل بأي مشروع آخر باستخدام find_package
.
find_package(Mylib 1.0 REQUIRED)
الاتصال باعتباره وحدة فرعية
هناك خيار آخر هو توصيل المجلد add_subdirectory
بمشروع آخر كوحدة فرعية باستخدام add_subdirectory
.
استخدام
طرق الربط مختلفة ، ولكن النتيجة هي نفسها. في كلتا الحالتين ، في مشروع يستخدم وحدتنا ، ستكون أهداف Mylib::myfeature
و Mylib::mylib
متاحة ، والتي يمكن استخدامها ، على سبيل المثال ، مثل هذا:
add_executable(some_executable some.cpp sources.cpp) target_link_libraries(some_executable PRIVATE Mylib::myfeature)
على وجه التحديد ، في حالتنا ، يجب Mylib::myfeature
عندما يكون من الضروري libmyfeature
بمكتبة libmyfeature
. إذا كانت هناك رؤوس كافية ، فيجب عليك استخدام مكتبة Mylib::mylib
.
يمكن أن تكون أهداف CMake صعبة ، على سبيل المثال ، مصممة فقط لإعادة توجيه بعض الخصائص والتبعيات وما إلى ذلك. في الوقت نفسه ، يحدث العمل معهم بطريقة واحدة.
ما هو المطلوب لتلقي.