C++ in CMake - brata za vedno, II.del

C++ in CMake - brata za vedno, II.del

V prejšnjem delu Ta zabavna zgodba je govorila o organiziranju knjižnice glav znotraj generatorja sistema za gradnjo CMake.

Tokrat mu bomo dodali sestavljeno knjižnico, govorili pa bomo tudi o povezovanju modulov med seboj.

Neučakani lahko tako kot doslej takoj pojdite na posodobljeno skladišče in se dotakni vsega z lastnimi rokami.


Vsebina

  1. Razdeli
  2. osvojiti

Razdeli

Prva stvar, ki jo moramo narediti za dosego našega visokega cilja, je razdelitev programske opreme, ki jo razvijamo, na univerzalne, izolirane bloke, ki so enotni z vidika uporabnika.

V prvem delu je bil opisan tak standardni blok - projekt s knjižnico glav. Zdaj pa našemu projektu dodamo prevedeno knjižnico.

Če želite to narediti, odstranimo izvedbo funkcije myfunc v ločenem .cpp-mapa:

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

Nato definiramo knjižnico, ki jo bomo prevedli (myfeature), ki bo sestavljen iz tega, kar je bilo pridobljeno v prejšnjem koraku .cpp-mapa. Nova knjižnica očitno zahteva obstoječe glave in da bi to zagotovila, je lahko in mora biti vezana na obstoječi namen mylib. Poleg tega je povezava med njimi javna, kar pomeni, da je povezano vse, s čimer bo tarča myfeature, bo samodejno prejel obremenitev in cilj mylib (več o načinih pletenja).

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

Nato se bomo prepričali, da je nova knjižnica nameščena tudi v sistemu:

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

Opozoriti je treba, da za namen myfeature, kot za mylib ustvarjen je vzdevek s predpono Mylib::. Pri izvozu za namestitev v sistem je za oba namena napisano enako. To omogoča enotno delo s cilji za vse vezavna shema.

Po tem preostane le še povezovanje testov enot z novo knjižnico (funkcija myfunc vzeto iz naslova, zato morate zdaj povezati):

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
 )

Naslovi (Mylib::mylib) zdaj se vam ni treba posebej povezovati, saj se, kot že omenjeno, samodejno povežejo skupaj s knjižnico (Mylib::myfeature).

In dodamo nekaj odtenkov, da zagotovimo meritve pokritosti ob upoštevanju novo prispele knjižnice:

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

Dodate lahko več knjižnic, izvedljivih datotek itd. Ni pomembno, kako natančno so med seboj povezani znotraj projekta. Pomembno je le, katere tarče so vmesnik našega modula, torej štrlijo.

osvojiti

Zdaj imamo standardne blokovne module in nad njimi lahko dominiramo: sestavimo jih v strukturo poljubne kompleksnosti, jih vgradimo v sistem ali jih povežemo v en sam montažni sistem.

Namestitev v sistem

Ena izmed možnosti uporabe modula je tudi namestitev našega modula v sistem.

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

Po tem se z ukazom poveže s katerim koli drugim projektom find_package.

find_package(Mylib 1.0 REQUIRED)

Priključek kot podmodul

Druga možnost je povezava mape z našim projektom z drugim projektom kot podmodul z ukazom add_subdirectory.

Uporaba

Načini vezave so različni, rezultat pa je enak. V obeh primerih bodo cilji na voljo v projektu z uporabo našega modula Mylib::myfeature и Mylib::mylib, ki se lahko uporablja na primer takole:

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

Konkretno v našem primeru knjižnica Mylib::myfeature morajo biti povezani, ko se je treba povezati s knjižnico libmyfeature. Če je dovolj glav, potem je vredno uporabiti knjižnico Mylib::mylib.

Cilji CMake so lahko zapleteni, na primer namenjeni le posredovanju nekaterih lastnosti, odvisnosti itd. Hkrati se delo z njimi odvija na enak način.

To smo morali dobiti.

Vir: www.habr.com

Dodaj komentar