C++ og CMake - brødre for evigt, del II

C++ og CMake - brødre for evigt, del II

I forrige del Denne underholdende historie talte om at organisere et header-bibliotek i CMake build-systemgeneratoren.

Denne gang vil vi tilføje et kompileret bibliotek til det, og også tale om at forbinde moduler med hinanden.

Som før kan de, der er utålmodige, straks gå til det opdaterede lager og rør ved alt med dine egne hænder.


Indhold

  1. Dele
  2. Erobre

Dele

Det første, vi skal gøre for at nå vores høje mål, er at opdele den software, vi udvikler, i universelle, isolerede blokke, der er ensartede fra brugerens synspunkt.

I den første del blev en sådan standardblok beskrevet - et projekt med et header-bibliotek. Lad os nu tilføje et kompileret bibliotek til vores projekt.

For at gøre dette, lad os tage implementeringen af ​​funktionen ud myfunc i en separat .cpp-fil:

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

Derefter definerer vi det bibliotek, der skal kompileres (myfeature), som vil bestå af det, der blev opnået i det foregående trin .cpp-fil. Det nye bibliotek kræver naturligvis eksisterende headere, og for at kunne levere dette kan og bør det knyttes til det eksisterende formål mylib. Desuden er forbindelsen mellem dem offentlig, hvilket betyder, at alt, som målet vil være forbundet med myfeature, vil automatisk modtage belastningen og målet mylib (mere om strikkemetoder).

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

Dernæst sørger vi for, at det nye bibliotek også er installeret på systemet:

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

Det skal bemærkes, at til formålet myfeature, som for mylib et alias med et præfiks blev oprettet Mylib::. Det samme er skrevet til begge formål, når de eksporteres til installation på systemet. Dette gør det muligt at arbejde ensartet med mål for evt bindende ordning.

Herefter er der kun tilbage at forbinde enhedstest med det nye bibliotek (funktion myfunc taget ud af titlen, så nu skal du linke):

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
 )

Overskrifter (Mylib::mylib) nu behøver du ikke oprette forbindelse separat, for som allerede nævnt forbindes de automatisk sammen med biblioteket (Mylib::myfeature).

Og lad os tilføje et par nuancer for at sikre dækningsmålinger under hensyntagen til det nyligt ankomne bibliotek:

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

Du kan tilføje flere biblioteker, eksekverbare filer osv. Det er lige meget, hvor præcist de er forbundet med hinanden inden for projektet. Det eneste vigtige er, hvilke mål der er grænsefladen for vores modul, det vil sige, de stikker ud.

Erobre

Nu har vi standardblokmoduler, og vi kan dominere dem: sammensætte dem til en struktur af enhver kompleksitet, installere dem i et system eller sammenkæde dem i et enkelt montagesystem.

Installation i systemet

En af mulighederne for at bruge modulet er at installere vores modul i systemet.

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

Derefter er det forbundet til ethvert andet projekt ved hjælp af kommandoen find_package.

find_package(Mylib 1.0 REQUIRED)

Tilslutning som et undermodul

En anden mulighed er at forbinde mappen med vores projekt til et andet projekt som et undermodul ved hjælp af kommandoen add_subdirectory.

Brug

Bindingsmetoderne er forskellige, men resultatet er det samme. I begge tilfælde vil mål være tilgængelige i projektet ved hjælp af vores modul Mylib::myfeature и Mylib::mylib, som for eksempel kan bruges sådan:

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

Specifikt i vores tilfælde, biblioteket Mylib::myfeature skal tilsluttes, når det er nødvendigt at forbinde med biblioteket libmyfeature. Hvis der er nok overskrifter, så er det værd at bruge biblioteket Mylib::mylib.

CMake-mål kan være vanskelige, for eksempel kun beregnet til at videresende nogle egenskaber, afhængigheder osv. Samtidig foregår arbejdet med dem på samme måde.

Det var det, vi skulle have fat i.

Kilde: www.habr.com

Tilføj en kommentar