Especifique siempre la versión mínima requerida de cmake
cmake_minimum_required(VERSION 3.9)
Deberías declarar un proyecto. cmake
dice que es obligatorio y definirá variables convenientes PROJECT_NAME
, PROJECT_VERSION
y PROJECT_DESCRIPTION
(esta última variable necesita cmake 3.9):
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
Declarar un nuevo objetivo de biblioteca. Por favor, evite el uso de file(GLOB ...)
. Esta característica no proporciona dominio asistido del proceso de compilación. Si eres flojo, copia y pega la salida de ls -1 sources/*.cpp
:
add_library(mylib SHARED
sources/animation.cpp
sources/buffers.cpp
[...]
)
Establecer VERSION
propiedad (opcional pero es una buena práctica):
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
También puede establecer SOVERSION
un número mayor de VERSION
. Entonces libmylib.so.1
será un enlace simbólico a libmylib.so.1.0.0
.
set_target_properties(mylib PROPERTIES SOVERSION 1)
Declara la API pública de tu biblioteca. Esta API se instalará para la aplicación de terceros. Es una buena práctica aislarlo en su árbol de proyecto (como colocarlo en el include/
directorio). Tenga en cuenta que no se deben instalar encabezados privados y le sugiero que los coloque con los archivos de origen.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
Si trabaja con subdirectorios, no es muy conveniente incluir rutas relativas como "../include/mylib.h"
. Entonces, pase un directorio superior en los directorios incluidos:
target_include_directories(mylib PRIVATE .)
o
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
Cree una regla de instalación para su biblioteca. Sugiero usar variables CMAKE_INSTALL_*DIR
definidas en GNUInstallDirs
:
include(GNUInstallDirs)
Y declarar archivos para instalar:
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
También puede exportar un pkg-config
archivo. Este archivo permite que una aplicación de terceros importe fácilmente su biblioteca:
Crear un archivo de plantilla llamada mylib.pc.in
(ver PC (5) página de manual para más información):
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}
En su CMakeLists.txt
, agregue una regla para expandir las @
macros ( @ONLY
solicite cmake para no expandir las variables del formulario ${VAR}
):
configure_file(mylib.pc.in mylib.pc @ONLY)
Y finalmente, instale el archivo generado:
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
También puede usar la función cmakeEXPORT
. Sin embargo, esta función solo es compatible cmake
y me resulta difícil de usar.
Finalmente todo CMakeLists.txt
debería verse así:
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)