La mise en place d'un nouveau projet C ++ nécessite généralement une quantité importante de code de préparation et de chauffeur, d'autant plus pour les projets C ++ modernes avec des tests, des exécutables et une intégration continue. Ce modèle est le résultat des apprentissages de nombreux projets précédents et devrait aider à réduire le travail requis pour configurer un projet C ++ moderne.
Greeter signifie le nom du projet, tandis que greeter est utilisé dans les noms de fichiers.include/greeter pour utiliser le nom minuscule de votre projet et mettre à jour tous #include pertinents en conséquence.CODECOV_TOKENFinalement, vous pouvez supprimer tous les fichiers inutilisés, tels que le répertoire autonome ou les workflows GitHub non pertinents pour votre projet. N'hésitez pas à remplacer la licence par une licence adaptée à votre projet.
Pour séparer proprement le code de la bibliothèque et du sous-projet, le CMakeList.txt externe.txt définit uniquement la bibliothèque elle-même tandis que les tests et autres sous-projets sont autonomes dans leurs propres répertoires. Pendant le développement, il est généralement pratique de créer tous les sous-projets à la fois.
Utilisez la commande suivante pour construire et exécuter la cible exécutable.
cmake -S standalone -B build/standalone
cmake --build build/standalone
./build/standalone/Greeter --helpUtilisez les commandes suivantes du répertoire racine du projet pour exécuter la suite de tests.
cmake -S test -B build/test
cmake --build build/test
CTEST_OUTPUT_ON_FAILURE=1 cmake --build build/test --target test
# or simply call the executable:
./build/test/GreeterTests Pour collecter des informations de couverture de code, exécutez CMake avec l'option -DENABLE_TEST_COVERAGE=1 .
Utilisez les commandes suivantes du répertoire racine du projet pour vérifier et corriger le style de source C ++ et CMake. Cela nécessite un format de clang , du format cmake et du pyyaml à installer sur le système actuel.
cmake -S test -B build/test
# view changes
cmake --build build/test --target format
# apply changes
cmake --build build/test --target fix-formatVoir format.cmake pour plus de détails. Ces dépendances peuvent être facilement installées à l'aide de PIP.
pip install clang-format==14.0.6 cmake_format==0.6.11 pyyamlLa documentation est automatiquement construite et publiée chaque fois qu'une version GitHub est créée. Pour construire manuellement la documentation, appelez la commande suivante.
cmake -S documentation -B build/doc
cmake --build build/doc --target GenerateDocs
# view the docs
open build/doc/doxygen/html/index.htmlPour construire la documentation localement, vous aurez besoin de Doxygen, Jinja2 et Pygments installés sur votre système.
Le projet comprend également un répertoire all qui permet de construire toutes les cibles en même temps. Ceci est utile pendant le développement, car il expose tous les sous-projets à votre IDE et évite les versions redondantes de la bibliothèque.
cmake -S all -B build
cmake --build build
# run tests
./build/test/GreeterTests
# format code
cmake --build build --target fix-format
# run standalone
./build/standalone/Greeter --help
# build docs
cmake --build build --target GenerateDocsLe test et les sous-projets autonomes incluent le fichier outils.cmake qui est utilisé pour importer des outils supplémentaires à la demande via des arguments de configuration CMake. Les éléments suivants sont actuellement pris en charge.
Les désinfectants peuvent être activés en configurant CMake avec -DUSE_SANITIZER=<Address | Memory | MemoryWithOrigins | Undefined | Thread | Leak | 'Address;Undefined'> .
Les analyseurs statiques peuvent être activés en réglant -DUSE_STATIC_ANALYZER=<clang-tidy | iwyu | cppcheck> , ou une combinaison de ceux des guillemets, séparés par des demi-colons. Par défaut, les analyseurs trouveront automatiquement des fichiers de configuration tels que .clang-format . Des arguments supplémentaires peuvent être transmis aux analyseurs en définissant les variables CLANG_TIDY_ARGS , IWYU_ARGS ou CPPCHECK_ARGS .
Ccache peut être activé en configurant avec -DUSE_CCACHE=<ON | OFF> .
Puis-je l'utiliser pour les bibliothèques d'en-tête uniquement?
Oui, cependant, vous devrez modifier le type de bibliothèque en bibliothèque INTERFACE tel que documenté dans cMakelists.txt. Voir ici pour un exemple de bibliothèque d'en-tête uniquement basée sur le modèle.
Je n'ai pas besoin d'une cible / documentation autonome. Comment puis-je m'en débarrasser?
Supprimez simplement le répertoire autonome / documentation et selon le fichier de workflow GitHub.
Puis-je construire les tests autonomes et les tests en même temps? / Comment puis-je parler à mon IDE de tous les sous-projets?
Pour garder le modèle modulaire, tous les sous-projets dérivés de la bibliothèque ont été séparés en leurs propres modules CMake. Cette approche rend trivial pour les projets tiers afin de réutiliser le code de la bibliothèque des projets. Pour permettre aux IDE de voir la portée complète du projet, le modèle comprend le répertoire all qui créera une seule version pour tous les sous-projets. Utilisez-le comme répertoire principal du meilleur support IDE.
Je vois que vous utilisez
GLOBpour ajouter des fichiers source dans cMakelists.txt. N'est-ce pas le mal?
Glob est considéré comme mauvais car toute modification de la structure du fichier source peut ne pas être automatiquement capturée par les constructeurs de CMake et vous devrez invoquer manuellement les modifications de CMake. Personnellement, je préfère la solution GLOB pour sa simplicité, mais n'hésitez pas à la modifier pour répertorier explicitement les sources.
Je veux créer des cibles supplémentaires qui dépendent de ma bibliothèque. Dois-je modifier les principaux cmakelists pour les inclure?
Évitez d'inclure des projets dérivés des bibliothèques CMakelists (même si c'est une vue courante dans le monde C ++), car cela inverse efficacement l'arbre de dépendance et rend le système de construction difficile à raisonner. Au lieu de cela, créez un nouveau répertoire ou un nouveau projet avec un CMAKELIST qui ajoute la bibliothèque comme une dépendance (par exemple, comme le répertoire autonome). Selon le type, il peut être logique de déplacer ces composants dans des référentiels distincts et de référencer un engagement ou une version spécifique de la bibliothèque. Cela a l'avantage que les bibliothèques et les composants individuels peuvent être améliorés et mis à jour indépendamment.
Vous recommandez d'ajouter des dépendances externes à l'aide de CPM.CMake. Cela obligera-t-il également les utilisateurs de ma bibliothèque à utiliser CPM.CMake également?
CPM.CMake doit être invisible pour les utilisateurs de la bibliothèque car il s'agit d'un script CMake autonome. Si des problèmes surviennent, les utilisateurs peuvent toujours se désinscrire en définissant la variable CMake ou Env CPM_USE_LOCAL_PACKAGES , qui remplacera tous les appels vers CPMAddPackage avec l'appel Selon find_package . Cela devrait également permettre aux utilisateurs d'utiliser le projet avec leur gestionnaire de dépendance C ++ externe préféré, tel que VCPKG ou Conan.
Puis-je configurer et créer mon projet hors ligne?
Aucune connexion Internet n'est requise pour construire le projet, cependant, lorsque l'utilisation des dépendances manquantes CPM est téléchargée au moment de la configuration. Pour éviter les téléchargements redondants, il est fortement recommandé de définir un répertoire de cache CPM.CMake, par exemple: export CPM_SOURCE_CACHE=$HOME/.cache/CPM . Cela permettra des clones peu profonds et permettra des configurations hors ligne que les dépendances sont déjà disponibles dans le cache.
Puis-je utiliser CPACK pour créer un installateur de package pour mon projet?
Comme il y a beaucoup d'options et de configurations possibles, ce n'est pas (encore) dans la portée de ce modèle. Voir la documentation CPACK pour plus d'informations sur la configuration des installateurs CPACK.
C'est trop, je veux juste jouer avec le code C ++ et tester certaines bibliothèques.
Peut-être que le Minicppstarter est quelque chose pour vous!