Cómo vincular el programa C ++ con Boost usando CMake

109

¿Cómo debería verse mi archivo CMake para vincular mi programa con la biblioteca Boost en Ubuntu?

Los errores que se muestran durante la ejecución make:

main.cpp:(.text+0x3b): undefined reference to `boost::program_options::options_description::m_default_line_length'

El archivo principal es realmente simple:

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/option.hpp>
using namespace std;
#include <iostream>

namespace po = boost::program_options;

int main(int argc, char** argv) {

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ;

    return 0;
}

Me las he arreglado para hacer eso. Las únicas líneas que agregué a mis archivos CMake fueron:

target_link_libraries(
my_target_file
${Boost_PROGRAM_OPTIONS_LIBRARY}
)
Szymon Lipiński
fuente

Respuestas:

150

En CMake puede utilizar find_packagepara encontrar las bibliotecas que necesita. Por lo general, hay un FindBoost.cmakejunto con la instalación de CMake.

Por lo que recuerdo, se instalará /usr/share/cmake/Modules/junto con otros scripts de búsqueda para bibliotecas comunes. Puede consultar la documentación en ese archivo para obtener más información sobre cómo funciona.

Un ejemplo fuera de mi cabeza:

FIND_PACKAGE( Boost 1.40 COMPONENTS program_options REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )

ADD_EXECUTABLE( anyExecutable myMain.cpp )

TARGET_LINK_LIBRARIES( anyExecutable LINK_PUBLIC ${Boost_LIBRARIES} )

Espero que este código te ayude.

MOnsDaR
fuente
2
Se agregó un enlace de trabajo desde el repositorio de Kitwares Github. También se agregó un enlace a la documentación oficial sobre FindBoost.cmake
MOnsDaR
1
¿Por qué Boost 1.40 en particular? ¿Cuándo dejaron de cambiar las funcionalidades básicas de la biblioteca?
jgyou
6
¿Porque, porque no? Es solo un ejemplo ... Complete lo que más le convenga
MOnsDaR
5
Un detalle importante es colocarlo target_link_libraries después de las líneas add_executable y find_package , para que se conozcan todos los componentes vinculados.
Murphy
52

La siguiente es mi configuración:

cmake_minimum_required(VERSION 2.8)
set(Boost_INCLUDE_DIR /usr/local/src/boost_1_46_1)
set(Boost_LIBRARY_DIR /usr/local/src/boost_1_46_1/stage/lib)
find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})

add_executable(main main.cpp)
target_link_libraries( main ${Boost_LIBRARIES} )
Dean Chen
fuente
7
No se requiere link_directories ya que Boost_LIBRARIES serán rutas completamente calificadas.
RobertJMaynard
En mi caso, link_directories era necesario.
mgruber4
25

Adaptando la respuesta @MOnsDaR para la sintaxis de CMake moderna con destinos importados, esto sería:

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

Tenga en cuenta que no es necesario especificar los directorios de inclusión manualmente, ya que ya se realiza a través del destino importado Boost::program_options.

oLen
fuente
La desventaja de este enfoque de destino es que si su versión de Boost es más nueva que su versión de CMake, esto probablemente fallará. The FindBoost.cmakeoriginalmente los compila solo si enumera explícitamente su versión de Boost. En algún momento se suponía que esto iba a mejorar, pero sigo viendo fallas con CMake 3.10.2 y Boost 1.66 (copias más recientes de brew).
Henry Schreiner
4
stackoverflow comienza a fallar porque hay tantas respuestas desactualizadas que a menudo es difícil encontrar la respuesta correcta (esta).
Carlo Wood
3

¿Qué biblioteca de Boost? Muchos de ellos son plantillas puras y no requieren vinculación.

Ahora, con ese ejemplo concreto que realmente se muestra que nos dice que desea las opciones del programa Boost (y aún más nos dice que está en Ubuntu), debe hacer dos cosas:

  1. Instálelo libboost-program-options-devpara que pueda vincularlo.
  2. Dile cmakeque se vincule contra libboost_program_options.

Principalmente uso Makefiles, así que aquí está el uso directo de la línea de comandos:

$ g++ boost_program_options_ex1.cpp -o bpo_ex1 -lboost_program_options
$ ./bpo_ex1
$ ./bpo_ex1 -h
$ ./bpo_ex1 --help
$ ./bpo_ex1 -help
$

Parece que no hace mucho.

Para CMake, debe agregar boost_program_options a la lista de bibliotecas, y IIRC esto se hace a través SET(liblist boost_program_options)de su CMakeLists.txt.

Dirk Eddelbuettel
fuente
11
Su consejo de CMake es incorrecto (vea la respuesta aceptada) y su consejo de línea de comandos no es muy útil ya que la pregunta era sobre CMake.
Ela782
3

De dos formas, utilizando la ruta de instalación predeterminada del sistema, normalmente /usr/lib/x86_64-linux-gnu/:

find_package(Boost REQUIRED regex date_time system filesystem thread graph)
include_directories(${BOOST_INCLUDE_DIRS})
message("boost lib: ${Boost_LIBRARIES}")
message("boost inc:${Boost_INCLUDE_DIR}")

add_executable(use_boost use_boost.cpp)
target_link_libraries(use_boost
        ${Boost_LIBRARIES}
        )

Si instala Boost en un directorio local o elige la instalación local en lugar de la instalación del sistema, puede hacerlo así:

set( BOOST_ROOT "/home/xy/boost_install/lib/" CACHE PATH "Boost library path" )
set( Boost_NO_SYSTEM_PATHS on CACHE BOOL "Do not search system for Boost" )

find_package(Boost REQUIRED regex date_time system filesystem thread graph)
include_directories(${BOOST_INCLUDE_DIRS})
message("boost lib: ${Boost_LIBRARIES}, inc:${Boost_INCLUDE_DIR}")

add_executable(use_boost use_boost.cpp)
target_link_libraries(use_boost
        ${Boost_LIBRARIES}
        )

Tenga en cuenta que el directorio anterior /home/xy/boost_install/lib/es donde instalo Boost:

xy@xy:~/boost_install/lib$ ll -th
total 16K
drwxrwxr-x 2 xy xy 4.0K May 28 19:23 lib/
drwxrwxr-x 3 xy xy 4.0K May 28 19:22 include/

xy@xy:~/boost_install/lib$ ll -th lib/
total 57M
drwxrwxr-x 2 xy xy 4.0K May 28 19:23 ./
-rw-rw-r-- 1 xy xy 2.3M May 28 19:23 libboost_test_exec_monitor.a
-rw-rw-r-- 1 xy xy 2.2M May 28 19:23 libboost_unit_test_framework.a
.......

xy@xy:~/boost_install/lib$ ll -th include/
total 20K
drwxrwxr-x 110 xy xy  12K May 28 19:22 boost/

Si está interesado en cómo usar un Boost instalado localmente, puede ver esta pregunta ¿Cómo puedo hacer que CMake encuentre mi instalación Boost alternativa? .

Jayhello
fuente
2

Aquí está mi opinión:

cmake_minimum_required(VERSION 3.15)

project(TryOuts LANGUAGES CXX)

find_package(Boost QUIET REQUIRED COMPONENTS program_options)

if(NOT Boost_FOUND)
    message(FATAL_ERROR "Boost Not found")
endif()

add_executable(helloworld main.cpp)

target_link_libraries(helloworld PUBLIC Boost::program_options)
además
fuente
target_link_libraries (helloworld PUBLIC Boost :: program_options) dará un error de CMAKE: - Configuración realizada CMake Error en CMakeLists.txt: 102 (add_executable): enlaces de destino "DB32" al destino "Boost :: program_options" pero no se encontró el destino . ¿Quizás falta una llamada find_package () para un objetivo IMPORTADO, o falta un objetivo ALIAS?
munsingh
Hola, gracias por los comentarios. Parece que CMake no puede localizar Boost en su sistema. Tal vez sea mejor hacer una nueva versión del Boost desde la fuente. Antes de eso, es posible que desee probar lo siguiente: Busque el paquete con find_package(Boost QUIET REQUIRED)y enlace a su destino (DB32):target_link_libraries(DB32 PUBLIC Boost::headers)
adem el