C++ és CMake - testvérek örökké, II

C++ és CMake - testvérek örökké, II

Az előző részben Ez a szórakoztató történet egy fejléckönyvtár megszervezéséről szólt a CMake build rendszergenerátoron belül.

Ezúttal egy összeállított könyvtárat adunk hozzá, és szó lesz a modulok összekapcsolásáról is.

Mint korábban, a türelmetlenek azonnal megtehetik lépjen a frissített adattárba és a saját kezével érintsen meg mindent.


Tartalom

  1. Feloszt
  2. Meghódítani

Feloszt

Magasztos célunk eléréséhez az első dolog, hogy az általunk fejlesztett szoftvert univerzális, izolált, a felhasználó szempontjából egységes blokkokra osszuk.

Az első részben egy ilyen szabványos blokkot írtak le - egy projektet fejléckönyvtárral. Most adjunk hozzá egy összeállított könyvtárat a projektünkhöz.

Ehhez vegyük ki a függvény megvalósítását myfunc egy különállóban .cpp-fájl:

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

Ezután meghatározzuk a lefordítandó könyvtárat (myfeature), amely az előző lépésben kapott adatokból fog állni .cpp- fájl. Az új könyvtár nyilvánvalóan meglévő fejléceket igényel, és ennek biztosításához kötni lehet és kell a meglévő célhoz mylib. Ráadásul a köztük lévő kapcsolat nyilvános, ami azt jelenti, hogy minden, amihez a célpont kapcsolódik myfeature, automatikusan megkapja a terhelést és a célt mylib (bővebben a kötési módokról).

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

Ezután megbizonyosodunk arról, hogy az új könyvtár is telepítve van a rendszeren:

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

Meg kell jegyezni, hogy a cél érdekében myfeature, ami azt illeti mylib előtaggal ellátott alias jött létre Mylib::. Ugyanezt írják mindkét célra, amikor exportálják őket a rendszerre történő telepítéshez. Ez lehetővé teszi, hogy bármilyen céllal egységesen dolgozzunk kötelező érvényű séma.

Ezek után már csak az egységteszteket kell összekapcsolni az új könyvtárral (függvény myfunc kikerült a címből, ezért most linkelni kell):

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
 )

Címsorok (Mylib::mylib) most nem kell külön csatlakozni, mert mint már említettük, automatikusan kapcsolódnak a könyvtárral együtt (Mylib::myfeature).

És adjunk hozzá néhány árnyalatot, hogy biztosítsuk a lefedettség mérését, figyelembe véve az újonnan érkezett könyvtárat:

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

Hozzáadhat több könyvtárat, végrehajtható fájlt stb. Nem mindegy, hogy pontosan hogyan kapcsolódnak egymáshoz a projekten belül. Csak az a fontos, hogy mely célpontok képezik a modulunk felületét, vagyis kilógnak.

Meghódítani

Most már szabványos blokkmoduljaink vannak, és uralni tudjuk őket: tetszőleges bonyolultságú szerkezetté alakíthatjuk, rendszerbe építhetjük, vagy egyetlen összeállítási rendszeren belül összekapcsolhatjuk őket.

Telepítés a rendszerbe

A modul használatának egyik lehetősége, hogy a modulunkat telepítjük a rendszerbe.

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

Ezt követően a paranccsal csatlakozik bármely másik projekthez find_package.

find_package(Mylib 1.0 REQUIRED)

Csatlakozás almodulként

Egy másik lehetőség, hogy a projektünkkel rendelkező mappát a paranccsal egy másik projekthez kapcsoljuk almodulként add_subdirectory.

Használat

A kötési módszerek eltérőek, de az eredmény ugyanaz. A célok mindkét esetben elérhetőek lesznek a projektben a modulunk segítségével Mylib::myfeature и Mylib::mylib, amely például így használható:

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

Konkrétan a mi esetünkben a könyvtár Mylib::myfeature csatlakoztatni kell, ha a könyvtárhoz kell kapcsolni libmyfeature. Ha van elég fejléc, akkor érdemes a könyvtárat használni Mylib::mylib.

A CMake célok trükkösek lehetnek, például csak bizonyos tulajdonságok, függőségek stb. továbbítására szolgálnak. Ugyanakkor a velük való munka ugyanúgy történik.

Ez az, amit meg kellett szereznünk.

Forrás: will.com

Hozzászólás