C++ un CMake — mūžīgie brāļi, 2. daļa

C++ un CMake — mūžīgie brāļi, 2. daļa

Iepriekšējā daļā Šajā interesantajā stāstā tika runāts par galvenes bibliotēkas organizāciju CMake sistēmu ģenerātora ietvaros.

Šoreiz pievienosim tai kompilējamu bibliotēku un apspriedīsim moduļu savstarpējo kompozīciju.

Kā jau iepriekš, tie, kuriem nav pacietības, var uzreiz pāriet uz atjaunoto repozitoriju un visu aptaustīt ar savām rokām.


Satelīte

  1. Dalīties
  2. Kaut ko sasniegt

Dalīties

Pirmais, kas jādara, lai sasniegtu mūsu augsto mērķi, ir sadalīt izstrādājamo programmatūru universālos izolētos blokos, kuri ir vienveidīgi lietotāja acīs.

Pirmajā daļā tika aprakstīts tāds standarta bloks — projekts ar galvenes bibliotēku. Tagad pievienosim mūsu projektam kompilējamu bibliotēku.

Tāpēc izvirzīsim funkcijas myfunc īstenojumu atsevišķā .cpp-failā:

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 
+
+namespace mylib
+{
+    bool myfunc (mystruct)
+    {
+        return true;
+    }
+}

Pēc tam noteiksim kompilējamo bibliotēku (myfeature), kas būs sastāvējusi no iepriekšējā solī iegūtā .cpp-faila. Jaunajai bibliotēkai, acīmredzot, nepieciešamas jau esošās galvenes, un lai to nodrošinātu, tai ir jābūt savienotai ar esošo mērķi mylib. Turklāt savienojums starp tām ir publisks, un tas nozīmē, ka viss, kam pievienota mērķis myfeature, automātiski iegūs arī mērķi mylib (vairāk par savienojuma veidiem).

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)

+###################################################################################################
+##
+##      Kompilējama bibliotēka
+##
+###################################################################################################
+
+add_library(myfeature src/mylib/myfeature.cpp)
+target_link_libraries(myfeature PUBLIC mylib)
+
+add_library(Mylib::myfeature ALIAS myfeature)
+

Tālāk darīsim tā, lai jaunā bibliotēka arī tiktu instalēta sistēmā:

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

Jāņem vērā, ka mērķim myfeature, kā arī mylib tika tika ar prefiksu Mylib::. Tas pats ir norādīts abiem mērķiem, eksportējot tos sistēmas uzstādīšanai. Tas nodrošina vienmērīgu darbu ar mērķiem jebkurā saistīšanas shēmā.

Pēc tam palika saistīt moduļu testus ar jauno bibliotēku (funkciju myfunc izņemta no galvenes, tāpēc tagad nepieciešams to saistīt):

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
 )

Galvenes (Mylib::mylib) tagad nav jāiekļauj atsevišķi, jo, kā jau teikts, tās automātiski tiek iekļautas kopā ar bibliotēku (Mylib::myfeature).

Un pievienosim pāris nianses, lai nodrošinātu pārklājuma mērījumus, ņemot vērā jauniegūto bibliotēku:

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

Var pievienot vairāk bibliotēku, izpildāmās failus utt. Svarīgi ir tas, kā tie ir savienoti savā starpā projekta ietvaros. Svarīgi ir tikai tas, kuri mērķi ir mūsu moduļa saskarne, proti, kas ir redzams ārpusē.

Kaut ko sasniegt

Tagad mums ir standarta moduļi-bloki, un mēs varam tiem valdīt: sastāvēt no tiem struktūru jebkādas sarežģītības, uzstādot tos sistēmā vai saistot savā starpā vienotajā būvniecības sistēmā.

Uzstādīšana sistēmā

Viena no moduļa lietošanas iespējām ir uzstādīt mūsu moduli sistēmā.

cmake --build ceļš/uz/būves/mapi --target install

Pēc tam to var iekļaut jebkurā citā projektā ar komandu find_package.

find_package(Mylib 1.0 REQUIRED)

Iekļaušana kā apakšmodulis

Vēl viena iespēja ir pievienot mūsu projekta mapes citiem projektiem kā apakšmoduli ar komandu add_subdirectory.

Izmantošana

Sistēmas saistīšanas veidi atšķiras, taču rezultāts ir viens un tas pats. Gan vienā, gan otrā gadījumā projektā, kas izmanto mūsu moduli, būs pieejami mērķi Mylib::myfeature un Mylib::mylib, kurus var izmantot, piemēram, šādā veidā:

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

Konkrētajā gadījumā bibliotēku Mylib::myfeature jāievieš tikai tad, kad nepieciešams saistīties ar bibliotēku libmyfeature. Ja pietiek ar virsrakstiem, tad ir vērts izmantot bibliotēku Mylib::mylib.

CMake mērķi var būt viltīgi, piemēram, paredzēti tikai īpašību, atkarību u.c. pārnešanai. Tomēr darbs ar tiem notiek vienoti.

Ko arī vajadzēja iegūt.

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster