Comment lier un programme C ++ avec Boost en utilisant CMake

109

À quoi mon fichier CMake doit-il ressembler pour lier mon programme à la bibliothèque Boost sous Ubuntu?

Les erreurs affichées lors de l'exécution make:

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

Le fichier principal est vraiment 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;
}

J'ai réussi à faire ça. Les seules lignes que j'ai ajoutées à mes fichiers CMake étaient:

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

Réponses:

150

Dans CMake, vous pouvez utiliser find_packagepour trouver les bibliothèques dont vous avez besoin. Il y a généralement un FindBoost.cmakeavec votre installation CMake.

Autant que je me souvienne, il sera installé /usr/share/cmake/Modules/avec d'autres scripts de recherche pour les bibliothèques courantes. Vous pouvez simplement consulter la documentation de ce fichier pour plus d'informations sur son fonctionnement.

Un exemple hors de ma tête:

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} )

J'espère que ce code vous aidera.

MOnsDaR
la source
2
Ajout d'un lien fonctionnel depuis le référentiel Kitwares Github. Ajout d'un lien vers la documentation officielle sur FindBoost.cmake
MOnsDaR
1
Pourquoi Boost 1.40 en particulier? Quand les fonctionnalités de base de la bibliothèque ont-elles cessé de changer?
jgyou
6
Parce que pourquoi pas? C'est juste un exemple ... Remplissez ce qui vous convient le mieux
MOnsDaR
5
Un détail important est de placer target_link_libraries après les lignes add_executable et find_package , afin que tous les composants liés soient connus.
Murphy
52

Voici ma configuration:

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
la source
7
Les link_directories ne sont pas obligatoires car Boost_LIBRARIES sera des chemins d'accès complets.
RobertJMaynard
Dans mon cas, link_directories était nécessaire.
mgruber4
25

En adaptant la réponse @MOnsDaR à la syntaxe CMake moderne avec des cibles importées, ce serait:

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

Notez qu'il n'est pas nécessaire de spécifier manuellement les répertoires d'inclusion, car cela est déjà pris en charge via la cible importée Boost::program_options.

oLen
la source
L'inconvénient de cette approche cible est que si votre version Boost est plus récente que votre version CMake, cela échouera probablement. The FindBoost.cmakene les construit à l'origine que s'il répertorie explicitement votre version Boost. À un moment donné, cela était censé être amélioré, mais je vois toujours des échecs avec CMake 3.10.2 et Boost 1.66 (les dernières copies de brew).
Henry Schreiner
4
stackoverflow commence à échouer car il y a tellement de réponses obsolètes qu'il est souvent difficile de trouver la bonne réponse (celle-ci).
Carlo Wood
3

Quelle bibliothèque Boost? Beaucoup d'entre eux sont de purs modèles et ne nécessitent pas de liaison.

Maintenant, avec cet exemple concret réellement montré qui nous indique que vous voulez des options de programme Boost (et encore plus nous dit que vous êtes sur Ubuntu), vous devez faire deux choses:

  1. Installez de libboost-program-options-devmanière à pouvoir établir un lien avec celui-ci.
  2. Dites cmakeà lier contre libboost_program_options.

J'utilise principalement Makefiles, voici donc l'utilisation directe de la ligne de commande:

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

Cela ne fait pas grand-chose semble-t-il.

Pour CMake, vous devez ajouter boost_program_options à la liste des bibliothèques, et IIRC cela se fait via SET(liblist boost_program_options)dans votre fichier CMakeLists.txt.

Dirk Eddelbuettel
la source
11
Votre conseil CMake est faux (voir la réponse acceptée) et votre conseil en ligne de commande n'est pas très utile car la question concernait CMake.
Ela782
3

Deux façons, en utilisant le chemin d'installation par défaut du système, généralement /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 vous installez Boost dans un répertoire local ou choisissez l'installation locale au lieu de l'installation du système, vous pouvez le faire de la manière suivante:

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}
        )

Notez que le répertoire ci-dessus /home/xy/boost_install/lib/est l'endroit où j'installe 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 vous souhaitez savoir comment utiliser un Boost installé localement, vous pouvez voir cette question Comment puis-je demander à CMake de trouver mon autre installation Boost? .

Jayhello
la source
2

Voici ma prise:

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
la source
target_link_libraries (helloworld PUBLIC Boost :: program_options) donnera une erreur CMAKE: - Configuration terminée Erreur CMake à CMakeLists.txt: 102 (add_executable): cible "DB32" liens vers la cible "Boost :: program_options" mais la cible n'a pas été trouvée . Peut-être qu'un appel find_package () est manquant pour une cible IMPORTÉE, ou une cible ALIAS est manquante?
munsingh le
Salut, merci pour les commentaires. Il semble que CMake ne puisse pas localiser Boost sur votre système. Vous feriez peut-être mieux de faire une nouvelle version du Boost à partir de la source. Avant cela, vous voudrez peut-être essayer ce qui suit: Trouvez le package avec find_package(Boost QUIET REQUIRED)et lien vers votre cible (DB32):target_link_libraries(DB32 PUBLIC Boost::headers)
adem le