C++ и CMake - браќа засекогаш, II дел

C++ и CMake - браќа засекогаш, II дел

Во претходниот дел Оваа забавна приказна зборуваше за организирање библиотека со заглавија во генераторот на системот за изградба на CMake.

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

Како и досега, нетрпеливите можат веднаш одете во ажурираното складиште и допрете сè со свои раце.


содржина

  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.

Целите на CMake може да бидат незгодни, на пример, наменети само за проследување на некои својства, зависности итн. Во исто време, работата со нив се случува на ист начин.

Тоа е она што требаше да го добиеме.

Извор: www.habr.com

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