C++ a CMake — bratia navždy, časť II

C++ a CMake — bratia navždy, časť II

V predchádzajúcej časti tohto zaujímavého príbehu sa hovorilo o organizácii hlavičkovej knižnice v rámci generátora systémov zostavovania CMake.

Tentokrát pridáme k nemu kompilovateľnú knižnicu a zároveň sa porozprávame o prepojení modulov medzi sebou.

Ako vždy, tí, ktorí sa nemôžu dočkať, môžu okamžite prejsť do aktualizovaného repozitára a všetko si vyskúšať na vlastnej koži.


Obsah

  1. Rozdeľuj
  2. Panuj

Rozdeľuj

Prvá vec, ktorú musíme urobiť na dosiahnutie našich vysokých cieľov, je rozdeliť vyvíjaný softvér na univerzálne izolované bloky, ktoré sú z pohľadu používateľa jednotné.

V prvej časti bol opísaný takýto štandardný blok – projekt s hlavičkovou knižnicou. Teraz pridáme do nášho projektu kompilovateľnú knižnicu.

Na to presunieme implementáciu funkcie myfunc do samostatného .cpp-súboru:

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

Potom definujeme kompilovateľnú knižnicu (myfeature), ktorá sa bude skladať z predchádzajúceho .cpp-súboru. Novej knižnici, samozrejme, vznikajú už existujúce hlavičky a na to, aby to bolo zabezpečené, je potrebné ju prepojiť s existujúcou cieľovosťou mylib. Prepojenie medzi nimi je verejné, čo znamená, že všetko, k čomu sa pripojí cieľ myfeature, automaticky získa aj cieľ mylib (podrobnejšie o spôsoboch prepojenia).

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)

+###################################################################################################
+##
+##      Kompilovateľná knižnica
+##
+###################################################################################################
+
+add_library(myfeature src/mylib/myfeature.cpp)
+target_link_libraries(myfeature PUBLIC mylib)
+
+add_library(Mylib::myfeature ALIAS myfeature)
+

Ďalej zabezpečíme, aby sa nová knižnica tiež inštalovala do systému:

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

Je potrebné venovať pozornosť tomu, že pre cieľ myfeature, ako aj pre mylib bol zadaný pseudonym s prefixom Mylib::. To isté je zadané pre oba účely pri exporte na inštaláciu do systému. To umožňuje jednotnú prácu s cieľmi pri akejkoľvek schéme prepojenia.

Po tomto zostáva prepojiť modulové testy s novou knižnicou (funkcia myfunc bola presunutá z hlavičky, takže ju teraz treba prepojiť):

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
 )

Hlavičky (Mylib::mylib) teraz nie je potrebné pripojiť osobitne, pretože, ako už bolo povedané, sú automaticky pripojené spolu s knižnicou (Mylib::myfeature).

A pridáme pár nuáns, aby sme zabezpečili merania pokrytia s ohľadom na novopridanú knižnicu:

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

Môžeme pridať viac knižníc, spustiteľné súbory atď. Pri tom nezáleží na tom, ako sú presne prepojené medzi sebou v rámci projektu. Dôležité je len to, ktoré ciele sú rozhraním nášho modulu, teda vystupujú von.

Panuj

Teraz máme štandardné modulárne bloky, a môžeme nad nimi vládnuť: skladať z nich štruktúru akýchkoľvek komplikovaností, inštalovať ich do systému alebo prepojiť medzi sebou v rámci jedného systému zostavovania.

Inštalácia do systému

Jednou z možností použitia modulu je nainštalovať náš modul do systému.

cmake --build cesta/k/zostavovacej/directory --target install

Potom sa pripojí v akomkoľvek inom projekte pomocou príkazu find_package.

find_package(Mylib 1.0 REQUIRED)

Pripojenie ako podmodul

Ďalšou možnosťou je pripojenie priečinka s naším projektom k inému projektu ako podmodulu pomocou príkazu add_subdirectory.

Použitie

Spôsoby prepojenia sú rôzne, ale výsledok je rovnaký. V oboch prípadoch budú ciele dostupné v projekte, ktorý používa náš modul. Mylib::myfeature a Mylib::mylib, ktoré je možné použiť napríklad takto:

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

Konkrétne v našom prípade treba použiť knižnicu Mylib::myfeature , keď je potrebné zlinkovať s knižnicou libmyfeature. Ak sú dostatočné hlavičky, je lepšie použiť knižnicu Mylib::mylib.

CMake ciele môžu byť komplikované, napríklad určené len na to, aby preposielali určité vlastnosti, závislosti atď. Práca s nimi prebieha jednotným spôsobom.

Čo sa a vyžadovalo získať.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster