Una biblioteca en C++
es una colección de funcionalidades cuyas declaraciones
suelen estar agrupadas en archivos de cabecera; una biblioteca puede estar
compuesta de múltiples archivos de cabecera.
Las implementaciones suelen estar en archivos de código fuente separados del
archivo de cabecera; cuando la implementación se encuentra adentro se conoce
como solo-cabecera o header-only e implica que toda la lógica está expuesta y
no se genera una unidad de compilación; este suele ser el caso de
funcionalidades definidas en plantillas.
Aunque al ser header-only también es una reunión de funcionalidades que se
considera como una biblioteca, esta definición se encuentra en un área gris
puesto que no genera un fichero de biblioteca: .lib
, .dll
, .a
, .dylib
,
o .so
.
Excluyendo las header-only, los dos tipos de bibliotecas usualmente creadas
en C++
son: estáticas y dinámicas (compartidas). A diferencia de los binarios
ejecutables, estas no tienen punto de entrada main
definido.
Es posible crear un proyecto de CMake
para que contenga como objetivos:
- Solamente una biblioteca.
- Un ejecutable que use una o varias bibliotecas internas.
- Un ejecutable que use una o varias bibliotecas externas.
Sólo biblioteca
No tiene un punto de entrada definido, sin embargo, en caso de tener pruebas
unitarias se podrá definir un punto de entrada en éstas.
Para establecer que un objetivo (target) es una biblioteca en un proyecto
con CMake
se usa el comando de agregar biblioteca, como se puede ver en
Compilación simplificada con CMake,
y posteriormente se le indican los archivos de código fuente que debe incluir:
# CMakeLists.txt
# ...
project(solo_biblioteca)
# ...
# Crear el objetivo como biblioteca dinámica
add_library("${PROJECT_NAME}_dinamica" SHARED )
# Crear el objetivo como biblioteca estática
add_library("${PROJECT_NAME}_estatica" STATIC )
# Incluir los archivos en el objetivo
target_sources("${PROJECT_NAME}_dinamica" PUBLIC foo.cpp)
target_sources("${PROJECT_NAME}_estatica" PUBLIC bar.cpp)
# ...
En un sistema Linux se generan las bibliotecas libsolo_biblioteca_dinamica.so
y libsolo_biblioteca_estatica.a
.
Dentro del mismo proyecto
Un proyecto puede tener tanto un objetivo ejecutable, como múltiples objetivos de bibliotecas enlazadas a éste:
# CMakeLists.txt
# ...
project(biblioteca_adentro)
# ...
# Crear el objetivo de la biblioteca
add_library("${PROJECT_NAME}" SHARED foo.cpp )
# Crear el objetivo del ejecutable
add_executable("${PROJECT_NAME}_runner" main.cpp )
# ...
# Enlazar la biblioteca al objetivo ejecutable
target_link_libraries("${PROJECT_NAME}_runner" biblioteca_adentro)
# ...
El objetivo biblioteca_adentro_runner
que contiene el punto de entrada
consume las funcionalidades de la biblioteca incluida en el proyecto.
En un sistema Linux se generan la biblioteca libbiblioteca_adentro.so
y
el ejecutable biblioteca_adentro_runner
.
Fuera del proyecto
Si se requiere usar una biblioteca que ya está creada, ya sea propia o por
terceros, hay varias opciones para incluirla en el proyecto; la manera
tradicional es tener el paquete de la biblioteca descargado y compilado, y
buscarlo desde el proyecto para enlazarlo; una manera moderna es usar un
administrador de paquetes como Conan
o vcpkg
.
Usando Conan
, como se puede ver en:
Conan como administrador de paquetes,
basta con agregar la configuración básica de conan y enlazar las bibliotecas
a usar:
# CMakeLists.txt
# ...
# Agregar configuración de conan
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
# Enlazar
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
# ...
Consideraciones
- Además de las opciones
STATIC
(para estática) ySHARED
(para dinámica) existe la opciónINTERFACE
pero está fuera del alcance de esta publicación. - Versión CMake > 3.0
Recursos
- Documentación oficial CMake: Add library
- Documentación oficial CMake: Link libraries
Deja un comentario