
de ce récit captivant, il a été question de l'organisation d'une bibliothèque d'en-têtes dans le cadre du générateur de systèmes de construction CMake.
Cette fois, nous allons y ajouter une bibliothèque compilable et parler de l'assemblage des modules entre eux.
Comme auparavant, ceux qui ne peuvent pas attendre peuvent directement et essayer tout par eux-mêmes.
Contenu
La première chose à faire pour atteindre notre grand objectif est de diviser le logiciel en blocs isolés et universels, uniformes du point de vue de l'utilisateur.
Dans la première partie, un type de bloc standard a été décrit : un projet avec une bibliothèque d'en-têtes. Maintenant, ajoutons une bibliothèque compilable à notre projet.
Pour cela, nous allons extraire l'implémentation de la fonction myfunc dans un fichier distinct .cpp-fichier :
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
~ voir 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;
+ }
+}Ensuite, nous allons définir la bibliothèque compilable (myfeature), qui consistera en le fichier obtenu à l'étape précédente. Évidemment, la nouvelle bibliothèque a besoin des en-têtes existants, et pour cela, il est possible et nécessaire de la lier à la cible existante .cppmylib . De plus, le lien entre eux est public, ce qui signifie que tout ce à quoi la cible sera connectée obtiendra également en charge la cibleplus d'informations sur les méthodes de liaison 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)+################################################################################################### +## +## Bibliothèque compilable +## +################################################################################################### + +add_library(myfeature src/mylib/myfeature.cpp) +target_link_libraries(myfeature PUBLIC mylib) + +add_library(Mylib::myfeature ALIAS myfeature) + . De plus, le lien entre eux est public, ce qui signifie que tout ce à quoi la cible sera connectée obtiendra également en charge la cible ().
@@ -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)Ensuite, nous allons faire en sorte que la nouvelle bibliothèque soit également installée dans le système :
@@ -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)Il est important de noter que, pour l'objectif myfeature, tout comme pour . De plus, le lien entre eux est public, ce qui signifie que tout ce à quoi la cible sera connectée obtiendra également en charge la cible , un alias a été créé avec le préfixe Mylib::. Il en va de même pour les deux objectifs lors de leur exportation pour une installation dans le système. Cela permet un travail uniforme avec les objectifs dans n'importe quel .
Après cela, il reste à intégrer les tests modulaires avec la nouvelle bibliothèque (la fonction myfunc a été retirée de l'en-tête, donc il faut maintenant se lier) :
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
)Les en-têtes (Mylib::mylib) n'ont plus besoin d'être inclus séparément, car, comme mentionné précédemment, ils sont connectés automatiquement avec la bibliothèque (Mylib::myfeature).
Et ajoutons quelques nuances pour assurer les mesures de couverture en tenant compte de la nouvelle bibliothèque :
@@ -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
)On peut ajouter plus de bibliothèques, d'exécutables, etc. Peu importe comment ils sont liés entre eux dans le cadre du projet. Ce qui est important, ce sont les cibles qui constituent l'interface de notre module, c'est-à-dire celles qui sont exposées à l'extérieur.
Nous avons maintenant des modules-blocs standards, et nous pouvons les contrôler : construire une structure de toute complexité, les installant dans le système ou les reliant entre eux dans une seule système de construction.
Installation dans le système
Une des façons d'utiliser le module consiste à installer notre module dans le système.
cmake --build chemin/vers/le/répertoire/de/construction --target installAprès cela, il peut être intégré dans tout autre projet à l'aide de la commande .
find_package(Mylib 1.0 REQUIRED)Intégration en tant que sous-module
Une autre option consiste à intégrer le dossier de notre projet dans un autre projet en tant que sous-module à l'aide de la commande .
Utilisation
Les méthodes de liaison sont différentes, mais le résultat est le même. Dans les deux cas, dans un projet utilisant notre module, des cibles seront disponibles. Mylib::myfeature et Mylib::mylib, qui peuvent être utilisées, par exemple, de cette manière :
add_executable(some_executable some.cpp sources.cpp)
target_link_libraries(some_executable PRIVATE Mylib::myfeature)Dans notre cas spécifique, la bibliothèque Mylib::myfeature doit être intégrée lorsque vous devez lier avec la bibliothèque libmyfeature.S'il suffit d'en-têtes, il est alors préférable d'utiliser la bibliothèque. Mylib::mylib.
Les cibles CMake peuvent être astucieuses, par exemple, destinées uniquement à faire passer certaines propriétés, dépendances, etc. Cependant, le travail avec elles se fait de manière uniforme.
Ce qui était recherché.
Source : habr.com
