
V tomto zajímavém příběhu se hovoří o organizaci hlavičkové knihovny v rámci systému pro sestavování CMake.
Tentokrát přidáme kompilovatelnou knihovnu a také si promluvíme o propojení modulů mezi sebou.
Jak již bylo zmíněno, ti, kdo se nemohou dočkat, mohou ihned a vyzkoušet si to na vlastní kůži.
Obsah
První věc, kterou je třeba udělat pro dosažení našeho vysokého cíle, je rozdělit vyvíjený software na univerzální izolované bloky, které jsou jednotné z uživatelského hlediska.
V první části byl popsán takový standardní blok — projekt s hlavičkovou knihovnou. Nyní do našeho projektu přidáme kompilovatelnou knihovnu.
Za tímto účelem oddělíme implementaci funkce myfunc do samostatného .cpp-souboru:
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
~ viz 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;
+ }
+}Pak definujeme kompilovatelnou knihovnu (myfeature), která se bude skládat ze souboru vytvořeného v předchozím kroku. Nové knihovně jsou, očividně, potřebné již existující hlavičky, a proto je nutné ji propojit s existující cílovou knihovnou .cppmylib . Propojení mezi nimi je veřejné, což znamená, že vše, co bude k cíli připojeno, automaticky získá také cílovou knihovnu.podrobněji o způsobech propojení myfeaturediff --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)+################################################################################################### +## +## Kompilovatelná knihovna +## +################################################################################################### + +add_library(myfeature src/mylib/myfeature.cpp) +target_link_libraries(myfeature PUBLIC mylib) + +add_library(Mylib::myfeature ALIAS myfeature) + . Propojení mezi nimi je veřejné, což znamená, že vše, co bude k cíli připojeno, automaticky získá také cílovou knihovnu. ().
@@ -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)Je třeba si uvědomit, že pro cílovou knihovnu
, stejně jako proНужно обратить внимание, что для цели myfeature, как и для . Propojení mezi nimi je veřejné, což znamená, že vše, co bude k cíli připojeno, automaticky získá také cílovou knihovnu. byl zaveden pseudonym s prefixem Mylib::. Totéž je napsáno pro oba účely při exportování jejich pro instalaci v systému. To poskytuje možnost jednotné práce s cíli při jakékoli .
Po tom zbývá propojit modulární testy s novou knihovnou (funkci myfunc vynesli z hlavičky, takže nyní je třeba linkovat):
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
)Hlavičky (Mylib::mylib) nyní není třeba připojovat zvlášť, protože, jak už bylo řečeno, jsou automaticky připojeny spolu s knihovnou (Mylib::myfeature).
A přidáme pár nuancí, abychom zajistili měření pokrytí s ohledem na nově příchozí knihovnu:
@@ -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
)Můžeme přidat více knihoven, spustitelných souborů atd. Přitom nezáleží na tom, jak přesně jsou mezi sebou propojeny v rámci projektu. Důležité je pouze to, které cíle jsou rozhraním našeho modulu, tedy vyčnívají ven.
Nyní máme standardní modulární bloky a můžeme s nimi vládnout: sestavit z nich strukturu jakékoli složitosti, instalovat je do systému nebo je mezi sebou propojovat v rámci jediné buildovací struktury.
Instalace do systému
Jedna z možností použití modulu — nainstalovat náš modul do systému.
cmake --build cesta/k/build/adresáři --target installPoté se připojí v jakémkoli jiném projektu pomocí příkazu .
find_package(Mylib 1.0 REQUIRED)Připojení jako podmodul
Další možností je připojit složku s naším projektem k jinému projektu jako podmodul pomocí příkazu .
Použití
Způsoby propojení jsou různé, ale výsledek je stejný. A v obou případech budou v projektu, který používá náš modul, k dispozici cíle Mylib::myfeature a Mylib::mylib, které mohou být použity například takto:
add_executable(some_executable some.cpp sources.cpp)
target_link_libraries(some_executable PRIVATE Mylib::myfeature)V našem konkrétním případě je třeba knihovnu Mylib::myfeature připojit pouze tehdy, když je nutné se s knihovnou propojit libmyfeature. Pokud stačí hlavičkové soubory, pak by bylo lepší použít knihovnu Mylib::mylib.
CMake cíle mohou být složité, například určené pouze k předávání určitých vlastností, závislostí atd. Práce s nimi přitom probíhá jednotně.
Což bylo požadováno.
Zdroj: habr.com
