C++ og CMake - brødre for alltid, del II

C++ og CMake - brødre for alltid, del II

I forrige del Denne underholdende historien snakket om å organisere et header-bibliotek i CMake build-systemgeneratoren.

Denne gangen vil vi legge til et kompilert bibliotek til det, og også snakke om å koble moduler med hverandre.

Som før kan de som er utålmodige umiddelbart gå til det oppdaterte depotet og ta på alt med egne hender.


Innhold

  1. Dele opp
  2. Erobre

Dele opp

Det første vi må gjøre for å nå vårt høye mål er å dele opp programvaren vi utvikler i universelle, isolerte blokker som er enhetlige fra brukerens synspunkt.

I den første delen ble en slik standardblokk beskrevet - et prosjekt med et overskriftsbibliotek. La oss nå legge til et kompilert bibliotek til prosjektet vårt.

For å gjøre dette, la oss ta ut implementeringen av funksjonen myfunc i en separat .cpp-fil:

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

Deretter definerer vi biblioteket som skal kompileres (myfeature), som vil bestå av det som ble oppnådd i forrige trinn .cpp-fil. Det nye biblioteket krever åpenbart eksisterende overskrifter, og for å kunne tilby dette kan og bør det knyttes til det eksisterende formålet mylib. Dessuten er forbindelsen mellom dem offentlig, noe som betyr at alt som målet vil være koblet til myfeature, vil automatisk motta lasten og målet mylib (mer om strikkemetoder).

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

Deretter skal vi sørge for at det nye biblioteket også er installert på systemet:

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

Det skal bemerkes at for formålet myfeature, når det gjelder mylib et alias med et prefiks ble opprettet Mylib::. Det samme skrives for begge formål når de eksporteres for installasjon på systemet. Dette gjør det mulig å jobbe enhetlig med mål for evt bindende ordning.

Etter dette gjenstår det bare å koble enhetstester med det nye biblioteket (funksjon myfunc tatt ut av tittelen, så nå må du linke):

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
 )

Overskrifter (Mylib::mylib) nå trenger du ikke koble til separat, fordi, som allerede nevnt, kobles de automatisk sammen med biblioteket (Mylib::myfeature).

Og la oss legge til et par nyanser for å sikre dekningsmålinger som tar hensyn til det nylig ankomne biblioteket:

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

Du kan legge til flere biblioteker, kjørbare filer osv. Det spiller ingen rolle hvor nøyaktig de er knyttet til hverandre innenfor prosjektet. Det eneste viktige er hvilke mål som er grensesnittet til modulen vår, det vil si at de stikker seg ut.

Erobre

Nå har vi standard blokkmoduler, og vi kan dominere dem: komponere dem til en struktur av enhver kompleksitet, installere dem i et system eller koble dem sammen i et enkelt monteringssystem.

Installasjon i systemet

Et av alternativene for å bruke modulen er å installere vår modul i systemet.

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

Etter det kobles den til et hvilket som helst annet prosjekt ved å bruke kommandoen find_package.

find_package(Mylib 1.0 REQUIRED)

Tilkobling som en undermodul

Et annet alternativ er å koble mappen med prosjektet vårt til et annet prosjekt som en undermodul ved å bruke kommandoen add_subdirectory.

Bruk

Bindingsmetodene er forskjellige, men resultatet er det samme. I begge tilfeller vil mål være tilgjengelige i prosjektet ved hjelp av vår modul Mylib::myfeature и Mylib::mylib, som kan brukes for eksempel slik:

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

Spesielt i vårt tilfelle, biblioteket Mylib::myfeature må kobles til når det er nødvendig å koble til biblioteket libmyfeature. Hvis det er nok overskrifter, er det verdt å bruke biblioteket Mylib::mylib.

CMake-mål kan være vanskelige, for eksempel kun ment å videresende enkelte egenskaper, avhengigheter osv. Samtidig skjer arbeidet med dem på samme måte.

Det var det vi trengte å få.

Kilde: www.habr.com

Legg til en kommentar