C++ è CMake - fratelli per sempre, parte II

C++ è CMake - fratelli per sempre, parte II

In a parte precedente Questa storia divertente hà parlatu di l'urganizazione di una biblioteca di header in u generatore di sistema di creazione CMake.

Questa volta aghjunghjemu una biblioteca cumpilata, è parlemu ancu di ligà moduli cù l'altri.

Cum'è prima, quelli chì sò impacienti ponu immediatamente andate à u repositoriu aghjurnatu è toccu tuttu cù e vostre mani.


Cuntenuti

  1. Divide
  2. Cunquistà

Divide

A prima cosa chì avemu bisognu di fà per ghjunghje u nostru altu scopu hè di dividisce u software chì sviluppemu in blocchi universali, isolati chì sò uniformi da u puntu di vista di l'utilizatori.

In a prima parte, un tali bloccu standard hè statu discrittu - un prughjettu cù una biblioteca di header. Avà aghjunghje una biblioteca cumpilata à u nostru prughjettu.

Per fà questu, andemu da l'implementazione di a funzione myfunc in un separatu .cpp-file:

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

Dopu avemu definitu a biblioteca per esse cumpilata (myfeature), chì serà cumpostu di ciò chì hè stata ottenuta in u passu precedente .cpp- schedariu. A nova biblioteca precisa ovviamente intestazioni esistenti, è per furnisce questu, pò è deve esse ligata à u scopu esistente. mylib. Inoltre, a cunnessione trà elli hè publicu, chì significa chì tuttu ciò chì u mira serà cunnessu myfeature, riceverà automaticamente a carica è u mira mylib (più nantu à i metudi di maglia).

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

In seguitu, avemu da assicurà chì a nova biblioteca hè ancu installata in u sistema:

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

Hè da nutà chì per u scopu myfeature, in quantu mylib un alias cù un prefissu hè statu creatu Mylib::. U listessu hè scrittu per i dui scopi quandu l'esporta per a stallazione in u sistema. Questu permette di travaglià uniformemente cù scopi per qualsiasi schema di ligame.

Dopu questu, tuttu ciò chì resta hè di ligà e teste di unità cù a nova biblioteca (funzione myfunc cacciatu da u titulu, dunque avà avete bisognu di ligà):

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
 )

Intestazioni (Mylib::mylib) avà ùn avete micca bisognu di cunnette separatamente, perchè, cum'è digià dettu, sò automaticamente cunnessi cù a biblioteca (Mylib::myfeature).

È aghjunghjemu un paru di sfumature per assicurà e misurazioni di a cobertura tenendu in contu a libreria appena ghjunta:

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

Pudete aghjunghje più librerie, eseguibili, etc. Ùn importa micca quantu esattamente sò cunnessi l'un à l'altru in u prugettu. L'unicu impurtante hè chì i miri sò l'interfaccia di u nostru modulu, vale à dì, si stanu fora.

Cunquistà

Avà avemu moduli di blocchi standard, è pudemu duminà: cumpone in una struttura di ogni cumplessità, installendu in un sistema o ligà inseme in un sistema di assemblea unicu.

Installazione in u sistema

Una di l'opzioni per aduprà u modulu hè di installà u nostru modulu in u sistema.

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

Dopu quì, hè cunnessu à qualsiasi altru prughjettu cù u cumandamentu find_package.

find_package(Mylib 1.0 REQUIRED)

Cunnessione cum'è un submodulu

Un'altra opzione hè di cunnette u cartulare cù u nostru prughjettu à un altru prughjettu cum'è un submodulu cù u cumandimu add_subdirectory.

Usu

I metudi di ubligatoriu sò diffirenti, ma u risultatu hè u listessu. In i dui casi, i scopi seranu dispunibili in u prugettu cù u nostru modulu Mylib::myfeature и Mylib::mylib, chì pò esse usatu, per esempiu, cusì:

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

In particulare in u nostru casu, a biblioteca Mylib::myfeature deve esse cunnessu quandu hè necessariu di ligà cù a biblioteca libmyfeature. Se ci sò abbastanza intestazioni, vale a pena aduprà a biblioteca Mylib::mylib.

I miri CMake ponu esse difficili, per esempiu, destinati solu à rinvià alcune proprietà, dipendenze, etc. À u listessu tempu, u travagliu cun elli si faci in u listessu modu.

Hè ciò chì avemu bisognu di ottene.

Source: www.habr.com

Add a comment