web-dev-qa-db-fra.com

Comment ajouter des bibliothèques Boost dans CMakeLists.txt?

Je dois ajouter des bibliothèques Boost à mon CMakeLists.txt. Comment faites-vous ou comment l'ajoutez-vous?

108
laksh

Mettez ceci dans votre fichier CMakeLists.txt (Changez les options de OFF à ON si vous le souhaitez):

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
find_package(Boost 1.45.0 COMPONENTS *boost libraries here*) 

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS}) 
    add_executable(progname file1.cxx file2.cxx) 
    target_link_libraries(progname ${Boost_LIBRARIES})
endif()

Évidemment, vous devez mettre les bibliothèques de votre choix là où je mets *boost libraries here*. Par exemple, si vous utilisez la bibliothèque filesystem et regex, vous écrirez:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)
157
LainIwakura

Vous pouvez utiliser find_package pour rechercher les librairies boost disponibles. Il diffère la recherche de Boost sur FindBoost.cmake , qui est installé par défaut avec CMake.

Après avoir trouvé Boost, l’appel find_package() aura rempli de nombreuses variables (vérifiez la référence pour FindBoost.cmake ). Parmi celles-ci figurent les variables BOOST_INCLUDE_DIRS, Boost_LIBRARIES et Boost_XXX_LIBRARY, XXX étant remplacé par des bibliothèques Boost spécifiques. Vous pouvez les utiliser pour spécifier include_directories et target_link_libraries .

Par exemple, supposons que vous ayez besoin de boost :: program_options et de boost :: regex, vous feriez quelque chose comme:

find_package( Boost REQUIRED COMPONENTS program_options regex )
include_directories( ${Boost_INCLUDE_DIRS} )
add_executable( run main.cpp ) # Example application based on main.cpp

# Alternatively you could use ${Boost_LIBRARIES} here.
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )

Quelques conseils généraux:

  • Lors de la recherche, FindBoost vérifie la variable d’environnement $ ENV {BOOST_ROOT}. Vous pouvez définir cette variable avant d'appeler find_package si nécessaire.
  • Lorsque vous disposez de plusieurs versions de build de boost (multi-thread, statique, partagée, etc.), vous pouvez spécifier la configuration souhaitée avant d'appeler find_package. Pour ce faire, définissez certaines des variables suivantes sur On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED, Boost_USE_STATIC_RUNTIME
  • Lorsque vous recherchez Boost sous Windows, veillez à la liaison automatique. Lisez la "NOTE destinée aux utilisateurs de Visual Studio" dans le référence .
    • Mon conseil est de désactiver la liaison automatique et d'utiliser la gestion des dépendances de cmake: add_definitions( -DBOOST_ALL_NO_LIB )
    • Dans certains cas, vous devrez peut-être spécifier explicitement qu’un boost dynamique est utilisé: add_definitions( -DBOOST_ALL_DYN_LINK )
73
André

Adapter la réponse de @ LainIwakura pour la syntaxe CMake moderne aux cibles importées serait le suivant:

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
find_package(Boost 1.45.0 COMPONENTS filesystem regex) 

if(Boost_FOUND)
    add_executable(progname file1.cxx file2.cxx) 
    target_link_libraries(progname Boost::filesystem Boost::regex)
endif()

Notez qu'il n'est plus nécessaire de spécifier manuellement les répertoires d'inclusion, ceux-ci étant déjà pris en charge via les cibles importées Boost::filesystem et Boost::regex.
regex et filesystem peuvent être remplacés par toutes les bibliothèques boost dont vous avez besoin.

20
oLen

Puisse cela être utile pour certaines personnes. J'ai eu une erreur coquine: référence indéfinie au symbole '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: erreur lors de l'ajout de symboles: DSO manquant de la ligne de commande ici Il y avait un problème avec cmakeList.txt et il me manquait quelque part d’inclure explicitement les bibliothèques "système" et "système de fichiers". J'ai donc écrit ces lignes dans CMakeLists.txt

Ces lignes sont écrites au début avant de créer le fichier exécutable du projet, car à ce stade, nous n'avons pas besoin de lier la bibliothèque boost à notre fichier exécutable.

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
set(Boost_NO_SYSTEM_PATHS TRUE) 

if (Boost_NO_SYSTEM_PATHS)
  set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../3p/boost")
  set(BOOST_INCLUDE_DIRS "${BOOST_ROOT}/include")
  set(BOOST_LIBRARY_DIRS "${BOOST_ROOT}/lib")
endif (Boost_NO_SYSTEM_PATHS)


find_package(Boost COMPONENTS regex date_time system filesystem thread graph program_options) 

find_package(Boost REQUIRED regex date_time system filesystem thread graph program_options)
find_package(Boost COMPONENTS program_options REQUIRED)

Maintenant, à la fin du fichier, j'ai écrit ces lignes en considérant "KeyPointEvaluation" comme étant l'exécutable de mon projet.

if(Boost_FOUND)
    include_directories(${BOOST_INCLUDE_DIRS})
    link_directories(${Boost_LIBRARY_DIRS})
    add_definitions(${Boost_DEFINITIONS})

    include_directories(${Boost_INCLUDE_DIRS})  
    target_link_libraries(KeyPointEvaluation ${Boost_LIBRARIES})
    target_link_libraries( KeyPointEvaluation ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY})
endif()
6
Spandan

Je suis d'accord avec les réponses 1 et 2 . Cependant, je préfère spécifier chaque bibliothèque séparément. Cela rend les dépendances plus claires dans les grands projets. Cependant, il existe un risque d'erreur de frappe des noms de variables (sensibles à la casse). Dans ce cas, il n’ya pas d’erreur directe de cmake mais quelques problèmes de lieur de références non définis plus tard, qui peuvent prendre un certain temps à résoudre. Par conséquent, j'utilise la fonction cmake suivante:

function(VerifyVarDefined)
  foreach(lib ${ARGV}) 
    if(DEFINED ${lib})
    else(DEFINED ${lib})
      message(SEND_ERROR "Variable ${lib} is not defined")
    endif(DEFINED ${lib})
  endforeach()
endfunction(VerifyVarDefined)

Pour l'exemple mentionné ci-dessus, cela ressemble à:

VerifyVarDefined(Boost_PROGRAM_OPTIONS_LIBRARY Boost_REGEX_LIBRARY)
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )

Si j'avais écrit "BOOST_PROGRAM_OPTIONS_LIBRARY", il y aurait eu une erreur déclenchée par cmake et peu de temps après déclenchée par l'éditeur de liens.

2
MarkusParker

Essayez en disant documentation Boost :

set(Boost_USE_STATIC_LIBS        ON)  # only find static libs
set(Boost_USE_DEBUG_LIBS         OFF) # ignore debug libs and 
set(Boost_USE_RELEASE_LIBS       ON)  # only find release libs 
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF) 
find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...)
if(Boost_FOUND)   
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(foo foo.cc)   
    target_link_libraries(foo ${Boost_LIBRARIES})
endif()

N'oubliez pas de remplacer foo par le nom de votre projet et les composants par les vôtres!

1
Nikolay Pakudin