Sempre especifique a versão mínima exigida do cmake
cmake_minimum_required(VERSION 3.9)
Você deve declarar um projeto. cmake
diz que é obrigatória e vai definir variáveis convenientes PROJECT_NAME
, PROJECT_VERSION
e PROJECT_DESCRIPTION
(esta última necessitate variável cmake 3.9):
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
Declare um novo destino de biblioteca. Por favor, evite o uso de file(GLOB ...)
. Esse recurso não fornece o domínio do processo de compilação. Se você é preguiçoso, copie e cole a saída de ls -1 sources/*.cpp
:
add_library(mylib SHARED
sources/animation.cpp
sources/buffers.cpp
[...]
)
Defina a VERSION
propriedade (opcional, mas é uma boa prática):
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
Você também pode definir SOVERSION
um número principal de VERSION
. Então libmylib.so.1
será um link simbólico para libmylib.so.1.0.0
.
set_target_properties(mylib PROPERTIES SOVERSION 1)
Declare a API pública da sua biblioteca. Essa API será instalada para o aplicativo de terceiros. É uma boa prática isolá-lo na árvore de projetos (como colocá-lo no include/
diretório). Observe que cabeçalhos privados não devem ser instalados e eu sugiro colocá-los com os arquivos de origem.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
Se você trabalha com subdiretórios, não é muito conveniente incluir caminhos relativos como "../include/mylib.h"
. Portanto, passe um diretório superior nos diretórios incluídos:
target_include_directories(mylib PRIVATE .)
ou
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
Crie uma regra de instalação para sua biblioteca. Sugiro usar variáveis CMAKE_INSTALL_*DIR
definidas em GNUInstallDirs
:
include(GNUInstallDirs)
E declare os arquivos para instalar:
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
Você também pode exportar um pkg-config
arquivo. Este arquivo permite que um aplicativo de terceiros importe facilmente sua biblioteca:
Crie um arquivo de modelo chamado mylib.pc.in
(consulte a página de manual do pc (5) para obter mais informações):
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}
No seu CMakeLists.txt
, adicione uma regra para expandir @
macros ( @ONLY
peça ao cmake para não expandir variáveis do formulário ${VAR}
):
configure_file(mylib.pc.in mylib.pc @ONLY)
E, finalmente, instale o arquivo gerado:
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
Você também pode usar o recurso cmakeEXPORT
. No entanto, esse recurso é compatível apenas cmake
e acho difícil de usar.
Finalmente, o conjunto CMakeLists.txt
deve se parecer com:
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)