C++ en CMake - broers vir altyd, deel II

C++ en CMake - broers vir altyd, deel II

In die vorige deel Hierdie vermaaklike storie het gepraat oor die organisering van 'n kopbiblioteek binne die CMake-boustelselgenerator.

Hierdie keer sal ons 'n saamgestelde biblioteek daarby voeg, en ook praat oor die skakel van modules met mekaar.

Soos voorheen kan diegene wat ongeduldig is dadelik gaan na die opgedateerde bewaarplek en raak alles met jou eie hande aan.


inhoud

  1. Verdeel
  2. Oorwin

Verdeel

Die eerste ding wat ons moet doen om ons verhewe doel te bereik, is om die sagteware wat ons ontwikkel in universele, geΓ―soleerde blokke te verdeel wat eenvormig is vanuit die gebruiker se oogpunt.

In die eerste deel is so 'n standaardblok beskryf - 'n projek met 'n kopbiblioteek. Kom ons voeg nou 'n saamgestelde biblioteek by ons projek.

Om dit te doen, laat ons die implementering van die funksie uitneem myfunc in 'n aparte .cpp-lΓͺer:

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

Dan definieer ons die biblioteek wat saamgestel moet word (myfeature), wat sal bestaan ​​uit wat in die vorige stap verkry is .cpp-lΓͺer. Die nuwe biblioteek benodig natuurlik bestaande opskrifte, en om dit te voorsien, kan en moet dit gekoppel word aan die bestaande doel mylib. Boonop is die verband tussen hulle publiek, wat beteken dat alles waaraan die teiken gekoppel sal wees myfeature, sal outomaties die vrag en teiken ontvang mylib (meer oor breimetodes).

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

Vervolgens sal ons seker maak dat die nuwe biblioteek ook op die stelsel geΓ―nstalleer is:

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

Daar moet kennis geneem word dat vir die doel myfeature, wat betref mylib 'n alias met 'n voorvoegsel is geskep Mylib::. Dieselfde word vir beide doeleindes geskryf wanneer dit uitgevoer word vir installasie op die stelsel. Dit maak dit moontlik om eenvormig te werk met doelwitte vir enige bindende skema.

Hierna is al wat oorbly om eenheidstoetse met die nuwe biblioteek (funksie myfunc uit die titel gehaal, so nou moet jy skakel):

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
 )

Opskrifte (Mylib::mylib) nou hoef jy nie afsonderlik te koppel nie, want, soos reeds genoem, word hulle outomaties saam met die biblioteek gekoppel (Mylib::myfeature).

En kom ons voeg 'n paar nuanses by om dekkingsmetings te verseker met inagneming van die nuut aangekome biblioteek:

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

Jy kan meer biblioteke, uitvoerbare, ens. Dit maak nie saak hoe presies hulle binne die projek met mekaar verbind is nie. Die enigste belangrike ding is watter teikens die koppelvlak van ons module is, dit wil sΓͺ, hulle steek uit.

Oorwin

Nou het ons standaardblokmodules, en ons kan dit oorheers: dit saamstel in 'n struktuur van enige kompleksiteit, installeer dit in 'n stelsel of koppel hulle saam binne 'n enkele samestellingstelsel.

Installasie in die stelsel

Een van die opsies vir die gebruik van die module is om ons module in die stelsel te installeer.

cmake --build ΠΏΡƒΡ‚ΡŒ/ΠΊ/сборочной/Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ --target install

Daarna word dit aan enige ander projek gekoppel deur die opdrag te gebruik find_package.

find_package(Mylib 1.0 REQUIRED)

Verbinding as 'n submodule

Nog 'n opsie is om die gids met ons projek aan 'n ander projek te koppel as 'n submodule deur die opdrag te gebruik add_subdirectory.

Gebruik

Die bindmetodes verskil, maar die resultaat is dieselfde. In beide gevalle sal doelwitte beskikbaar wees in die projek deur ons module te gebruik Mylib::myfeature ΠΈ Mylib::mylib, wat byvoorbeeld soos volg gebruik kan word:

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

Spesifiek in ons geval, die biblioteek Mylib::myfeature moet gekoppel word wanneer dit nodig is om met die biblioteek te skakel libmyfeature. As daar genoeg opskrifte is, is dit die moeite werd om die biblioteek te gebruik Mylib::mylib.

CMake-teikens kan moeilik wees, byvoorbeeld, slegs bedoel om sekere eienskappe, afhanklikhede, ens. Terselfdertyd vind werk met hulle op dieselfde manier plaas.

Dit is wat ons moes kry.

Bron: will.com

Voeg 'n opmerking