Como vincular o programa C ++ com Boost usando CMake

109

Qual deve ser a aparência do meu arquivo CMake para vincular meu programa à biblioteca Boost no Ubuntu?

Os erros mostrados durante a execução make:

main.cpp:(.text+0x3b): undefined reference to `boost::program_options::options_description::m_default_line_length'

O arquivo principal é muito simples:

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/option.hpp>
using namespace std;
#include <iostream>

namespace po = boost::program_options;

int main(int argc, char** argv) {

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ;

    return 0;
}

Eu consegui fazer isso. As únicas linhas que adicionei aos meus arquivos CMake foram:

target_link_libraries(
my_target_file
${Boost_PROGRAM_OPTIONS_LIBRARY}
)
Szymon Lipiński
fonte

Respostas:

150

No CMake você pode usar find_packagepara encontrar as bibliotecas de que precisa. Geralmente há um FindBoost.cmakejunto com a instalação do CMake.

Pelo que me lembro, ele será instalado /usr/share/cmake/Modules/junto com outros scripts de localização para bibliotecas comuns. Você pode apenas verificar a documentação nesse arquivo para obter mais informações sobre como funciona.

Um exemplo da minha cabeça:

FIND_PACKAGE( Boost 1.40 COMPONENTS program_options REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )

ADD_EXECUTABLE( anyExecutable myMain.cpp )

TARGET_LINK_LIBRARIES( anyExecutable LINK_PUBLIC ${Boost_LIBRARIES} )

Espero que este código ajude.

MOnsDaR
fonte
2
Adicionado um link de trabalho do repositório Kitwares Github. Também foi adicionado um link para a documentação oficial sobre FindBoost.cmake
MOnsDaR
1
Por que Boost 1,40 em particular? Quando as funcionalidades básicas da biblioteca pararam de mudar?
jgyou
6
Porque porque não? É apenas um exemplo ... Preencha o que for mais adequado para você
MOnsDaR
5
Um detalhe importante é colocar target_link_libraries após as linhas add_executable e find_package , para que todos os componentes vinculados sejam conhecidos.
Murphy em
52

O seguinte é minha configuração:

cmake_minimum_required(VERSION 2.8)
set(Boost_INCLUDE_DIR /usr/local/src/boost_1_46_1)
set(Boost_LIBRARY_DIR /usr/local/src/boost_1_46_1/stage/lib)
find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})

add_executable(main main.cpp)
target_link_libraries( main ${Boost_LIBRARIES} )
Dean Chen
fonte
7
Os link_directories não são necessários, pois Boost_LIBRARIES serão caminhos totalmente qualificados.
RobertJMaynard
No meu caso, link_directories foi necessário.
mgruber4
25

Adaptando a resposta @MOnsDaR para a sintaxe CMake moderna com destinos importados, isso seria:

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

Observe que não é necessário especificar os diretórios de inclusão manualmente, pois isso já é feito por meio do destino importado Boost::program_options.

oLen
fonte
A desvantagem dessa abordagem de destino é se sua versão Boost for mais recente que a versão CMake, isso provavelmente irá falhar. The FindBoost.cmakeoriginalmente os constrói apenas se listar explicitamente sua versão do Boost. Em algum ponto isso deveria ser melhorado, mas ainda estou vendo falhas com CMake 3.10.2 e Boost 1.66 (cópias mais recentes da cerveja).
Henry Schreiner
4
stackoverflow começa a falhar porque há tantas respostas desatualizadas que muitas vezes é difícil encontrar a resposta certa (esta).
Carlo Wood
3

Qual biblioteca Boost? Muitos deles são modelos puros e não requerem vinculação.

Agora, com aquele exemplo concreto realmente mostrado que nos diz que você deseja as opções do programa Boost (e ainda mais nos disse que você está no Ubuntu), você precisa fazer duas coisas:

  1. Instale libboost-program-options-devpara que você possa vincular a ele.
  2. Diga cmakepara vincular libboost_program_options.

Eu uso principalmente Makefiles, então aqui está o uso direto da linha de comando:

$ g++ boost_program_options_ex1.cpp -o bpo_ex1 -lboost_program_options
$ ./bpo_ex1
$ ./bpo_ex1 -h
$ ./bpo_ex1 --help
$ ./bpo_ex1 -help
$

Parece que não faz muita coisa.

Para CMake, você precisa adicionar boost_program_options à lista de bibliotecas, e IIRC isso é feito via SET(liblist boost_program_options)em seu CMakeLists.txt.

Dirk Eddelbuettel
fonte
11
Seu conselho CMake está errado (veja a resposta aceita), e seu conselho de linha de comando não é muito útil, pois a pergunta era sobre CMake.
Ela782
3

Duas maneiras, usando o caminho de instalação padrão do sistema, geralmente /usr/lib/x86_64-linux-gnu/:

find_package(Boost REQUIRED regex date_time system filesystem thread graph)
include_directories(${BOOST_INCLUDE_DIRS})
message("boost lib: ${Boost_LIBRARIES}")
message("boost inc:${Boost_INCLUDE_DIR}")

add_executable(use_boost use_boost.cpp)
target_link_libraries(use_boost
        ${Boost_LIBRARIES}
        )

Se você instalar o Boost em um diretório local ou escolher a instalação local em vez da instalação do sistema, você pode fazer isso:

set( BOOST_ROOT "/home/xy/boost_install/lib/" CACHE PATH "Boost library path" )
set( Boost_NO_SYSTEM_PATHS on CACHE BOOL "Do not search system for Boost" )

find_package(Boost REQUIRED regex date_time system filesystem thread graph)
include_directories(${BOOST_INCLUDE_DIRS})
message("boost lib: ${Boost_LIBRARIES}, inc:${Boost_INCLUDE_DIR}")

add_executable(use_boost use_boost.cpp)
target_link_libraries(use_boost
        ${Boost_LIBRARIES}
        )

Observe que o diretório acima /home/xy/boost_install/lib/é onde eu instalo o Boost:

xy@xy:~/boost_install/lib$ ll -th
total 16K
drwxrwxr-x 2 xy xy 4.0K May 28 19:23 lib/
drwxrwxr-x 3 xy xy 4.0K May 28 19:22 include/

xy@xy:~/boost_install/lib$ ll -th lib/
total 57M
drwxrwxr-x 2 xy xy 4.0K May 28 19:23 ./
-rw-rw-r-- 1 xy xy 2.3M May 28 19:23 libboost_test_exec_monitor.a
-rw-rw-r-- 1 xy xy 2.2M May 28 19:23 libboost_unit_test_framework.a
.......

xy@xy:~/boost_install/lib$ ll -th include/
total 20K
drwxrwxr-x 110 xy xy  12K May 28 19:22 boost/

Se estiver interessado em como usar um Boost instalado localmente, você pode ver esta pergunta: Como faço para que o CMake encontre minha instalação alternativa do Boost? .

Jayhello
fonte
2

Aqui está minha opinião:

cmake_minimum_required(VERSION 3.15)

project(TryOuts LANGUAGES CXX)

find_package(Boost QUIET REQUIRED COMPONENTS program_options)

if(NOT Boost_FOUND)
    message(FATAL_ERROR "Boost Not found")
endif()

add_executable(helloworld main.cpp)

target_link_libraries(helloworld PUBLIC Boost::program_options)
adem
fonte
target_link_libraries (helloworld PUBLIC Boost :: program_options) dará um erro CMAKE: - Configuring done CMake Error em CMakeLists.txt: 102 (add_executable): O destino "DB32" se vincula ao destino "Boost :: program_options", mas o destino não foi encontrado . Talvez uma chamada find_package () esteja faltando para um destino IMPORTED ou um destino ALIAS esteja faltando?
munsingh
Oi, obrigado pelo feedback. Parece que o CMake não consegue localizar o Boost em seu sistema. Talvez seja melhor você fazer uma nova construção do Boost a partir da fonte. Antes disso, você pode tentar o seguinte: Encontre o pacote com find_package(Boost QUIET REQUIRED)e link para seu destino (DB32):target_link_libraries(DB32 PUBLIC Boost::headers)
adem