2011-07-11 17 views

risposta

124

mettere questo nel file CMakeLists.txt (modificare le opzioni da OFF a ON se si vuole):

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 è necessario mettere le librerie che si desidera dove ho messo *boost libraries here*. Ad esempio, se si sta utilizzando la libreria filesystem e regex devi scrivere:

find_package(Boost 1.45.0 COMPONENTS filesystem regex) 
+1

Si noti che non è necessario specificare componenti per le librerie di sola intestazione, come 'lexical_cast'. Quindi hai solo bisogno del comando 'find_package' e' include_directories'. –

+1

Su Windows, può anche essere d'aiuto aggiungere questo al tuo file cmake: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB) altrimenti potresti imbatterti in http://stackoverflow.com/questions/28887680/linking-boost-library-with-boost-use- static-lib-off-on-windows –

+0

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

68

È possibile utilizzare find_package per cercare le librerie Boost disponibili. Rinvia la ricerca di Boost a FindBoost.cmake, che viene installato di default con CMake.

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

Ad esempio, supponiamo che avrebbe bisogno di boost :: program_options e boost :: regex, si potrebbe fare qualcosa di simile:

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 consigli generali:

  • Durante la ricerca, controlla il FindBoost variabile d'ambiente $ ENV {BOOST_ROOT}. È possibile impostare questa variabile prima di chiamare find_package, se necessario.
  • Se si dispone di più versioni build di boost (multi-thread, statico, condiviso, ecc.) È possibile specificare la configurazione desiderata prima di chiamare find_package. Effettuare ciò impostando alcune delle seguenti variabili a On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED, Boost_USE_STATIC_RUNTIME
  • Durante la ricerca di Boost su Windows, fare attenzione con il collegamento automatico. Leggi la "NOTA per gli utenti di Visual Studio" nello reference.
    • Il mio consiglio è quello di disabilitare l'auto-linking e la gestione delle dipendenze utilizzo cmake: add_definitions(-DBOOST_ALL_NO_LIB)
    • In alcuni casi, potrebbe essere necessario specificare esplicitamente che una spinta dinamica viene utilizzato: add_definitions(-DBOOST_ALL_DYN_LINK)
+3

Grazie per i suggerimenti generali. Mi hanno aiutato molto. –

+0

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

2

Sono d'accordo con le risposte 1 e 2. Tuttavia, preferisco specificare ciascuna libreria separatamente. Questo rende le responsabilità più chiare nei grandi progetti. Tuttavia, esiste il rischio di digitare in modo errato i nomi delle variabili (sensibili al maiuscolo/minuscolo). In questo caso non ci sono errori cmake diretti ma alcuni problemi di linker di riferimenti non definiti in seguito, che potrebbero richiedere del tempo per risolverli.Perciò io uso 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 di cui sopra, questo appare come:

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 più tardi innescato dal linker.

5

Adattamento @ risposta di LainIwakura per la moderna sintassi CMake con gli obiettivi 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() 

Nota che non è più necessario specificare le directory includere manualmente, dal momento che è già curato attraverso il obiettivi importati Boost::filesystem e Boost::regex.
regex e filesystem possono essere sostituiti da eventuali librerie di boost necessarie.

+1

Come apparirebbe se volessi dire di collegarti a tutti gli boost? Voglio dire senza elencare tutte le librerie ci sono in boost. –

+1

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

0

Potrebbe essere utile per alcune persone. Ho avuto un errore di cattivo: undefined reference to simbolo //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 '_ZN5boost6system15system_categoryEv': errore di simboli che aggiungono: DSO manca dalla riga di comando Ci sono stati alcuni problema 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 sono scritte all'inizio prima di creare l'eseguibile del progetto, poiché in questa fase non è necessario collegare la libreria di boost al nostro eseguibile di 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 il mio eseguibile 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() 
Problemi correlati