Ц++ и ЦМаке - браћа заувек, ИИ део

Ц++ и ЦМаке - браћа заувек, ИИ део

У претходном делу Ова забавна прича говорила је о организовању библиотеке заглавља у оквиру генератора ЦМаке система.

Овог пута ћемо му додати компајлирану библиотеку, а такође ћемо говорити о међусобном повезивању модула.

Као и до сада, они који су нестрпљиви могу одмах идите у ажурирано спремиште и све додирни својим рукама.


Садржина

  1. Подела
  2. Победити

Подела

Прва ствар коју треба да урадимо да бисмо постигли наш узвишени циљ је да поделимо софтвер који развијамо на универзалне, изоловане блокове који су једнообразни са тачке гледишта корисника.

У првом делу је описан такав стандардни блок – пројекат са библиотеком заглавља. Сада додајмо компајлирану библиотеку нашем пројекту.

Да бисмо то урадили, хајде да узмемо у обзир имплементацију функције myfunc у посебном .cpp-фајл:

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

Затим дефинишемо библиотеку која се компајлира (myfeature), који ће се састојати од онога што је добијено у претходном кораку .cpp-филе. Нова библиотека очигледно захтева постојећа заглавља, а да би то обезбедила, може и треба да буде везана за постојећу намену mylib. Штавише, веза између њих је јавна, што значи да ће све на шта циљ бити повезан myfeature, аутоматски ће примити оптерећење и циљ mylib (више о методама плетења).

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

Затим ћемо се уверити да је нова библиотека такође инсталирана на систему:

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

Треба напоменути да у сврху myfeature, Што се тиче mylib створен је псеудоним са префиксом Mylib::. Исто је написано за обе сврхе када их извозите за инсталацију на систем. Ово омогућава да се ради уједначено са циљевима за било кога шема везивања.

Након овога, остаје само да повежете јединичне тестове са новом библиотеком (функција myfunc извучено из наслова, па сада треба линк):

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
 )

Наслови (Mylib::mylib) сада не морате да се повезујете одвојено, јер, као што је већ поменуто, они су аутоматски повезани заједно са библиотеком (Mylib::myfeature).

И додајмо неколико нијанси како бисмо осигурали мерење покривености узимајући у обзир новопристиглу библиотеку:

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

Можете додати још библиотека, извршних датотека итд. Није битно колико су тачно међусобно повезани у оквиру пројекта. Важно је само које су мете интерфејс нашег модула, односно стрше.

Победити

Сада имамо стандардне блок модуле и можемо да доминирамо њима: компонујемо их у структуру било које сложености, инсталирамо их у систем или их повезујемо заједно у оквиру једног монтажног система.

Инсталација у систем

Једна од опција за коришћење модула је уградња нашег модула у систем.

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

Након тога се повезује са било којим другим пројектом помоћу команде find_package.

find_package(Mylib 1.0 REQUIRED)

Веза као подмодул

Друга опција је да повежете фасциклу са нашим пројектом са другим пројектом као подмодулом помоћу команде add_subdirectory.

Коришћење

Методе везивања су различите, али је резултат исти. У оба случаја, циљеви ће бити доступни у пројекту помоћу нашег модула Mylib::myfeature и Mylib::mylib, који се може користити, на пример, овако:

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

Конкретно у нашем случају, библиотека Mylib::myfeature потребно је повезати када је потребно повезати се са библиотеком libmyfeature. Ако има довољно заглавља, онда је вредно користити библиотеку Mylib::mylib.

ЦМаке циљеви могу бити незгодни, на пример, намењени само за прослеђивање неких својстава, зависности итд. Истовремено, рад са њима се одвија на исти начин.

То је оно што смо требали да добијемо.

Извор: ввв.хабр.цом

Додај коментар