
tega zanimivega pripovedovanja smo govorili o organizaciji glavne knjižnice znotraj generacijskega sistema za gradnjo CMake.
Tokrat bomo dodali knjižnico, ki se lahko kompajlira, ter se pogovorili o povezovanju modulov med seboj.
Kot prej lahko tisti, ki ne morejo čakati, takoj in vse preizkusite sami.
Vsebina
Prvo, kar moramo storiti za dosego našega visokega cilja, je razdeliti razvijano programsko opremo na univerzalne izolirane bloke, enotne z vidika uporabnika.
V prvem delu je bil opisan tak standardni blok — projekt z glavno knjižnico. Zdaj bomo dodali v naš projekt knjižnico, ki se lahko kompajlira.
Zato bomo izvedbo funkcije myfunc preselili v ločeno .cpp-datoteko:
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;
+ }
+}Nato bomo definirali knjižnico, ki se lahko kompajlira (myfeature), ki bo sestavljena iz prej pridobljene .cpp-datoteke. Novi knjižnici so očitno potrebni obstoječi naslovi, in da bi to zagotovili, jo lahko in moramo povezati z obstoječo ciljno mylib. Povezava med njima je javna, kar pomeni, da bo vse, kar bo povezano s ciljem myfeature, samodejno pridobilo tudi cilj 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)
+###################################################################################################
+##
+## Knjižnica, ki se lahko kompajlira
+##
+###################################################################################################
+
+add_library(myfeature src/mylib/myfeature.cpp)
+target_link_libraries(myfeature PUBLIC mylib)
+
+add_library(Mylib::myfeature ALIAS myfeature)
+Nato bomo poskrbeli, da se bo nova knjižnica prav tako namestila v sistem:
@@ -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)Pozoriti je treba, da je za cilj myfeature, as well as for mylib a pseudonym with a prefix was created Mylib::. The same is specified for both purposes when exporting them for installation in the system. This allows for consistent interaction with targets under any .
After that, it remains to run module tests with the new library (the function myfunc was moved from the header, so now it needs to be linked):
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
)Headers (Mylib::mylib) no longer need to be included separately, because, as mentioned, they are automatically included with the library (Mylib::myfeature).
And let's add a couple of nuances to ensure coverage measurements considering the newly arrived 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
)You can add more libraries, executables, etc. The specific way they are connected within the project doesn't matter. What matters is which targets serve as the interface of our module, that is, are exposed outward.
Now we have standard module blocks, and we can control them: forming structures of any complexity, installing them in the system or linking them together within a single build system.
Installation in the system
One of the options for using the module is to install our module in the system.
cmake --build path/to/build/directory --target installAfter that, it connects in any other project using the command .
find_package(Mylib 1.0 REQUIRED)Connecting as a submodule
Another option is to connect the folder with our project to another project as a submodule using the command .
Uporaba
The binding methods vary, but the result is the same. In both cases, the project that uses our module will have access to the targets Mylib::myfeature in Mylib::mylib, ki se lahko uporabljajo, na primer, tako:
add_executable(some_executable some.cpp sources.cpp)
target_link_libraries(some_executable PRIVATE Mylib::myfeature)V našem primeru je knjižnica Mylib::myfeature potrebno vključiti takrat, ko se je treba povezati z knjižnico libmyfeature. Če so dovolj glave, potem je bolje uporabiti knjižnico Mylib::mylib.
CMake cilji so lahko premeteni, na primer namenjeni samo za posredovanje določenih lastnosti, odvisnosti itd. Pri tem se z njimi dela na enoten način.
Kar smo želeli doseči.
Izvor: habr.com
