Jak połączyć program C ++ z Boost przy użyciu CMake

109

Jak powinien wyglądać mój plik CMake do łączenia mojego programu z biblioteką Boost w systemie Ubuntu?

Błędy wyświetlane podczas uruchamiania make:

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

Główny plik jest naprawdę prosty:

#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;
}

Udało mi się to zrobić. Jedyne wiersze, które dodałem do moich plików CMake, to:

target_link_libraries(
my_target_file
${Boost_PROGRAM_OPTIONS_LIBRARY}
)
Szymon Lipiński
źródło

Odpowiedzi:

150

W CMake możesz użyć find_packagedo znalezienia potrzebnych bibliotek. Zazwyczaj FindBoost.cmakewraz z instalacją CMake znajduje się plik .

O ile pamiętam, zostanie on zainstalowany /usr/share/cmake/Modules/wraz z innymi skryptami wyszukiwania dla popularnych bibliotek. Możesz po prostu sprawdzić dokumentację w tym pliku, aby uzyskać więcej informacji o tym, jak to działa.

Przykład z mojej głowy:

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

Mam nadzieję, że ten kod pomoże.

MOnsDaR
źródło
2
Dodano działający link z repozytorium Kitwares Github. Dodano również link do oficjalnej dokumentacji o FindBoost.cmake
MOnsDaR
1
Dlaczego właśnie Boost 1.40? Kiedy podstawowe funkcjonalności biblioteki przestały się zmieniać?
jgyou
6
Bo czemu nie? To tylko przykład ... Wpisz to, co najbardziej Ci odpowiada
MOnsDaR
5
Ważnym szczegółem jest na miejscu target_link_libraries po add_executable i find_package linii, więc wszystko połączone składniki są znane.
Murphy
52

Oto moja konfiguracja:

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
źródło
7
Katalogi link_directories nie są wymagane, ponieważ Boost_LIBRARIES będą w pełni kwalifikowanymi ścieżkami.
RobertJMaynard
W moim przypadku link_directories był konieczny.
mgruber4
25

Dostosowanie odpowiedzi @MOnsDaR do nowoczesnej składni CMake z zaimportowanymi celami wyglądałoby tak:

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

Zauważ, że nie jest konieczne ręczne określanie katalogów dołączanych, ponieważ jest to już obsługiwane przez importowany cel Boost::program_options.

oLen
źródło
Wadą tego podejścia docelowego jest to, że jeśli Twoja wersja Boost jest nowsza niż wersja CMake, prawdopodobnie się to nie powiedzie. The FindBoost.cmakepierwotnie tworzy je tylko wtedy, gdy wyraźnie wymienia Twoją wersję Boost. W pewnym momencie miało to zostać poprawione, ale nadal widzę awarie z CMake 3.10.2 i Boost 1.66 (najnowsze kopie z brew).
Henry Schreiner
4
stackoverflow zaczyna zawodzić, ponieważ jest tak wiele nieaktualnych odpowiedzi, że często trudno jest znaleźć właściwą odpowiedź (tę).
Carlo Wood
3

Która biblioteka Boost? Wiele z nich to czyste szablony i nie wymagają linkowania.

Teraz z tym faktycznie pokazanym konkretnym przykładem, który mówi nam, że chcesz opcji programu Boost (a nawet więcej powiedział nam, że jesteś na Ubuntu), musisz zrobić dwie rzeczy:

  1. Zainstaluj libboost-program-options-dev, aby móc połączyć się z nim.
  2. Powiedz, cmakeaby połączyć libboost_program_options.

Głównie używam Makefiles, więc tutaj jest bezpośrednie użycie w linii poleceń:

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

Wydaje się, że to niewiele robi.

W przypadku CMake musisz dodać boost_program_options do listy bibliotek, a IIRC odbywa się za pośrednictwem SET(liblist boost_program_options)twojego CMakeLists.txt.

Dirk Eddelbuettel
źródło
11
Twoja rada dotycząca CMake jest błędna (zobacz zaakceptowaną odpowiedź), a rada dotycząca wiersza poleceń nie jest zbyt pomocna, ponieważ pytanie dotyczyło CMake.
Ela782
3

Na dwa sposoby, zwykle używając domyślnej ścieżki instalacji systemu /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}
        )

Jeśli zainstalujesz Boost w katalogu lokalnym lub wybierzesz instalację lokalną zamiast instalacji systemu, możesz to zrobić w ten sposób:

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

Zauważ, że powyższy katalog /home/xy/boost_install/lib/to miejsce, w którym instaluję 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/

Jeśli interesuje Cię, jak korzystać z lokalnego, zainstalowanego Boost, możesz zobaczyć to pytanie Jak mogę sprawić, by CMake znalazł moją alternatywną instalację Boost? .

Jayhello
źródło
2

Oto moje podejście:

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
źródło
target_link_libraries (helloworld PUBLIC Boost :: program_options) wyświetli błąd CMAKE: - Konfiguracja zakończona Błąd CMake w CMakeLists.txt: 102 (add_executable): Docelowe "DB32" łączy do celu "Boost :: program_options", ale cel nie został znaleziony . Być może brakuje wywołania find_package () dla celu IMPORTOWANEGO lub brakuje celu ALIAS?
munsingh
Cześć, dzięki za informację zwrotną. Wygląda na to, że CMake nie może zlokalizować Boost w twoim systemie. Może lepiej będzie stworzyć nową wersję Boost ze źródła. Wcześniej możesz spróbować wykonać następujące czynności: Znajdź pakiet zawierający find_package(Boost QUIET REQUIRED)i link do celu (DB32):target_link_libraries(DB32 PUBLIC Boost::headers)
adem