C++ at CMake - magkapatid na forever, part II

C++ at CMake - magkapatid na forever, part II

Sa nakaraang bahagi Ang nakakaaliw na kuwentong ito ay nagsalita tungkol sa pag-aayos ng isang header library sa loob ng CMake build system generator.

Sa pagkakataong ito ay magdaragdag kami ng isang pinagsama-samang aklatan dito, at pag-uusapan din ang tungkol sa pag-uugnay ng mga module sa isa't isa.

Gaya ng dati, pwede agad ang mga naiinip pumunta sa na-update na imbakan at hawakan ang lahat gamit ang iyong sariling mga kamay.


nilalaman

  1. Hatiin
  2. lupigin

Hatiin

Ang unang bagay na kailangan naming gawin upang makamit ang aming matayog na layunin ay hatiin ang software na aming binuo sa unibersal, nakahiwalay na mga bloke na pare-pareho mula sa pananaw ng user.

Sa unang bahagi, ang tulad ng isang karaniwang bloke ay inilarawan - isang proyekto na may isang header library. Ngayon, magdagdag tayo ng pinagsama-samang aklatan sa ating proyekto.

Upang gawin ito, kunin natin ang pagpapatupad ng function myfunc sa isang hiwalay .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;
+    }
+}

Pagkatapos ay tinukoy namin ang library na isasama (myfeature), na bubuo ng kung ano ang nakuha sa nakaraang hakbang .cpp-file. Ang bagong library ay malinaw na nangangailangan ng mga umiiral na header, at upang maibigay ito, maaari at dapat itong iugnay sa umiiral na layunin mylib. Bukod dito, ang koneksyon sa pagitan ng mga ito ay pampubliko, na nangangahulugan na ang lahat ng bagay na kung saan ang target ay konektado myfeature, ay awtomatikong makakatanggap ng load at target mylib (higit pa tungkol sa mga pamamaraan ng pagniniting).

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

Susunod, titiyakin namin na ang bagong library ay naka-install din sa system:

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

Dapat tandaan na para sa layunin myfeature, para sa mylib isang alias na may prefix ang ginawa Mylib::. Ang parehong ay nakasulat para sa parehong mga layunin kapag ini-export ang mga ito para sa pag-install sa system. Ginagawa nitong posible na magtrabaho nang pantay-pantay sa mga layunin para sa anuman nagbubuklod na pamamaraan.

Pagkatapos nito, ang natitira na lang ay i-link ang mga unit test sa bagong library (function myfunc inalis sa pamagat, kaya ngayon kailangan mong mag-link):

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
 )

Mga Pamagat (Mylib::mylib) ngayon hindi mo na kailangang kumonekta nang hiwalay, dahil, tulad ng nabanggit na, awtomatiko silang konektado kasama ng library (Mylib::myfeature).

At magdagdag tayo ng ilang mga nuances upang matiyak ang mga sukat ng saklaw na isinasaalang-alang ang bagong dating na library:

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

Maaari kang magdagdag ng higit pang mga library, executable, atbp. Hindi mahalaga kung gaano sila eksaktong konektado sa isa't isa sa loob ng proyekto. Ang tanging mahalagang bagay ay kung aling mga target ang interface ng aming module, iyon ay, nananatili ang mga ito.

lupigin

Ngayon ay mayroon na kaming mga karaniwang block module, at maaari naming dominahin ang mga ito: i-compose ang mga ito sa isang istraktura ng anumang kumplikado, i-install ang mga ito sa isang system o i-link ang mga ito nang magkasama sa loob ng isang sistema ng pagpupulong.

Pag-install sa system

Isa sa mga opsyon sa paggamit ng module ay ang pag-install ng aming module sa system.

cmake --build ΠΏΡƒΡ‚ΡŒ/ΠΊ/сборочной/Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ --target install

Pagkatapos nito, ito ay konektado sa anumang iba pang proyekto gamit ang command find_package.

find_package(Mylib 1.0 REQUIRED)

Koneksyon bilang isang submodule

Ang isa pang pagpipilian ay upang ikonekta ang folder sa aming proyekto sa isa pang proyekto bilang isang submodule gamit ang command add_subdirectory.

Gamitin

Ang mga paraan ng pagbubuklod ay iba, ngunit ang resulta ay pareho. Sa parehong mga kaso, ang mga layunin ay magagamit sa proyekto gamit ang aming module Mylib::myfeature ΠΈ Mylib::mylib, na maaaring gamitin, halimbawa, tulad nito:

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

Partikular sa aming kaso, ang library Mylib::myfeature kailangang konektado kapag kinakailangan na mag-link sa library libmyfeature. Kung may sapat na mga header, sulit na gamitin ang library Mylib::mylib.

Ang mga target ng CMake ay maaaring nakakalito, halimbawa, nilayon lamang na ipasa ang ilang mga katangian, dependency, atbp. Kasabay nito, ang pakikipagtulungan sa kanila ay nangyayari sa parehong paraan.

Iyon ang kailangan naming makuha.

Pinagmulan: www.habr.com

Magdagdag ng komento