CMake par Exemple

Mirko Kiefer
22 février 2017 · 4 min de lecture

div>

En essayant d’apprendre CMake, je n’ai pas trouvé de bonne introduction. La documentation CMake est assez complète mais ne convient pas à un débutant. Il y a quelques tutoriels utiles liés sur le Wiki CMake mais la plupart d’entre eux ne couvrent que des problèmes très spécifiques ou sont trop basiques. J’ai donc écrit cette courte introduction à CMake comme une version distillée de ce que j’ai découvert après avoir parcouru les documents et suivi les questions de stackoverflow.

C’est un travail en cours et je vais essayer de l’améliorer continuellement.

CMake est un outil de méta-génération qui vous permet de générer des scripts de génération natifs pour une gamme de plates-formes :

  • Makefiles Unix
  • Xcode
  • Visual Studio
  • Blocs de codes
  • Eclipse
  • et plus encoreSee

Voir la liste complète des générateurs CMake.

Supposons que nous ayons une application simple avec un seul.fichier c.

Nous en créant un fichier CMakeLists.txt à la racine de notre projet.

cmake_minimum_required(VERSION 2.8)project(app_project)add_executable(myapp main.c)install(TARGETS myapp DESTINATION bin)

C’est tout ce dont nous avons besoin pour pouvoir créer notre application avec l’un des générateurs disponibles.

add_executable définit notre binaire avec tous les fichiers sources liés.

install indique à cmake d’installer notre binaire dans le répertoire bin du répertoire d’installation.

Construction

CMake prend en charge les builds hors source – donc tout notre code compilé va dans un répertoire séparé des sources.

Pour démarrer une génération, nous créons un nouveau dossier:

mkdir _build
cd _build

Et appelons cmake avec le chemin d’accès à la racine du projet (dans ce cas, le dossier parent):

cmake ..

Cela générera des scripts de génération en utilisant le générateur par défaut — sous Linux / OSX, il devrait s’agir de Makefiles.

Par défaut, cmake installera notre build dans les répertoires système.
Pour définir un répertoire d’installation personnalisé, nous le transmettons simplement à cmake:

cmake .. -DCMAKE_INSTALL_PREFIX=../_install

Pour exécuter le script de construction, vous pouvez simplement utiliser le Makefile:

make
make install

Nous pouvons maintenant exécuter notre binaire à partir du répertoire d’installation:

../_install/bin/myapp

Si nous voulions utiliser un générateur différent, nous le transmettons à cmake en utilisant le paramètre -G:

cmake .. -GXcode

Cela produira un projet Xcode facilement configuré pour créer notre application.

En utilisant CMake avec des bibliothèques

Pour construire une bibliothèque, nous utilisons un script similaire:

cmake_minimum_required(VERSION 2.8)project(libtest_project)add_library(test STATIC test.c)install(TARGETS test DESTINATION lib)
install(FILES test.h DESTINATION include)

CMake construira la bibliothèque sous la forme libtest.a et l’installera dans le dossier lib du répertoire d’installation.
Nous incluons également notre fichier d’en-tête public dans l’étape d’installation et demandons à cmake de le mettre dans include.

Au lieu d’une bibliothèque statique, nous pouvons également créer une bibliothèque partagée :

add_library(test SHARED test.c)

Reliant les bibliothèques aux exécutables avec CMake

Nous pouvons étendre notre exécutable d’en haut en le liant à notre libray libtest.a.

Commençons par ajouter le répertoire de la bibliothèque en tant que sous-répertoire à notre projet myapp.

Maintenant, nous pouvons utiliser la bibliothèque définie dans CMakeLists.txt de libtest_project dans les listes CMakeLists de myapp.txt:

cmake_minimum_required(VERSION 2.8)project(myapp)add_subdirectory(libtest_project)add_executable(myapp main.c)target_link_libraries(myapp test)install(TARGETS myapp DESTINATION bin)

add_subdirectory rend la bibliothèque test définie dans libtestproject disponible pour la génération.
Dans target_link_libraries nous disons à CMake de le lier à notre exécutable. CMake s’assurera d’abord de construire le test avant de le lier à myapp.

Y compris les bibliothèques externes utilisant d’autres systèmes de génération

Bien que CMake suscite un intérêt croissant, il existe encore de nombreuses bibliothèques utilisant des systèmes de génération natifs comme les Makefiles Unix. Vous pouvez les utiliser dans votre projet CMake sans avoir à réécrire leurs scripts de construction.

Tout ce dont nous avons besoin est le support de CMake pour les projets externes et les bibliothèques importées:

ExternalProject_Add(project_luajit
URL http://luajit.org/download/LuaJIT-2.0.1.tar.gz
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/luajit-2.0.1
CONFIGURE_COMMAND ""
BUILD_COMMAND make
INSTALL_COMMAND make install
PREFIX=${CMAKE_CURRENT_BINARY_DIR}/luajit-2.0.1
)ExternalProject_Get_Property(project_luajit install_dir)add_library(luajit STATIC IMPORTED)set_property(TARGET luajit PROPERTY IMPORTED_LOCATION ${install_dir}/lib/libluajit-5.1.a)add_dependencies(luajit project_luajit)add_executable(myapp main.c)include_directories(${install_dir}/include/luajit-2.0)target_link_libraries(myapp luajit)

ExternalProject_Add nous permet d’ajouter un projet externe comme cible à notre projet. Si vous ne spécifiez pas de commandes comme BUILD_COMMAND ou INSTALL_COMMAND, CMake recherchera un CMakeLists.txt dans le projet externe et l’exécutera.
Dans notre cas, nous voulons utiliser la bibliothèque luajit qui est construite à l’aide d’un Makefile.

add_library prend également en charge l’importation de bibliothèques déjà construites – il suffit de définir sa propriété IMPORTED_LOCATION.
Appeler ExternalProject_Add spécifie uniquement le projet externe en tant que cible mais ne le construit pas automatiquement. Il ne sera construit que si nous y ajoutons une dépendance. Nous appelons donc add_dependencies pour rendre notre bibliothèque importée dépendante du projet externe.

Enfin, nous pouvons lier notre bibliothèque importée comme une bibliothèque « normale” avec target_link_libraries.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *