This is an old revision of the document!
Table of Contents
CMake
Hello World
Considérons le petit exemple suivant :
Voici un fichier CMakeLists.txt minimaliste pour compiler ce petit projet :
- CMakeLists.txt
cmake_minimum_required(VERSION 2.6) project(HelloWorld) add_executable(hello hello.c)
Pour générer un Makefile et compiler notre projet “sur place”, il faut taper les commandes suivantes :
cmake . 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 peu plus compliqué
Considérons maintenant dans notre projet plusieurs fichiers sources (hello.c, pouet.c, pouet.h) et une bibliothèque extérieure (la library m associé à <math.h> qui contient la définition de la fonction sqrt()).
- hello.c
#include <stdio.h> #include "pouet.h" int main() { printf("Hello World!\n"); pouet(); return 0; }
- pouet.h
void pouet();
Voici donc le fichier CMakeLists.txt pour compiler tout cela. On a également ajouté des variables CMAKE par défaut : CMAKE_C_FLAGS et CMAKE_INSTALL_PREFIX pour le répertoire d'installation…
- CMakeLists.txt
cmake_minimum_required (VERSION 2.6) project (HelloWorld C) set(CMAKE_C_FLAGS "-std=c99 -g -Wall") set(CMAKE_INSTALL_PREFIX "install") add_executable(hello hello.c pouet.c) target_link_libraries(hello m) install(TARGETS hello RUNTIME DESTINATION bin)
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…
cmake . make make install # make install DESTDIR="/some/absolute/path"
Utilisation d'une bibliothèque interne
Considérons maintenant le projet cmake-v2.zip, dont la structure est décrit ci-dessous :
├── CMakeLists.txt ├── hello.c ├── mylib │ ├── CMakeLists.txt │ ├── mylib.c │ └── mylib.h ├── pouet.c └── pouet.h
Ce projet contient un éxecutable hello qui utilise la bibliothèque interne mylib définit par un second fichier CMakeLists.txt dans le sous-répertoire mylib. Voici donc les deux fichiers CMake :
- CMakeLists.txt
cmake_minimum_required (VERSION 2.6) project (HelloWorld C) set(CMAKE_C_FLAGS "-std=c99 -g -Wall") set(CMAKE_INSTALL_PREFIX "install") include_directories(mylib) # link_directories(mylib) add_executable(hello hello.c pouet.c) target_link_libraries(hello m mylib) install(TARGETS hello RUNTIME DESTINATION bin) add_subdirectory(mylib)
- mylib/CMakeLists.txt
add_library(mylib mylib.c) install(TARGETS mylib ARCHIVE DESTINATION lib) install(FILES mylib.h DESTINATION include)
Ensuite, on fait comme d'habitude…
cmake . make make install
On trouve alors dans le répertoire install les fichiers suivants :
├── bin │ └── hello ├── include │ └── mylib.h └── lib └── libmylib.a
Tests Unitaires
On ajoute à notre projet un sous-répertoire tests pour vérifier les fonctions de mylib (cmake-v3.zip).
├── CMakeLists.txt ├── hello.c ├── mylib │ ├── CMakeLists.txt │ ├── mylib.c │ └── mylib.h ├── pouet.c ├── pouet.h └── tests ├── CMakeLists.txt ├── test-mylib-bar.c └── test-mylib-foo.c
Voici le fichier CMake pour compiler et exécuter les tests…
- tests/CMakeLists.txt
enable_testing() add_executable(test-mylib-foo test-mylib-foo.c) target_link_libraries(test-mylib-foo mylib) add_executable(test-mylib-bar test-mylib-bar.c) target_link_libraries(test-mylib-bar mylib) add_test(test1 test-mylib-foo) set_tests_properties(test1 PROPERTIES TIMEOUT 3) set_tests_properties(test1 PROPERTIES PASS_REGULAR_EXPRESSION "foo") add_test(test2 test-mylib-bar) set_tests_properties(test2 PROPERTIES TIMEOUT 3) set_tests_properties(test2 PROPERTIES PASS_REGULAR_EXPRESSION "foo") add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
Bah vous connaissez la formule… Pour lancer les tests :
make check