Respostas:
Coloque isso em seu CMakeLists.txt
arquivo (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 filesystem
e, regex
escreveria:
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
lexical_cast
. Portanto, você só precisa do comando find_package
e include_directories
.
*boost libraries here*
significa?
FIND_PACKAGE(Boost REQUIRED COMPONENTS system)
se não souber a versão exata do impulso a ser usado
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_DIRS
variá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:
On
: Boost_USE_STATIC_LIBS
, Boost_USE_MULTITHREADED
,Boost_USE_STATIC_RUNTIME
add_definitions( -DBOOST_ALL_NO_LIB )
add_definitions( -DBOOST_ALL_DYN_LINK )
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::filesystem
e Boost::regex
.
regex
e filesystem
pode ser substituído por qualquer biblioteca de impulso que você precisar.
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()
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.
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!