C++ och CMake — bröder för alltid, del II

C++ och CMake — bröder för alltid, del II

I den föregÄende delen av denna underhÄllande berÀttelse talades det om organisationen av en header-bibliotek inom ramen för CMake-byggsystemet.

Denna gÄng lÀgger vi till ett kompilera-bibliotek, och pratar om hur moduler ska kopplas samman.

Som tidigare, för de som inte kan vÀnta, kan ni omedelbart gÄ till det uppdaterade arkivet och utforska allt med egna hÀnder.


InnehÄll

  1. Dela
  2. HĂ€rska

Dela

Det första steget för att nÄ vÄrt höga mÄl Àr att dela den utvecklade mjukvaran i universella isolerade block, som Àr enhetliga sett ur anvÀndarens perspektiv.

I den första delen beskrev vi en sÄdan standardblock - ett projekt med en header-bibliotek. Nu lÀgger vi till ett kompilera-bibliotek i vÄrt projekt.

För detta kommer vi att flytta implementeringen av funktionen myfunc till 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 
+
+namespace mylib
+{
+    bool myfunc (mystruct)
+    {
+        return true;
+    }
+}

DÀrefter definierar vi kompilera-biblioteket (myfeature), som kommer att bestÄ av den fil som ficks frÄn föregÄende steg. .cppDet nya biblioteket behöver uppenbarligen redan existerande headers, och för att tillhandahÄlla detta kan och bör vi koppla det till den befintliga mÄlet mylib. Kopplingen mellan dem Àr offentlig, vilket innebÀr att allt som kopplas till mÄlet myfeature, automatiskt kommer att fÄ med sig den mÄlet mylib (lÀs mer om kopplingsmetoder).

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)

+###################################################################################################
+##
+##      Kompilera-bibliotek
+##
+###################################################################################################
+
+add_library(myfeature src/mylib/myfeature.cpp)
+target_link_libraries(myfeature PUBLIC mylib)
+
+add_library(Mylib::myfeature ALIAS myfeature)
+

Sedan gör vi sÄ att det nya biblioteket ocksÄ installeras i 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 Àr viktigt att notera att för mÄlet myfeature, liksom för mylib en pseudonym med prefixet Mylib::. Detsamma anges för bÄda mÄlen nÀr de exporteras för installation i systemet. Detta möjliggör enhetlig hantering av mÄlen under alla bindningsscheman.

Efter detta ÄterstÄr det att koppla samman modul-tester med det nya biblioteket (funktionen myfunc har flyttats frÄn headern, sÄ nu behöver vi lÀnka):

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
 )

Rubriker (Mylib::mylib) behöver nu inte kopplas separat, för som redan nÀmnts, kopplas de automatiskt ihop med biblioteket (Mylib::myfeature).

Och vi lÀgger till nÄgra detaljer för att sÀkerstÀlla mÀtningar av tÀckningen med det nyligen tillkomna biblioteket:

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

Man kan lÀgga till fler bibliotek, körbara filer och sÄ vidare. Det spelar ingen roll hur de Àr kopplade till varandra inom projektet. Det viktiga Àr bara vilka mÄl som Àr grÀnssnittet för vÄr modul, det vill sÀga de som Àr exponerade.

HĂ€rska

Nu har vi standardmoduler och vi kan kontrollera dem: skapa en struktur av valfri komplexitet av dem, installera dem i systemet eller lÀnka dem samman inom en enda byggsystem.

Installation i systemet

Ett alternativ för att anvÀnda modulen Àr att installera vÄr modul i systemet.

cmake --build path/to/build/directory --target install

Efter detta kopplas den in i vilket annat projekt som helst med kommandot find_package.

find_package(Mylib 1.0 REQUIRED)

Koppling som en under-modul

Ett annat alternativ Àr att koppla mappen med vÄrt projekt till ett annat projekt som en under-modul med kommandot add_subdirectory.

AnvÀndning

Bindningsmetoderna Àr olika, men resultatet Àr detsamma. I bÄda fallen kommer mÄlen som anvÀnder vÄr modul att vara tillgÀngliga i projektet Mylib::myfeature och Mylib::mylib, som kan anvÀndas till exempel sÄ hÀr:

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

I vÄrt specifika fall biblioteket Mylib::myfeature mÄste kopplas in nÀr det Àr nödvÀndigt att lÀnka med biblioteket libmyfeature. Om det rÀcker med headerfiler, bör dÄ biblioteket anvÀndas Mylib::mylib.

CMake-mÄl kan vara knepiga, till exempel avsedda endast för att vidarebefordra vissa egenskaper, beroenden och sÄ vidare. Arbetet med dem sker pÄ ett enhetligt sÀtt.

Det som krÀvdes att uppnÄ.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster