Je dois ajouter des bibliothèques Boost à mon CMakeLists.txt. Comment faites-vous ou comment l'ajoutez-vous?
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)
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:
On
: Boost_USE_STATIC_LIBS
, Boost_USE_MULTITHREADED
, Boost_USE_STATIC_RUNTIME
add_definitions( -DBOOST_ALL_NO_LIB )
add_definitions( -DBOOST_ALL_DYN_LINK )
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.
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()
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.
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!