C++ a CMake - bratři navždy, část II

C++ a CMake - bratři navždy, část II

V předchozí části Tento zábavný příběh hovořil o uspořádání knihovny záhlaví v generátoru systému sestavení CMake.

Tentokrát k ní přidáme zkompilovanou knihovnu a také si povíme o propojení modulů mezi sebou.

Stejně jako dříve, netrpěliví mohou okamžitě přejděte do aktualizovaného úložiště a dotknout se všeho vlastníma rukama.


Obsah

  1. Rozdělit
  2. Dobýt

Rozdělit

První věc, kterou musíme udělat, abychom dosáhli našeho vysokého cíle, je rozdělit námi vyvíjený software do univerzálních, izolovaných bloků, které jsou jednotné z pohledu uživatele.

V první části byl popsán takový standardní blok - projekt s knihovnou hlaviček. Nyní do našeho projektu přidáme zkompilovanou knihovnu.

Abychom to udělali, vynecháme implementaci funkce myfunc v odděleném .cpp-soubor:

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

Poté definujeme knihovnu, která se má zkompilovat (myfeature), který se bude skládat z toho, co bylo získáno v předchozím kroku .cpp-soubor. Nová knihovna samozřejmě vyžaduje existující hlavičky, a aby to mohla poskytovat, může a měla by být svázána se stávajícím účelem mylib. Spojení mezi nimi je navíc veřejné, což znamená, že vše, k čemu bude připojen cíl myfeature, automaticky obdrží zátěž a cíl mylib (více o metodách pletení).

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

Dále se ujistíme, že nová knihovna je také nainstalována v 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)

Nutno podotknout, že za účelem myfeature, pokud jde o mylib byl vytvořen alias s předponou Mylib::. Totéž se zapisuje pro oba účely při jejich exportu pro instalaci do systému. To umožňuje jednotně pracovat s cíli pro libovolné závazné schéma.

Poté zbývá pouze propojit testy jednotek s novou knihovnou (funkce myfunc vyjmuto z názvu, takže nyní musíte propojit):

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
 )

nadpisy (Mylib::mylib) nyní se nemusíte připojovat samostatně, protože, jak již bylo zmíněno, jsou automaticky připojeny spolu s knihovnou (Mylib::myfeature).

A přidáme několik nuancí, abychom zajistili měření pokrytí s přihlédnutím k nově příchozí knihovně:

@@ -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ůžete přidat další knihovny, spustitelné soubory atd. Nezáleží na tom, jak přesně jsou vzájemně propojeny v rámci projektu. Důležité je pouze to, které cíle jsou rozhraním našeho modulu, tedy vyčnívají.

Dobýt

Nyní máme standardní blokové moduly a můžeme jim dominovat: skládat je do libovolně složité struktury, instalovat je do systému nebo je propojovat v rámci jediného montážního systému.

Instalace do systému

Jednou z možností využití modulu je instalace našeho modulu do systému.

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

Poté se pomocí příkazu připojí k jakémukoli jinému projektu find_package.

find_package(Mylib 1.0 REQUIRED)

Připojení jako submodul

Další možností je propojit složku s naším projektem s jiným projektem jako submodul pomocí příkazu add_subdirectory.

Použití

Způsoby vázání jsou různé, ale výsledek je stejný. V obou případech budou cíle dostupné v projektu pomocí našeho modulu Mylib::myfeature и Mylib::mylib, který lze použít například takto:

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

Konkrétně v našem případě knihovna Mylib::myfeature musí být připojen, když je nutné propojit s knihovnou libmyfeature. Pokud je dostatek hlaviček, pak se vyplatí knihovnu použít Mylib::mylib.

Cíle CMake mohou být složité, například určené pouze k předávání některých vlastností, závislostí atd. Práce s nimi přitom probíhá stejným způsobem.

To jsme potřebovali získat.

Zdroj: www.habr.com

Přidat komentář