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

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

V předchozí části V tomto zajímavém příběhu se hovoří o organizaci hlavičkové knihovny v rámci systému pro sestavování CMake.

Tentokrát přidáme kompilovatelnou knihovnu a také si promluvíme o propojení modulů mezi sebou.

Jak již bylo zmíněno, ti, kdo se nemohou dočkat, mohou ihned přejít do aktualizovaného repozitáře a vyzkoušet si to na vlastní kůži.


Obsah

  1. Rozdělej
  2. Paní

Rozdělej

První věc, kterou je třeba udělat pro dosažení našeho vysokého cíle, je rozdělit vyvíjený software na univerzální izolované bloky, které jsou jednotné z uživatelského hlediska.

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

Za tímto účelem oddělíme implementaci funkce myfunc do samostatného .cpp-souboru:

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

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

Pak definujeme kompilovatelnou knihovnu (myfeature), která se bude skládat ze souboru vytvořeného v předchozím kroku. Nové knihovně jsou, očividně, potřebné již existující hlavičky, a proto je nutné ji propojit s existující cílovou knihovnou .cppmylib . Propojení mezi nimi je veřejné, což znamená, že vše, co bude k cíli připojeno, automaticky získá také cílovou knihovnu.podrobněji o způsobech propojení myfeaturediff --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)+################################################################################################### +## +## Kompilovatelná knihovna +## +################################################################################################### + +add_library(myfeature src/mylib/myfeature.cpp) +target_link_libraries(myfeature PUBLIC mylib) + +add_library(Mylib::myfeature ALIAS myfeature) + . Propojení mezi nimi je veřejné, což znamená, že vše, co bude k cíli připojeno, automaticky získá také cílovou knihovnu. (Dále zajistíme, aby se nová knihovna také nainstalovala 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 třeba si uvědomit, že pro cílovou knihovnu

, stejně jako pro

Нужно обратить внимание, что для цели myfeature, как и для . Propojení mezi nimi je veřejné, což znamená, že vše, co bude k cíli připojeno, automaticky získá také cílovou knihovnu. byl zaveden pseudonym s prefixem Mylib::. Totéž je napsáno pro oba účely při exportování jejich pro instalaci v systému. To poskytuje možnost jednotné práce s cíli při jakékoli schémě propojení.

Po tom zbývá propojit modulární testy s novou knihovnou (funkci myfunc vynesli z hlavičky, takže nyní je třeba linkovat):

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) nyní není třeba připojovat zvlášť, protože, jak už bylo řečeno, jsou automaticky připojeny spolu s knihovnou (Mylib::myfeature).

A přidáme pár nuancí, abychom zajistili měření pokrytí s ohledem na nově příchozí knihovnu:

@@ -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 přidat více knihoven, spustitelných souborů atd. Přitom nezáleží na tom, jak přesně jsou mezi sebou propojeny v rámci projektu. Důležité je pouze to, které cíle jsou rozhraním našeho modulu, tedy vyčnívají ven.

Paní

Nyní máme standardní modulární bloky a můžeme s nimi vládnout: sestavit z nich strukturu jakékoli složitosti, instalovat je do systému nebo je mezi sebou propojovat v rámci jediné buildovací struktury.

Instalace do systému

Jedna z možností použití modulu — nainstalovat náš modul do systému.

cmake --build cesta/k/build/adresáři --target install

Poté se připojí v jakémkoli jiném projektu pomocí příkazu find_package.

find_package(Mylib 1.0 REQUIRED)

Připojení jako podmodul

Další možností je připojit složku s naším projektem k jinému projektu jako podmodul pomocí příkazu add_subdirectory.

Použití

Způsoby propojení jsou různé, ale výsledek je stejný. A v obou případech budou v projektu, který používá náš modul, k dispozici cíle Mylib::myfeature a Mylib::mylib, které mohou být použity například takto:

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

V našem konkrétním případě je třeba knihovnu Mylib::myfeature připojit pouze tehdy, když je nutné se s knihovnou propojit libmyfeature. Pokud stačí hlavičkové soubory, pak by bylo lepší použít knihovnu Mylib::mylib.

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

Což bylo požadováno.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster