Как связать программу C ++ с Boost с помощью CMake


109

Как должен выглядеть мой файл CMake для связывания моей программы с библиотекой Boost в Ubuntu?

Ошибки, отображаемые во время работы make:

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

Главный файл действительно прост:

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

Мне это удалось. Единственные строки, которые я добавил в свои файлы CMake, были:

target_link_libraries(
my_target_file
${Boost_PROGRAM_OPTIONS_LIBRARY}
)

Ответы:


150

В CMake вы можете использовать find_packageдля поиска нужных вам библиотек. Обычно FindBoost.cmakeвместе с установкой CMake.

Насколько я помню, он будет установлен /usr/share/cmake/Modules/вместе с другими скриптами поиска для общих библиотек. Вы можете просто проверить документацию в этом файле для получения дополнительной информации о том, как это работает.

Пример из моей головы:

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

Надеюсь, этот код поможет.


2
Добавлена ​​рабочая ссылка из репозитория Kitwares на Github. Также добавлена ​​ссылка на официальную документацию по FindBoost.cmake
MOnsDaR 09

1
Почему именно Boost 1.40? Когда перестали меняться базовые функции библиотеки?
jgyou

6
Почему бы и нет? Это просто пример ... Заполните то, что вам больше подходит
MOnsDaR

5
Важная деталь на место target_link_libraries после add_executable и find_package линий, поэтому все связанные компоненты известны.
Мерфи

52

Вот моя конфигурация:

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

7
Link_directories не требуется, поскольку Boost_LIBRARIES будут полными путями.
RobertJMaynard 09

В моем случае нужен link_directories.
mgruber4

25

Адаптируя ответ @MOnsDaR для современного синтаксиса CMake с импортированными целями, это будет:

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

Обратите внимание, что указывать подключаемые каталоги вручную не обязательно, поскольку об этом уже позаботились с помощью импортированной цели Boost::program_options.


Обратной стороной этого целевого подхода является то, что если ваша версия Boost новее, чем версия CMake, это, вероятно, не удастся. The FindBoost.cmakeизначально создает их только в том случае, если в нем явно указана ваша версия Boost. В какой-то момент это должно было быть улучшено, но я все еще наблюдаю сбои с CMake 3.10.2 и Boost 1.66 (новейшие копии от brew).
Генри Шрайнер

5
stackoverflow начинает давать сбой, потому что существует так много устаревших ответов, что часто бывает трудно найти правильный ответ (этот).
Carlo Wood

3

Какая библиотека Boost? Многие из них являются чистыми шаблонами и не требуют привязки.

Теперь, когда на самом деле показан конкретный пример, который говорит нам, что вам нужны параметры программы Boost (и даже больше сообщило нам, что вы используете Ubuntu), вам нужно сделать две вещи:

  1. Установите, libboost-program-options-devчтобы вы могли ссылаться на него.
  2. Скажите cmakeссылку против libboost_program_options.

Я в основном использую Makefiles, так что вот прямое использование командной строки:

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

Кажется, это не так уж много.

Для CMake вам нужно добавить boost_program_options в список библиотек, а IIRC это делается через SET(liblist boost_program_options)ваш CMakeLists.txt.


11
Ваш совет CMake неверен (см. Принятый ответ), а ваш совет командной строки не очень полезен, поскольку вопрос был о CMake.
Ela782

3

Двумя способами, используя системный путь установки по умолчанию, обычно /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}
        )

Если вы устанавливаете Boost в локальный каталог или выбираете локальную установку вместо системной, вы можете сделать это следующим образом:

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

Обратите внимание, что в приведенном выше каталоге /home/xy/boost_install/lib/я устанавливаю 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/

Если вас интересует, как использовать локально установленный Boost, вы можете увидеть этот вопрос. Как мне заставить CMake найти мою альтернативную установку Boost? .


2

Вот мой вывод:

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)

target_link_libraries (helloworld PUBLIC Boost :: program_options) выдаст ошибку CMAKE: - Настройка завершена ошибка CMake в CMakeLists.txt: 102 (add_executable): Целевые ссылки «DB32» на целевые «Boost :: program_options», но цель не была найдена . Возможно, для цели IMPORTED отсутствует вызов find_package () или отсутствует цель ALIAS?
munsingh

Привет, спасибо за отзыв. Похоже, CMake не может найти Boost в вашей системе. Может вам лучше сделать свежую сборку Boost из исходников. Перед этим вы можете попробовать следующее: Найдите пакет с find_package(Boost QUIET REQUIRED)вашей целью (DB32) и укажите ссылку на нее:target_link_libraries(DB32 PUBLIC Boost::headers)
adem
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.