Spécifiez toujours la version minimale requise de cmake
cmake_minimum_required(VERSION 3.9)
Vous devez déclarer un projet. cmake
dit que c'est obligatoire et qu'il définira des variables pratiques PROJECT_NAME
, PROJECT_VERSION
et PROJECT_DESCRIPTION
(cette dernière variable nécessite cmake 3.9):
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
Déclarez une nouvelle cible de bibliothèque. Veuillez éviter l'utilisation de file(GLOB ...)
. Cette fonctionnalité ne permet pas une maîtrise assistée du processus de compilation. Si vous êtes paresseux, copiez-collez la sortie de ls -1 sources/*.cpp
:
add_library(mylib SHARED
sources/animation.cpp
sources/buffers.cpp
[...]
)
Définir la VERSION
propriété (facultatif mais c'est une bonne pratique):
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
Vous pouvez également définir SOVERSION
un nombre majeur de VERSION
. Ce libmylib.so.1
sera donc un lien symbolique vers libmylib.so.1.0.0
.
set_target_properties(mylib PROPERTIES SOVERSION 1)
Déclarez l'API publique de votre bibliothèque. Cette API sera installée pour l'application tierce. Il est recommandé de l'isoler dans l'arborescence de votre projet (comme en le plaçant dans le include/
répertoire). Notez que les en-têtes privés ne doivent pas être installés et je suggère fortement de les placer avec les fichiers source.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
Si vous travaillez avec des sous-répertoires, il n'est pas très pratique d'inclure des chemins relatifs comme "../include/mylib.h"
. Alors, passez un répertoire supérieur dans les répertoires inclus:
target_include_directories(mylib PRIVATE .)
ou
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
Créez une règle d'installation pour votre bibliothèque. Je suggère d'utiliser des variables CMAKE_INSTALL_*DIR
définies dans GNUInstallDirs
:
include(GNUInstallDirs)
Et déclarez les fichiers à installer:
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
Vous pouvez également exporter un pkg-config
fichier. Ce fichier permet à une application tierce d'importer facilement votre bibliothèque:
Créez un fichier modèle nommé mylib.pc.in
(voir la page de manuel pc (5) pour plus d'informations):
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Requires:
Libs: -L${libdir} -lmylib
Cflags: -I${includedir}
Dans votre CMakeLists.txt
, ajoutez une règle pour développer les @
macros ( @ONLY
demandez à cmake de ne pas développer les variables du formulaire ${VAR}
):
configure_file(mylib.pc.in mylib.pc @ONLY)
Et enfin, installez le fichier généré:
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
Vous pouvez également utiliser la fonction cmakeEXPORT
. Cependant, cette fonctionnalité n'est compatible qu'avec cmake
et je trouve difficile à utiliser.
Enfin l'ensemble CMakeLists.txt
devrait ressembler à:
cmake_minimum_required(VERSION 3.9)
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
include(GNUInstallDirs)
add_library(mylib SHARED src/mylib.c)
set_target_properties(mylib PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
PUBLIC_HEADER api/mylib.h)
configure_file(mylib.pc.in mylib.pc @ONLY)
target_include_directories(mylib PRIVATE .)
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)