15 mai 2024
Ce document donne des précisions sur l’utilisation de différents outils utilisés durant CSC4526 :
Tous les canevas de projet C++ fournis dans le cadre de CSC4526 s’appuient sur cmake. cmake permet de configurer l’environnement du projet, ce qui dispensera de configurer l’IDE.
Commencez par lire ci-dessous les instructions communes à tous les IDE/OS, puis lisez la section correspondant à votre IDE/OS.
Cliquez pour déplier/plier les détails
SampleSFML.zip
dans l’exercice d’introduction) dans le répertoire de votre choix.
C:\Users\Barnabé\Mes Documents\CPP
est à bannir à cause du é dans Barnabé et de l’espace dans Mes Documents ; il vaut mieux que le chemin soit C:\CPP
. Si vous ne respectez pas ce conseil, votre IDE risque de recompiler systématiquement l’ensemble de votre projet.SampleSFML
)nouveau_nom_du_répertoire_racine\CMakeLists.txt
, au niveau de la ligne project(nom_projet VERSION 1.0.0 LANGUAGES CXX)
, remplacer nom_projet
par un nom (sans espace) qui correspond à votre projet.Cliquez pour déplier/plier les détails
chemin_absolu_vers_votre_projet/CMakeLists.txt
. Cliquez sur “OK” : Une fenêtre “Open Project” apparaît. CLiquez sur “Open as Project”sudo apt-get install -y ninja-build
(cf. ce site).cd chemin_absolu_vers_votreRépertoireProjet
rm -Rf cmake-build-debug
mkdir build
cd build
cmake .. # N'oubliez pas le " .." après la commande cmake
#
# Si cmake affiche l'une des messages suivants:
# - "cmake not found"
# - "Error during cmake"
# - "No CMAKE_CXX_COMPILER"
# - "Could NOT find X11"
# Alors tapez les 2 commandes suivantes:
#
sudo apt -y install git cmake g++ libx11-dev libxrandr-dev libxi-dev libxcursor-dev libudev-dev mesa-common-dev libfreetype6-dev libopenal-dev libvorbis-dev libflac-dev
# Au final, vous devriez obtenir le message "-- Build files have been written to: absolute_path_to_your_project". Cela signifie que toutes les installations préalables pour Linux sont OK.
#
# Il vous reste à nettoyer votre répertoire de votre test cmake:
cd ..
rm -Rf build
SampleSFML
), une fenêtre “SFML works !” semblable à la fenêtre ci-dessous s’ouvre:Cliquez pour déplier/plier les détails
Dans un terminal, tapez la commande which brew pour vous assurer d’avoir la version de Homebrew adaptée à l’architecture ARM de votre processeur : Si la version de Homebrew est adaptée à ARM, le chemin affiché devrait commencer par /opt/homebrew/
. Si le chemin affiché commence par /usr/local/
, votre version de Homebrew est adaptée à un processeur Intel (ce qui vous posera des soucis lorsque CLion fera des éditions de liens) : Il vous faut installer un Homebrew adapté à ARM (cf. procédure un peu modifiée de la 1ère réponse ici) :
brew bundle dump
pour créer un Brewfile des packages déjà installés.cd /opt
sudo mkdir -p homebrew
sudo chown -R $(whoami) homebrew
curl -L https://github.com/Homebrew/brew/tarball/master |\
tar xz --strip 1 -C homebrew
#+end_src
- Modifiez *PATH*
#+begin_src bash
PATH=/opt/homebrew/bin:$PATH
hash -d brew
brew bundle install --file /path/to/Brewfile
Cliquez pour déplier/plier les détails
brew install ninja
(cf. ce site).brew install sfml
SampleSFML
), une fenêtre “SFML works !” semblable à la fenêtre ci-dessous s’ouvre:Cliquez pour déplier/plier les détails
SampleSFML
, la fenêtre suivante s’affiche pour vous signifier que SFML fonctionne.Pour information, cette procédure crée les répertoires .vs et out dans le répertoire de votre projet.
Pour les premiers canevas de projet que vous utiliserez dans CSC4526, vous aurez juste à modifier des fichiers source déjà fournis dans le canevas.
Puis, vous serez amené à ajouter des fichiers sources, ce qui requiert une procédure particulière décrite dans cette section.
Cliquez pour déplier/plier les détails
.h
et de .cpp
. Sachez toutefois que CLion modifiera src/CMakeLists.txt
. pour y ajouter le nom des fichiers ajoutés. Si vous le souhaitez vous pouvez manuellement supprimer ces ajouts inutiles.
Cliquez pour déplier/plier les détails
Dans le cas où votre projet a été créé avec menu Fichier > Ouvrir > CMake… :
CMakeLists.txt
; c’est inutile, car votre CMakeLists.txt
prend en compte tout nouveau fichier grâce à sa ligne file(GLOB SOURCES CONFIGURE_DEPENDS *.h *.cpp)
Cliquez pour déplier/plier les détails
S106: Replace this usage of std::cout by a logger
qui est trop complexe à résoudre pour nos applications “jouet”), cliquez droit sur la règle (dans la fenêtre d’erreur de VisualStudio ou pour CLion, dans la sous-fenêtre SonarLint) et sélectionnez “Disable SonarLint rule”.Pour la session CSC4526 2023-2024, un bug lié à la combinaison Visual Studio version 17.9.6 / cmake / SonarLint est apparu quelques jours avant le début de ce cours. Il empêche que SonarLint affiche ses messages dans Visual Studio.
Voyons tout d’abord si vous êtes concerné·e par ce bug :
Dans Visual Studio, Outils > Ligne de commande > PowerShell développeur : Une fenêtre PowerShell s’ouvre.
Tapez la commande cmake --version
: La version de cmake
s’affiche.
Si la version affichée est cmake version 3.28.0-msvc1
, vous êtes concerné·e par le bug, ce qui explique que vous avez peut-être vu le message SonarLint: Failed to analyze <nomFichier>. See the Output Window for more information
(en bas à gauche).
D’ailleurs, dans l’onglet “Sortie” en bas de l’écran, si vous sélectionnez “SonarLint” à la place de “CMake” dans la combo box “Afficher la sortie à partir de :”, vous voyez le message :
[CLangAnalyzer] Analyzing C:\temp\CSC4526\SampleGoogleTest\unitTests\unitTests.cpp
[CFamily Analysis] Unsupported configuration: Unexpanded response file is not supported:@unitTests\CMakeFiles\unitTests.dir\unitTests.cpp.obj.modmap.
[CLangAnalyzer] Failed to analyze C:\temp\CSC4526\SampleGoogleTest\unitTests\unitTests.cpp: See above for more information.
Cet article indique la démarche pour résoudre ce bug :
C:\Program Files\CMake\bin
).PATH
de l’utilisateur (vous pouvez aussi indiquer “tous les utilisateurs”) soit modifié pour inclure le chemin vers ce cmake
.PATH
avec le chemin vers cmake installé : Le bug ne devrait plus se manifester.CMakeLists.txt
, vous devez faire régénérer votre projet ==> menu “Projet > Supprimer le cache et reconfigurer” pour que VisualStudio applique le CMakeLists.txt
avec le nouveau cmake.Google Test est un environnement facilitant l’écriture et le passage de tests unitaires. Cette section présente l’utilisation de Google Test selon l’IDE que vous utilisez. Nous supposons ici que vous avez déjà appliqué cmake sur un canevas de projet contenant des tests unitaires.
Cliquez pour déplier/plier les détails
Cliquez pour déplier/plier les détails
Si cette fenêtre ne vous affiche aucun test, mais le message “Générez votre solution pour découvrir tous les tests disponibles”, vérifiez que votre CMakeLists.txt
racine contient les trois dernières lignes suivantes :
include(GoogleTest)
enable_testing()
add_subdirectory(tests)
Si la ligne include(GoogleTest)
manque, ajoutez-la et supprimez-la du fichier unitTests/CMakeLists.txt
où elle doit encore apparaître.
Si elle ne manque pas, prévenez Michel Simatic pour qu’il voit ce qui peut être fait (Ce ticket ne serait pas corrigé).
unitTests (1)
: vous avez passé votre premier test unitaire sur votre application.unitTest (1)
et double-cliquez sur la ligne terminale TestName
: Visual Studio ouvre le fichier unitTests.cpp
au niveau du test unitaire en erreur (et l’explorateur de tests explicite l’erreur dans la sous-fenêtre à droite “Récapitulatif des détails du test”)Cette section retranscrit le contenu des vidéos de tutoriel sur le débogage :
Ces vidéos utilisent le fichier ExempleDeDebugDeProgramme.cpp
Cliquez pour déplier/plier les détails
Les manipulations ont été effectuées en s’appuyant sur le scénario Visual Studio ci-dessous. Pour information, CLion ne permet pas de mettre en place un arrêt quand la valeur d’une variable change (il faut taper manuellement la commande gdb watch
dans la console gdb fournie par CLion).
Cliquez pour déplier/plier les détails
Dans ce tutoriel vidéo, je vous propose une initiation aux principales fonctions de débogage offertes par Visual Studio. Vous pourrez ainsi gagner en efficacité et en rapidité dans la mise au point de vos programmes, qu’ils soient écrits en C++ ou dans d’autres langages. En effet, les notions présentées ici sont génériques à tous les langages de programmation.
Notez que, pour ce tutoriel, nous nous appuierons sur le fichier ExempleDeDebugDeProgramme.cpp
que je vous invite à télécharger maintenant, si vous ne l’avez pas déjà fait.
Expression: vector subscript out of range
Please retry to debug the application
, clic sur Recommencer
Expression: vector subscript out of range
.Please retry to debug the application
, clic sur Recommencer
vector subscript out of range
v.size
: VS vous affiche 4.v
et cliquez sur la flèche pour voir le contenu de v
: il y a 4 éléments. NB : on peut aussi voir le contenu de v
dans le cadre des variables locales en bas à gauche.-1
et cliquons sur le bouton “Redémarrer”division par zéro
. Effectivement c
vaut 0
(qui ne fait pas bon ménage avec l’opérateur modulo).c
s’est retrouvé avec la valeur 0
, mettons un point d’arrêt au niveau de la définition de c
, puis exécutons pas à pas le programme.unCalcul()
) ==> Zut, la valeur de c
a changé.unCalcul()
unCalcul()
return resultat
resultat == 0
c
soit définie.c
et “Arrêtez quand la valeur change”. Notez que la variable a
change aussi de couleur (vu que c
est une référence vers a
).a
(et donc c
) change.c
: il faut programmer un nouveau point d’arrêt pour cette variable.Nous voici arrivés à la fin de cette initiation au débogage sous Visual Studio : n’hésitez pas à faire vos propres expériences pour vous familiariser avec cet outil et ainsi gagner en efficacité et en rapidité dans la mise au point de vos programmes.
Pour analyser les fuites mémoire dans du code C++, nous nous appuyons sur des outils dédiés.
Pour tester ces outils, vous pouvez vous appuyer sur votre propre projet ou bien créer un projet console et substituer le code automatiquement généré par le contenu de codeQuiFuit.cpp.
Pour éviter l’installation d’un autre outil, nous nous appuyons sur le sanitizer address
.
Pour ce faire, modifiez le CMakeLists.txt
à la racine de votre projet en lui ajoutant les lignes :
.......set (BUILD_SHARED_LIBS FALSE)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # This cmake_policy avoids warning by cmake when we use pugixml
cmake_policy(SET CMP0135 NEW) # This cmake_policy avoids warning by cmake when we fetch contents based on URL
###### DEBUT lignes a rajouter
if(MSVC)
add_compile_options(/fsanitize=address)
else()
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
endif()
###### FIN lignes a rajouter
set(CMAKE_CXX_STANDARD 20)
.......
Dans votre projet, prenez en compte les changements de CMakeLists.txt
, puis régénérez complètement votre projet.
Si vous exécutez, comme jusqu’à présent, unitTests
dans le cadre de l’environnement GoogleTest, vos tests sont toujours tous corrects. Cependant, en bas à gauche de votre écran, à côté de l’onglet Console
, il y a un onglet Sanitizers
qui vous signale des problèmes repérés dans votre code :
Pour information, si vous choisissez d’exécuter la cible All CTests
, les tests qui causent la fuite mémoire sont signalés comme ne passant pas (alors que, pourtant, les différents EXPECT
ou ASSERT
sont corrects). L’onglet Sanitizers
permet de comprendre les problèmes.
Leak-DefinitelyLost 3 Warnings
. Si vous dépliez ce message, vous accédez au détail de ces fuites mémoire. En dépliant l’une de ces fuites, vous avez accès à la pile d’appel qui a amené à l’allocation mémoire sans libération associée. En double-cliquant sur l’une des lignes de la pile d’appel (par exemple, dans la figure 1, sur la ligne Group::Group(pugi::xml_node) Group.cpp:15)
), vous accédez au code de la ligne qui a fait le new
.Suivez la démarche proposée dans la section “CLion sans installation d’un autre outil” de Linux.
Sous MacOS, vous pouvez aussi vous appuyer sur l’outil leaks fourni en standard (cf. cet article).
Dans un terminal, compiler votre programme avec l’option -g
(NB: Clion compile votre programme directement avec cette option). Par exemple:
cc -g -Wall -Werror nomFichier.c -o nomFichier
leaks --atExit --list -- ./nomFichier
# ==> Détection des leaks sans voir leur emplacement précis dans le code
export MallocStackLogging=1
# Rien ne se passe
leaks --atExit --list -- ./nomFichier
# ==> Affichage des emplacements précis dans le code
Address
permette la détection de fuites mémoire sous WindowsWindows implémente le sanitizer Address
pour son compilateur MSVC (cf. tous ces exemples de détection), mais, actuellement, cette implémentation ne détecte pas les fuites mémoire !
Si vous le souhaitez, votez ici pour demander l’ajout de cette fonctionnalité !
En attendant, consultez la section suivante pour détecter les fuites mémoire sous Windows.
Par rapport à Valgrind sous Linux, le Visual Studio Profiler est un peu plus compliqué à mettre en oeuvre, mais présente l’avantage de ne pas du tout ralentir l’application profilée.
Cet outil étant disponible en standard dans Visual Studio, il n’y a aucune installation à faire.
Commencez par poser un point d’arrêt au niveau de l’appel à la fonction que vous souhaitez tester. Par exemple, dans le cas d’une application CSC4526, l’appel à la fonction myMain()
.
Si vous souhaitez voir si vos tests unitaires révèlent des fuites mémoire :
unitTests.exe!RUN_ALL_TESTS()
et double-cliquez dessus : le code de gtest.h
s’affiche.return ::testing::UnitTest::GetInstance()->Run();
unitTests.exe!Circle[]
)
L’outil Dr. Memory est sensé être un équivalent de Valgrind sous Windows. Mais il ne fonctionne pas correctement. Nous le mentionnons ici seulement pour information.