Come si aggiungono le librerie Boost in CMakeLists.txt?


125

Devo aggiungere le librerie Boost nel mio CMakeLists.txt. Come lo fai o come lo aggiungi?


cosa fa questa riga rosbuild_add_boost_directories ()?
laksh

Vedi la documentazione ufficiale qui
adem

Risposte:


171

Inseriscilo nel tuo CMakeLists.txtfile (modifica le opzioni da OFF a ON se lo desideri):

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

Ovviamente devi mettere le librerie che vuoi dove metto io *boost libraries here*. Ad esempio, se stai usando la libreria filesysteme regexdovresti scrivere:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
Tieni presente che non è necessario specificare i componenti per le librerie di sola intestazione, come lexical_cast. Quindi hai solo bisogno del comando find_packagee include_directories.
miguel.martin

1
Su Windows, può anche aiutare ad aggiungere questo al tuo file cmake: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB) altrimenti potresti imbatterti in stackoverflow.com/questions/28887680/…
Stéphane

è possibile impostare BOOST_USE_STATIC_LIBS su ON e Boost_USE_STATIC_RUNTIME OFF? & viceversa.
calamari

5
Cosa *boost libraries here*significa?
IgorGanapolsky

2
Puoi anche usarlo FIND_PACKAGE(Boost REQUIRED COMPONENTS system)se non conosci la versione esatta di boost da usare
smac89

78

Puoi usare find_package per cercare le librerie boost disponibili. Rinvia la ricerca di Boost a FindBoost.cmake , che è installato di default con CMake.

Dopo aver trovato Boost, la find_package()chiamata avrà riempito molte variabili (controlla il riferimento per FindBoost.cmake ). Tra questi ci sono BOOST_INCLUDE_DIRS, Boost_LIBRARIES e Boost_XXX_LIBRARY variabili, con XXX sostituito con specifiche librerie Boost. Puoi usarli per specificare include_directories e target_link_libraries .

Ad esempio, supponi di aver bisogno di boost :: program_options e boost :: regex, dovresti fare qualcosa come:

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

Alcuni suggerimenti generali:

  • Durante la ricerca, FindBoost controlla la variabile d'ambiente $ ENV {BOOST_ROOT}. È possibile impostare questa variabile prima di chiamare find_package, se necessario.
  • Quando hai più versioni di build di boost (multi-thread, statico, condiviso, ecc.) Puoi specificare la configurazione desiderata prima di chiamare find_package. A tale scopo, impostando alcune delle seguenti variabili On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • Quando si cerca Boost su Windows, fare attenzione al collegamento automatico. Leggere la "NOTA per gli utenti di Visual Studio" nel riferimento .
    • Il mio consiglio è di disabilitare il collegamento automatico e utilizzare la gestione delle dipendenze di cmake: add_definitions( -DBOOST_ALL_NO_LIB )
    • In alcuni casi, potrebbe essere necessario specificare esplicitamente che viene utilizzato un Boost dinamico: add_definitions( -DBOOST_ALL_DYN_LINK )

3
Grazie per i suggerimenti generali. Mi hanno aiutato molto.
Tyler Long

Risposta incredibilmente utile! Mi avrebbe risparmiato un sacco di tempo se l'avessi trovato due anni fa. Ottimo articolo.
Ela782

22

Adattando la risposta di @ LainIwakura per la moderna sintassi CMake con target importati, questo sarebbe:

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

Si noti che non è più necessario specificare manualmente le directory di inclusione, poiché è già gestito tramite le destinazioni importate Boost::filesysteme Boost::regex.
regexe filesystempuò essere sostituito da qualsiasi libreria boost di cui hai bisogno.


1
Come sarebbe questo se volessi dire di collegare contro tutto il boost? Voglio dire senza elencare tutte le librerie che ci sono in boost.
Toby Brull

4
Se utilizzi solo parti di boost di sola intestazione, "Boost :: boost" sarà sufficiente. Tutte le librerie boost compilate devono essere specificate esplicitamente.
oLen

2
@oLen Dove trovo un elenco di tutti i target cmake Boost :: * importati? Come faccio a sapere a quale devo collegarmi?
Markus

8

Possa questo potrebbe essere utile per alcune persone. Ho avuto un errore impertinente: riferimento non definito al simbolo "_ZN5boost6system15system_categoryEv" //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: errore durante l'aggiunta di simboli: DSO mancante dalla riga di comando Si sono verificati alcuni problemi di cmakeList.txt e in qualche modo mi mancava includere esplicitamente le librerie "system" e "filesystem". Quindi, ho scritto queste righe in CMakeLists.txt

Queste righe vengono scritte all'inizio prima di creare l'eseguibile del progetto, poiché in questa fase non è necessario collegare la libreria boost all'eseguibile del nostro progetto.

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)

Ora alla fine del file, ho scritto queste righe considerando "KeyPointEvaluation" come eseguibile del mio progetto.

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

2

Sono d'accordo con le risposte 1 e 2 . Tuttavia, preferisco specificare ogni libreria separatamente. Questo rende più chiare le dipendenze nei grandi progetti. Tuttavia, esiste il pericolo di digitare in modo errato i nomi delle variabili (con distinzione tra maiuscole e minuscole). In tal caso non si verifica alcun errore cmake diretto ma in seguito alcuni problemi di linker di riferimenti non definiti, che potrebbero richiedere del tempo per essere risolti. Pertanto utilizzo la seguente funzione cmake:

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)

Per l'esempio menzionato sopra, questo assomiglia a:

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

Se avessi scritto "BOOST_PROGRAM_OPTIONS_LIBRARY" ci sarebbe stato un errore innescato da cmake e non molto successivamente innescato dal linker.


2

Prova a dire Boost documentazione :

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

Non dimenticare di sostituire foo con il nome del tuo progetto e i componenti con il tuo!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.