User Tools

Site Tools


projtec:cmake

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
projtec:cmake [2017/01/25 22:58] – [Tests Unitaires] orelprojtec:cmake [2024/03/18 15:06] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ======CMake ====== ======CMake ======
 +
 +  * https://cmake.org/documentation/
 +  * https://cmake.org/cmake-tutorial/
 +  * https://cmake.org/cmake/help/v3.3/manual/cmake-commands.7.html
  
 ==== Hello World ==== ==== Hello World ====
Line 18: Line 22:
 <code text CMakeLists.txt> <code text CMakeLists.txt>
 cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
-project(HelloWorld)+project(HelloWorld C)
 add_executable(hello hello.c) add_executable(hello hello.c)
 </code> </code>
  
-Pour générer un Makefile et compiler notre projet, il faut taper les commandes suivantes :+Pour générer un Makefile et compiler notre projet "sur place", il faut taper les commandes suivantes :
  
   cmake .   cmake .
-  make        # ou make VERBOSE=ON+  make clean ; make 
 +  make VERBOSE=1   # compilation en mode verbose 
 +  make help        # pour voir la liste des cibles possibles 
 + 
 +Pour compiler "en dehors des sources"
 + 
 +  mkdir build 
 +  cd build 
 +  cmake .. 
 +  make 
 +   
 +Un des avantages de cette méthode est quelle permet de ne pas mélanger les fichiers générés par CMake et Make avec les fichiers sources. Du coup, il suffit de supprimer le répertoire //build// pour tout nettoyer.
  
 ==== Un peu plus compliqué ==== ==== Un peu plus compliqué ====
Line 61: Line 76:
 cmake_minimum_required (VERSION 2.6) cmake_minimum_required (VERSION 2.6)
 project (HelloWorld C) project (HelloWorld C)
 +
 +set(CMAKE_BUILD_TYPE DEBUG)
 +set(CMAKE_VERBOSE_MAKEFILE ON)
 +set(CMAKE_C_COMPILER gcc)
 set(CMAKE_C_FLAGS "-std=c99 -g -Wall") set(CMAKE_C_FLAGS "-std=c99 -g -Wall")
 set(CMAKE_INSTALL_PREFIX "install") set(CMAKE_INSTALL_PREFIX "install")
 +
 add_executable(hello hello.c pouet.c) add_executable(hello hello.c pouet.c)
 target_link_libraries(hello m) target_link_libraries(hello m)
 install(TARGETS hello RUNTIME DESTINATION bin) install(TARGETS hello RUNTIME DESTINATION bin)
 </code> </code>
 +
 +Notons que CMake scanne automatiquement les dépendances (sans faire néanmoins de preprocessing). Il en résulte que la dépendance sur //pouet.h// est ajouté implicitement.
  
 Ensuite, on fait... Ensuite, on fait...
  
   cmake .   cmake .
-  make +  make  
-  make install+  make install # make install DESTDIR="/some/absolute/path" 
 +  
      
 ==== Utilisation d'une bibliothèque interne ==== ==== Utilisation d'une bibliothèque interne ====
  
-Considérons maintenant le projet {{projtec:cmake.zip}}, dont la structure est décrit ci-dessous :+Considérons maintenant le projet {{projtec:cmake-v2.zip}}, dont la structure est décrit ci-dessous :
  
 <code> <code>
Line 128: Line 151:
 </code> </code>
  
-==== Tests Unitaires ====+==== Tests Dynamiques ====
  
-On ajoute au projet précédent un sous-répertoire //tests// pour vérifier les fonctions de //mylib//{{projtec:cmake-v3.zip}}+On ajoute à notre projet un sous-répertoire //tests// pour vérifier les fonctions de //mylib// ({{projtec:cmake-v3.zip}}).
  
 <code> <code>
Line 147: Line 170:
 </code> </code>
  
-Voici le fichier //CMake// pour compiler et exécuter les tests...+Voici le fichier //CMake// pour compiler et exécuter les tests. Par defaut, pour chaque test, CMake vérifie que le programme termine normalement (pas de signal SEGV par exemple ) et que la valeur de retour vaut EXIT_SUCCESS (0)On peut également rajouter d'autres propriétés à vérifier comme un //timeout// ou encore vérifier la sortie standard par une expression régulière.
  
 <code text tests/CMakeLists.txt> <code text tests/CMakeLists.txt>
 +include(CTest)
 enable_testing() enable_testing()
  
Line 159: Line 183:
  
 add_test(test1 test-mylib-foo) add_test(test1 test-mylib-foo)
-set_tests_properties(test1 PROPERTIES PASS_REGULAR_EXPRESSION "foo")+set_tests_properties(test1 PROPERTIES PASS_REGULAR_EXPRESSION "foo" TIMEOUT 3)
 add_test(test2 test-mylib-bar) add_test(test2 test-mylib-bar)
-set_tests_properties(test2 PROPERTIES PASS_REGULAR_EXPRESSION "bar")+set_tests_properties(test2 PROPERTIES PASS_REGULAR_EXPRESSION "fooTIMEOUT 3)
  
-add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) 
 </code> </code>
  
-(...)+Pour lancer les tests :  
 +  make test
  
 +==== Fuites Mémoire ====
  
-==== Biblio ====+Pour aller un peu plus loin, on peut lancer des tests de varification de la mémoire (memcheck) :
  
-  * https://cmake.org/documentation+  make ExperimentalMemCheck 
-  * https://cmake.org/cmake-tutorial+   
-  * https://cmake.org/cmake/help/v3.3/manual/cmake-commands.7.html+Ces tests se base sur la variable MEMORYCHECK_COMMAND qui est par défault sur /sur/bin/valgrind (enfin s'il est installé...). Les résultats sont dans Testing/<DATE-HOUR>/DynamicAnalysis.xml. 
 + 
 +Les logs sont disponibles dans Testing/Temporary/MemoryChecker.*.log 
 + 
 +Il est possible d'ajouter les options suivantes pour obtenir des logs encore plus détaillés... 
 + 
 +  find_program(MEMORYCHECK_COMMAND valgrind) 
 +  set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full" CACHE STRING "" FORCE) 
 + 
 + 
 +==== Couverture de Code ==== 
 + 
 +Pour aller encore plus loin... 
 + 
 +<code text tests/CMakeLists.txt> 
 +cmake_minimum_required(VERSION 3.0) 
 + 
 +include(CTest) 
 +enable_testing() 
 + 
 +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c99 -g --coverage"
 + 
 +add_executable(foo foo.c) 
 + 
 +add_test(test1 ./foo 2) 
 +add_test(test2 ./foo 5) 
 +</code> 
 + 
 +  cmake . 
 +  make ExperimentalTest # ou make test 
 +  make ExperimentalCoverage 
 +  more Testing/CoverageInfo/
 + 
 +Il est plus élégant de n'activer le coverage que en mode DEBUG... 
 + 
 +<code text tests/CMakeLists.txt> 
 +cmake_minimum_required(VERSION 3.0) 
 + 
 +include(CTest) 
 +enable_testing() 
 + 
 +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99"
 +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -g --coverage"
 + 
 +add_executable(foo foo.c) 
 + 
 +add_test(test1 ./foo 2) 
 +add_test(test2 ./foo 5) 
 +</code> 
 + 
 + 
 +Il faut alors compiler le code en mode DEBUG (et non pas en mode RELEASE) : 
 + 
 +  cmake -DCMAKE_BUILD_TYPE=DEBUG . 
 +  make ExperimentalTest 
 +  make ExperimentalCoverage 
 +  more Testing/CoverageInfo/*
  
projtec/cmake.1485385132.txt.gz · Last modified: 2024/03/18 15:05 (external edit)