Como você adiciona bibliotecas Boost em CMakeLists.txt?


125

Preciso adicionar bibliotecas Boost em meu CMakeLists.txt. Como você faz ou como você adiciona?


o que esta linha rosbuild_add_boost_directories () faz?
— laksh

Veja a documentação oficial aqui
— adem

Respostas:


171

Coloque isso em seu CMakeLists.txtarquivo (altere as opções de DESATIVADO para ATIVADO, se desejar):

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

Obviamente, você precisa colocar as bibliotecas que deseja onde eu coloco *boost libraries here*. Por exemplo, se você estiver usando a biblioteca filesysteme, regexescreveria:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
Observe que você não precisa especificar componentes para bibliotecas apenas de cabeçalho, como lexical_cast. Portanto, você só precisa do comando find_packagee include_directories.
— miguel.martin

1
No Windows, também pode ajudar adicionar isso ao seu arquivo cmake: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB), caso contrário, você pode executar stackoverflow.com/questions/28887680/…
— Stéphane

é possível definir BOOST_USE_STATIC_LIBS para ON e Boost_USE_STATIC_RUNTIME OFF? & vice-verso.
— lula de

5
O que isso *boost libraries here*significa?
— IgorGanapolsky

2
Você também pode usar FIND_PACKAGE(Boost REQUIRED COMPONENTS system)se não souber a versão exata do impulso a ser usado
— smac89

78

Você pode usar find_package para pesquisar por bibliotecas boost disponíveis. Ele adia a busca por Boost para FindBoost.cmake , que é instalado por padrão com o CMake.

Ao encontrar Boost, a find_package()chamada terá preenchido muitas variáveis ​​(verifique a referência para FindBoost.cmake ). Entre eles estão as BOOST_INCLUDE_DIRSvariáveis ​​Boost_LIBRARIES e Boost_XXX_LIBRARY, com XXX substituído por bibliotecas Boost específicas. Você pode usá-los para especificar include_directories e target_link_libraries .

Por exemplo, suponha que você precise boost :: program_options e boost :: regex, você faria algo como:

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

Algumas dicas gerais:

  • Ao pesquisar, FindBoost verifica a variável de ambiente $ ENV {BOOST_ROOT}. Você pode definir essa variável antes de chamar find_package, se necessário.
  • Quando você tem várias versões de build do boost (multi-threaded, estático, compartilhado, etc.), você pode especificar a configuração desejada antes de chamar find_package. Fazer isso definindo algumas das seguintes variáveis para On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • Ao pesquisar Boost no Windows, tome cuidado com a vinculação automática. Leia a "NOTA para usuários do Visual Studio" na referência .
    • Meu conselho é desabilitar o link automático e usar o tratamento de dependência do cmake: add_definitions( -DBOOST_ALL_NO_LIB )
    • Em alguns casos, você pode precisar especificar explicitamente que um Boost dinâmico é usado: add_definitions( -DBOOST_ALL_DYN_LINK )

3
Obrigado pelas dicas gerais. Eles me ajudaram muito.
— Tyler Long de

Resposta incrivelmente útil! Teria me poupado muito tempo se tivesse encontrado isso há dois anos. Ótimo artigo.
— Ela782 de

22

Adaptando a resposta de @LainIwakura para a sintaxe moderna do CMake com destinos importados, isso seria:

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

Observe que não é mais necessário especificar os diretórios de inclusão manualmente, uma vez que isso já é feito através dos destinos importados Boost::filesysteme Boost::regex.
regexe filesystempode ser substituído por qualquer biblioteca de impulso que você precisar.


1
Como isso ficaria se você quisesse dizer para vincular a todo impulso? Quer dizer, sem listar todas as bibliotecas que existem no boost.
— Toby Brull

4
Se você usar apenas partes do boost, apenas 'Boost :: boost' será suficiente. Todas as bibliotecas de reforço compiladas devem ser especificadas explicitamente.
— oLen

2
@oLen Onde encontro uma lista de todos os destinos cmake Boost :: * importados? Como posso saber para qual devo vincular?
— Markus

8

Isso pode ser útil para algumas pessoas. Eu tive um erro impertinente: referência indefinida ao símbolo '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: erro ao adicionar símbolos: DSO ausente na linha de comando Houve algum problema de cmakeList.txt e de alguma forma estava faltando incluir explicitamente as bibliotecas "sistema" e "sistema de arquivos". Então, eu escrevi essas linhas em CMakeLists.txt

Essas linhas são escritas no início, antes de criar o executável do projeto, pois neste estágio não precisamos vincular a biblioteca boost ao executável do nosso projeto.

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)

Agora, no final do arquivo, escrevi essas linhas considerando "KeyPointEvaluation" como o executável do meu projeto.

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

Eu concordo com as respostas 1 e 2 . No entanto, prefiro especificar cada biblioteca separadamente. Isso torna as dependências mais claras em grandes projetos. No entanto, existe o perigo de erros de digitação dos nomes das variáveis ​​(diferenciando maiúsculas de minúsculas). Nesse caso, não há erro cmake direto, mas alguns problemas do linker de referências indefinidas posteriormente, que podem levar algum tempo para serem resolvidos. Portanto, uso a seguinte função 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)

Para o exemplo mencionado acima, isso se parece com:

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

Se eu tivesse escrito "BOOST_PROGRAM_OPTIONS_LIBRARY", teria ocorrido um erro acionado por cmake e não muito depois acionado pelo vinculador.


2

Tente dizer a documentação do 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ão se esqueça de substituir foo pelo nome do projeto e componentes pelo seu!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.