C++ i CMake - braća zauvijek, II dio

C++ i CMake - braća zauvijek, II dio

U prethodnom dijelu Ova zabavna priča govorila je o organizovanju biblioteke zaglavlja unutar CMake build sistema generatora.

Ovog puta ćemo mu dodati kompajliranu biblioteku, a također ćemo govoriti o međusobnom povezivanju modula.

Kao i do sada, oni koji su nestrpljivi mogu odmah idite na ažurirano spremište i dotakni sve svojim rukama.


Sadržaj

  1. Podijelite
  2. Conquer

Podijelite

Prva stvar koju trebamo učiniti da bismo postigli naš visoki cilj je podijeliti softver koji razvijamo u univerzalne, izolovane blokove koji su ujednačeni sa stanovišta korisnika.

U prvom dijelu je opisan takav standardni blok - projekat sa bibliotekom zaglavlja. Sada dodajmo kompajliranu biblioteku našem projektu.

Da bismo to učinili, uzmimo implementaciju funkcije myfunc u posebnom .cpp-fajl:

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

Zatim definiramo biblioteku koja će se kompajlirati (myfeature), koji će se sastojati od onoga što je dobijeno u prethodnom koraku .cpp-file. Nova biblioteka očito zahtijeva postojeća zaglavlja, a da bi to obezbijedila, može i treba biti vezana za postojeću svrhu mylib. Štaviše, veza između njih je javna, što znači da će sve na šta cilj biti povezan myfeature, automatski će primiti opterećenje i cilj mylib (više o metodama 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)
+

Zatim ćemo se pobrinuti da je nova biblioteka također instalirana na 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)

Treba napomenuti da u tu svrhu myfeature, kao za mylib stvoren je pseudonim sa prefiksom Mylib::. Isto je napisano za obje svrhe kada ih izvozite za instalaciju na sistem. Ovo omogućava da se radi ujednačeno sa ciljevima za sve shema vezivanja.

Nakon ovoga, sve što ostaje je povezati jedinične testove s novom bibliotekom (funkcija myfunc izvučeno iz naslova, pa sad treba link):

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) sada se ne morate posebno povezivati, jer se, kao što je već spomenuto, automatski povezuju zajedno sa bibliotekom (Mylib::myfeature).

I dodajmo nekoliko nijansi kako bismo osigurali mjerenje pokrivenosti uzimajući u obzir novopristiglu biblioteku:

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

Možete dodati još biblioteka, izvršnih datoteka itd. Nije važno koliko su tačno međusobno povezani unutar projekta. Bitno je samo koje su mete sučelje našeg modula, odnosno strše.

Conquer

Sada imamo standardne blok module i možemo njima dominirati: komponovati ih u strukturu bilo koje složenosti, instalirati ih u sistem ili ih povezati zajedno u okviru jednog montažnog sistema.

Instalacija u sistem

Jedna od opcija za korištenje modula je ugradnja našeg modula u sistem.

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

Nakon toga se povezuje sa bilo kojim drugim projektom pomoću naredbe find_package.

find_package(Mylib 1.0 REQUIRED)

Veza kao podmodul

Druga opcija je da povežete fasciklu sa našim projektom na drugi projekat kao podmodul pomoću naredbe add_subdirectory.

Koristite

Metode vezivanja su različite, ali je rezultat isti. U oba slučaja, ciljevi će biti dostupni u projektu pomoću našeg modula Mylib::myfeature и Mylib::mylib, koji se može koristiti, na primjer, ovako:

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

Konkretno u našem slučaju, biblioteka Mylib::myfeature potrebno je povezati kada je potrebno povezati se s bibliotekom libmyfeature. Ako ima dovoljno zaglavlja, onda je vrijedno koristiti biblioteku Mylib::mylib.

CMake ciljevi mogu biti lukavi, na primjer, namijenjeni samo za prosljeđivanje nekih svojstava, zavisnosti itd. Istovremeno, rad s njima odvija se na isti način.

To je ono što smo trebali dobiti.

izvor: www.habr.com

Dodajte komentar