C++ և CMake - եղբայրներ ընդմիշտ, մաս II

C++ և CMake - եղբայրներ ընդմիշտ, մաս II

Նախորդ մասում Այս զվարճալի պատմությունը խոսում էր CMake build համակարգի գեներատորում վերնագրերի գրադարան կազմակերպելու մասին:

Այս անգամ դրան կավելացնենք կազմված գրադարան, ինչպես նաև կխոսենք մոդուլները միմյանց հետ կապելու մասին։

Ինչպես նախկինում, նրանք, ովքեր անհամբեր են, կարող են անմիջապես գնալ թարմացված պահոց և ձեր սեփական ձեռքերով շոշափեք ամեն ինչ:


Պարունակություն

  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 թիրախները կարող են բարդ լինել, օրինակ՝ նախատեսված միայն որոշ հատկություններ, կախվածություններ և այլն փոխանցելու համար: Միեւնույն ժամանակ, նրանց հետ աշխատելը տեղի է ունենում նույն կերպ:

Դա այն էր, ինչ մենք պետք է ստանայինք:

Source: www.habr.com

Добавить комментарий