C++ اور CMake - بھائی ہمیشہ کے لیے، حصہ II

C++ اور CMake - بھائی ہمیشہ کے لیے، حصہ II

پچھلے حصے میں اس دل لگی کہانی نے CMake بلڈ سسٹم جنریٹر کے اندر ہیڈر لائبریری کو منظم کرنے کے بارے میں بات کی۔

اس بار ہم اس میں ایک مرتب شدہ لائبریری کا اضافہ کریں گے، اور ماڈیولز کو ایک دوسرے سے جوڑنے کے بارے میں بھی بات کریں گے۔

پہلے کی طرح جو لوگ بے صبرے ہیں وہ فوراً کر سکتے ہیں۔ اپ ڈیٹ شدہ ذخیرہ پر جائیں۔ اور ہر چیز کو اپنے ہاتھوں سے چھوئے۔


مواد

  1. تقسیم کرنا
  2. فتح

تقسیم کرنا

اپنے بلند مقصد کو حاصل کرنے کے لیے ہمیں سب سے پہلے جو کام کرنے کی ضرورت ہے وہ یہ ہے کہ ہم جو سافٹ ویئر تیار کرتے ہیں اسے آفاقی، الگ تھلگ بلاکس میں تقسیم کرنا ہے جو صارف کے نقطہ نظر سے یکساں ہیں۔

پہلے حصے میں، اس طرح کے ایک معیاری بلاک کو بیان کیا گیا تھا - ایک ہیڈر لائبریری کے ساتھ ایک پروجیکٹ۔ اب ہم اپنے پروجیکٹ میں ایک مرتب شدہ لائبریری شامل کرتے ہیں۔

ایسا کرنے کے لیے، آئیے فنکشن کا نفاذ کرتے ہیں۔ 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. اس کے علاوہ، ان کے درمیان کنکشن عوامی ہے، جس کا مطلب یہ ہے کہ ہر چیز جس سے ہدف کو منسلک کیا جائے گا 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 ایک سابقہ ​​کے ساتھ ایک عرف بنایا گیا تھا۔ Mylib::. سسٹم پر انسٹالیشن کے لیے برآمد کرتے وقت دونوں مقاصد کے لیے ایک ہی لکھا جاتا ہے۔ اس سے کسی کے لیے اہداف کے ساتھ یکساں طور پر کام کرنا ممکن ہو جاتا ہے۔ پابند سکیم.

اس کے بعد، جو باقی رہ جاتا ہے وہ یونٹ ٹیسٹوں کو نئی لائبریری (فنکشن 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.

استعمال کریں

پابند کرنے کے طریقے مختلف ہیں، لیکن نتیجہ ایک ہی ہے۔ دونوں صورتوں میں، ہمارے ماڈیول کا استعمال کرتے ہوئے پروجیکٹ میں اہداف دستیاب ہوں گے۔ Mylib::myfeature и Mylib::mylib، جو استعمال کیا جا سکتا ہے، مثال کے طور پر، اس طرح:

add_executable(some_executable some.cpp sources.cpp)
target_link_libraries(some_executable PRIVATE Mylib::myfeature)

خاص طور پر ہمارے معاملے میں، لائبریری Mylib::myfeature جب لائبریری کے ساتھ لنک کرنا ضروری ہو تو منسلک ہونے کی ضرورت ہے۔ libmyfeature. اگر کافی ہیڈر ہیں، تو یہ لائبریری کا استعمال کرنے کے قابل ہے Mylib::mylib.

CMake کے اہداف مشکل ہو سکتے ہیں، مثال کے طور پر، صرف کچھ پراپرٹیز، انحصار وغیرہ کو آگے بڑھانا ہے۔ ایک ہی وقت میں، ان کے ساتھ کام کرنا اسی طرح ہوتا ہے.

ہمیں حاصل کرنے کی یہی ضرورت تھی۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں