15 mai 2024
Ce cours a pour vocation d’introduire à l’outil CMake en s’appuyant sur l’expérience acquise par Michel Simatic dans l’utilisation de CMake pour le cours CSC4526 de Télécom SudParis. Ce cours n’est donc qu’une introduction forcément partielle, mais qui permet quand même un bon survol des possibilités de CMake.
Décompressez l’archive SampleSFML.zip dans le répertoire de votre choix (par exemple, dans C:\users\votre_login\CSC4526
).
cd cheminVersLeRepertoireSampleSFML
mkdir buildUnix
cd buildUnix
cmake ..
cmake -- build . # Vous pouvez aussi taper la commande: make
src/sample # sous Linux (bin/sample sous MacOS)
_deps
contient le résultat de la récupération des sources SFML à partir de cette archive https://github.com/SFML/SFML/archive/refs/tags/2.6.1.tar.gz (cf. fichier CMakeLists.txt
racine).buildUnix
. Il suffit d’effacer ce répertoire pour s’en débarrasser.cmake
de ce document.cmake-build-debug
..idea
qui contient les données de travail de CLion sur ce projet (par exemple, l’indexation des fichiers).cmake-build-debug
et .idea
.cd cheminVersLeRepertoireSampleSFML
mkdir buildWindows
cd buildWindows
cmake ..
cmake --build . # Vous pouvez aussi taper la commande: MSBuild.exe .\JIN4_SampleSFML.sln
.\src\Debug\sample.exe
# NB : Si la fenêtre de commande a été lancée en dehors de Visual Studio, il faut exécuter
# la commande suivante pour correctement initialiser la variable d'environnement Path (pour voir
# le contenu de cette variable, tapez la commande : echo $env:path ) et donc accéder à tous les
# outils VisualStudio) :
# C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat amd64
# (NB : Ne fonctionne pas sous PowerShell ; en cours d'investigation)
_deps
contient le résultat de la récupération des sources SFML à partir de cette archive https://github.com/SFML/SFML/archive/refs/tags/2.6.1.tar.gz (cf. fichier CMakeLists.txt
racine).buildWindows
. Il suffit d’effacer ce répertoire pour s’en débarrasser.cmake
de ce document..out
..vs
qui contient les données de travail de CLion sur ce projet (par exemple, l’indexation des fichiers).out
et .vs
.CMakeLists.txt
CMakeLists.txt
à écrire. Nous les détaillons ci-après.CMakeLists.txt
globalSampleSFML/CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
Spécifie que vous avez au moins besoin de CMake 3.15 pour votre projet. NB : Dans CSC4526, on a besoin d’avoir au moins la version 3.15 de CMake pour disposer du module CMake FetchContent
.
cmake_policy(VERSION 3.15)
Désormais inutile, car, à partir de CMake version 2.4, “The cmake_minimum_required(VERSION) command implicitly invokes the cmake_policy(VERSION) command” (cf. https://cmake.org*CMake*help/latest/command/cmake_minimum_required.html)
include(FetchContent)
Spécifie qu’on utilise le module CMake FetchContent
.
project(JIN4_SampleSFML VERSION 1.0.0 LANGUAGES CXX)
Spécifie le nom de votre projet dans l’outil de construction (cf. JIN4_SampleSFML.sln), sa version et les langages informatiques utilisés pour votre projet.
IF(WIN32)
, else()
et endif()
Permettent une génération conditionnelle
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
Permet de positionner un flag de génération CMake dont SonarLint a besoin, sous Windows, pour travailler correctement après.
set (BUILD_SHARED_LIBS FALSE)
Indique à CMake de générer des bibliothèques statiques (et non dynamiques). Ainsi, même si les exécutables résultant sont plus gros, il n’y a rien à configurer au niveau du système d’exploitation des développeurs·ses pour que l’exécution puisse se faire correctement.
find_package
Demande à CMake de vérifier que ces bibliothèques sont bien installées sur la machine.
include_directories
Pour les futures compilation, configure le compilateur pour qu’il référence les répertoires en paramètre en tant que répertoires d’include.
FetchContent_Declare
Cette commande spécifie comment récupérer une bibliothèque externe (son repository GIT et la branche/tag de version à utiliser ou bien l’URL où récupérer une archive).
cet article explique qu’il est beaucoup plus performant de récupérer un projet via l’URL d’une archive que via un dépôt GIT (qui fait un git clone
). Dit autrement, préférez:
FetchContent_Declare(
sfml
URL https://github.com/SFML/SFML/archive/refs/tags/2.6.1.tar.gz )
à
FetchContent_Declare(
sfml
GIT_REPOSITORY https://github.com/SFML/SFML.git
GIT_TAG 2.6.1 )
Les tests que nous avons faits sur la bibliothèque cereal confirment cette opinion :
FetchContent_Declare
avec paramètre GIT_REPOSITORY
==> elapsed = 2.02 secondes ; CPU = 3.02 secondesFetchContent_Declare
avec paramètre URL
==> elapsed = 0.65 seconde ; CPU ~ 0 secondesSeul bémol sur l’utilisation d’une URL par rapport à l’utilisation d’un dépôt GIT, le FetchContent_Declare
doit être précédé par :
cmake_policy(SET CMP0135 NEW) # This cmake_policy avoids warning by cmake when we fetch contents based on URL
FetchContent_MakeAvailable
Cette commande récupère effectivement une bibliothèque externe.
set(CMAKE_CXX_STANDARD 20)
Spécifie que CMake doit dire au compilateur d’autoriser les spécificités du C++20 (ce qui inclut C++11, C++14, C++20, mais pas C++23).
add_subdirectory(sample)
Ajoute le sous-répertoire sample
à la construction.
enable_testing()
Permet de spécifier qu’il y aura des fichiers pour les tests dans le répertoire courant et ses sous-répertoires. NB : Pour que l’explorateur de tests de Visual Studio travaille correctement, cette instruction doit absolument :
CMakeLists.txt
de plus haut niveau (cf. documentation cmake),include(GoogleTest)
dans le CMakeLists.txt
de plus haut niveau (cf. ce ticket).CMakeLists.txt
par entité logicielleSampleSFML/sample/CMakeLists.txt
file(GLOB SOURCES CONFIGURE_DEPENDS #.h #.cpp)
Spécifie une variable CMake qui contient la liste de tous les fichiers .h
et .cpp
de votre répertoire courant.
NB : Certain·e·s “pro” de cmake déconseillent d’utiliser cette instruction. Iels disent qu’il vaut mieux lister explicitement les fichiers.
add_executable
Spécifie que votre entité logicielle générée est un exécutable du nom de sample
construit avec tous les fichiers issus de la liste de fichiers dans la variable CMake SOURCES
.
target_link_libraries(sample PUBLIC sfml-graphics)
Spécifie que, pour construire votre entité logicielle sample
, vous aurez besoin de faire l’édition de liens avec la bibliothèque sfml-graphics
(et donc, implicitement, que vous aurez besoin des include SFML pour la compilation de vos .cpp
build
et en tapant la commande ctest
.add_library(sqlite sqlite3.c)
set_target_properties(sqlite PROPERTIES LINKER_LANGUAGE CXX)
-pthread
pour obtenir un exécutable Unix multithreadé):add_executable(02_CounterMultithread
Source_02.cpp
)if (UNIX)
target_link_options(02_CounterMultithread PUBLIC -pthread)
endif()
if (MSVC)
# warning level 4 (see https://docs.microsoft.com/fr-fr/cpp/build/reference/compiler-option-warning-level?view=vs-2019)
# We do not put /WX to consider all warnings as errors
add_compile_options(/W4)
else()
# lots of warnings
# We do not put -Werror to consider all warnings as errors
add_compile_options(-g -Wall -Wextra)
endif()
add_custom_target(copy-Media ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Media)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Media
DEPENDS ${CMAKE_SOURCE_DIR}/Media
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/Media
${CMAKE_CURRENT_BINARY_DIR}/Media
)add_dependencies(my_executable copy-Media)
set (PHOTON_DIR "C:/Software/Photon-Windows-Sdk_v4-1-16-3")
if(MSVC)
find_library(PHOTON_COMMON Common-cpp_vc16_debug_windows_md_x64.lib PATHS ${PHOTON_DIR}/Common-cpp/lib REQUIRED)
find_library(PHOTON_PHOTON Photon-cpp_vc16_debug_windows_md_x64.lib PATHS ${PHOTON_DIR}/Photon-cpp/lib REQUIRED)
find_library(PHOTON_LOADBALANCING LoadBalancing-cpp_vc16_debug_windows_md_x64.lib PATHS ${PHOTON_DIR}/LoadBalancing-
cpp/lib REQUIRED)elseif(APPLE)
find_library(PHOTON_COMMON libCommon-cpp_debug_macosx.a PATHS ${PHOTON_DIR}/Common-cpp/lib REQUIRED)
find_library(PHOTON_PHOTON libPhoton-cpp_debug_macosx.a PATHS ${PHOTON_DIR}/Photon-cpp/lib REQUIRED)
find_library(PHOTON_LOADBALANCING libLoadBalancing-cpp_debug_macosx.a PATHS ${PHOTON_DIR}/LoadBalancing-cpp/lib REQU
IRED)else()
# Linux
find_library(PHOTON_COMMON libCommonDebug64.a PATHS ${PHOTON_DIR}/Common-cpp REQUIRED)
find_library(PHOTON_PHOTON libPhotonDebug64.a PATHS ${PHOTON_DIR}/Photon-cpp REQUIRED)
find_library(PHOTON_LOADBALANCING libLoadBalancingDebug64.a PATHS ${PHOTON_DIR}/LoadBalancing-cpp REQUIRED)
endif()
target_link_libraries(Multi_Photon_V0 PUBLIC sfml-graphics ${PHOTON_LOADBALANCING} ${PHOTON_PHOTON} ${PHOTON_COMMON} )
Ce tutoriel est très complet (il explique notamment comment construire un package d’installation avec l’instruction cpack
).