C++ dhe CMake - vëllezër përgjithmonë, pjesa II

C++ dhe CMake - vëllezër përgjithmonë, pjesa II

Në pjesën e mëparshme Kjo histori argëtuese foli për organizimin e një biblioteke me kokë brenda gjeneratorit të sistemit të ndërtimit CMake.

Këtë herë do t'i shtojmë një bibliotekë të përpiluar, dhe gjithashtu do të flasim për lidhjen e moduleve me njëri-tjetrin.

Si më parë, ata që janë të padurueshëm munden menjëherë shkoni te depoja e përditësuar dhe prekni gjithçka me duart tuaja.


Përmbajtje

  1. Ndani
  2. Pushtoni

Ndani

Gjëja e parë që duhet të bëjmë për të arritur qëllimin tonë të lartë është të ndajmë softuerin që zhvillojmë në blloqe universale, të izoluara që janë uniforme nga këndvështrimi i përdoruesit.

Në pjesën e parë, u përshkrua një bllok i tillë standard - një projekt me një bibliotekë me kokë. Tani le të shtojmë një bibliotekë të përpiluar në projektin tonë.

Për ta bërë këtë, le të heqim zbatimin e funksionit myfunc në një të veçantë .cpp-skedari:

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;
+    }
+}

Më pas përcaktojmë bibliotekën që do të përpilohet (myfeature), i cili do të përbëhet nga ajo që është marrë në hapin e mëparshëm .cpp- dosje. Biblioteka e re padyshim kërkon tituj ekzistues, dhe për ta siguruar këtë, ajo mund dhe duhet të lidhet me qëllimin ekzistues mylib. Për më tepër, lidhja mes tyre është publike, që do të thotë se gjithçka me të cilën objektivi do të lidhet myfeature, do të marrë automatikisht ngarkesën dhe objektivin mylib (më shumë rreth metodave të thurjes).

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)
+

Më pas, do të sigurohemi që biblioteka e re të jetë gjithashtu e instaluar në sistem:

@@ -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)

Duhet theksuar se për qëllimin myfeature, sa për mylib u krijua një pseudonim me një parashtesë Mylib::. E njëjta gjë shkruhet për të dy qëllimet kur i eksportoni për instalim në sistem. Kjo bën të mundur që të punohet në mënyrë uniforme me qëllimet për cilindo skemë detyruese.

Pas kësaj, gjithçka që mbetet është të lidhni testet e njësive me bibliotekën e re (funksioni myfunc është hequr nga titulli, kështu që tani duhet të lidhni):

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
 )

Titujt (Mylib::mylib) tani nuk keni nevojë të lidheni veçmas, sepse, siç u përmend tashmë, ato lidhen automatikisht së bashku me bibliotekën (Mylib::myfeature).

Dhe le të shtojmë disa nuanca për të siguruar matjet e mbulimit duke marrë parasysh bibliotekën e sapoardhur:

@@ -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
     )

Mund të shtoni më shumë biblioteka, ekzekutues, etj. Nuk ka rëndësi se sa saktësisht janë të lidhura me njëri-tjetrin brenda projektit. E vetmja gjë e rëndësishme është se cilat objektiva janë ndërfaqja e modulit tonë, domethënë ato qëndrojnë jashtë.

Pushtoni

Tani ne kemi module standarde të bllokut dhe mund t'i dominojmë ato: t'i kompozojmë në një strukturë të çdo kompleksiteti, duke i instaluar në një sistem ose duke i lidhur ato së bashku brenda një sistemi të vetëm montimi.

Instalimi në sistem

Një nga opsionet për përdorimin e modulit është instalimi i modulit tonë në sistem.

cmake --build путь/к/сборочной/директории --target install

Pas kësaj, ai lidhet me çdo projekt tjetër duke përdorur komandën find_package.

find_package(Mylib 1.0 REQUIRED)

Lidhja si nënmodul

Një tjetër mundësi është të lidhni dosjen me projektin tonë me një projekt tjetër si nënmodul duke përdorur komandën add_subdirectory.

Përdorim

Metodat e lidhjes janë të ndryshme, por rezultati është i njëjtë. Në të dyja rastet, qëllimet do të jenë të disponueshme në projekt duke përdorur modulin tonë Mylib::myfeature и Mylib::mylib, e cila mund të përdoret, për shembull, si kjo:

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

Konkretisht në rastin tonë, biblioteka Mylib::myfeature duhet të lidhen kur është e nevojshme të lidheni me bibliotekën libmyfeature. Nëse ka mjaft tituj, atëherë ia vlen të përdorni bibliotekën Mylib::mylib.

Objektivat CMake mund të jenë të ndërlikuara, për shembull, të destinuara vetëm për të përcjellë disa veti, varësi, etj. Në të njëjtën kohë, puna me ta ndodh në të njëjtën mënyrë.

Kjo është ajo që na duhej të merrnim.

Burimi: www.habr.com

Shto një koment