Як додати бібліотеки Boost у CMakeLists.txt?


125

Мені потрібно додати бібліотеки Boost до свого CMakeLists.txt. Як це зробити чи як додати?


що робить цей рядок rosbuild_add_boost_directories ()?
лакш

Дивіться офіційну документацію тут
adem

Відповіді:


171

Помістіть це у свій CMakeLists.txtфайл (якщо потрібно, змініть будь-які параметри з ВИМКНЕНО на ВКЛЮЧЕНО):

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

Очевидно, що вам потрібно помістити потрібні бібліотеки, куди я поклав *boost libraries here*. Наприклад, якщо ви використовуєте filesystemі regexбібліотеку ви б написати:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
Зауважте, що вам не потрібно вказувати компоненти лише для бібліотек заголовків, таких як lexical_cast. Таким чином, вам потрібні лише команда find_packageі include_directories.
miguel.martin

1
У Windows це також може допомогти додати це у файл cmake: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB), інакше ви можете зіткнутися з stackoverflow.com/questions/28887680/…
Stéphane

чи можна встановити BOOST_USE_STATIC_LIBS на ON та Boost_USE_STATIC_RUNTIME OFF? & віце-вірш.
кальмари

5
Що *boost libraries here*означає?
ІгорГанапольський

2
Ви також можете використовувати, FIND_PACKAGE(Boost REQUIRED COMPONENTS system)якщо ви не знаєте точну версію прискорення для використання
smac89

78

Ви можете використовувати find_package для пошуку доступних збільшити бібліотек. Він відкладає пошук Boost на FindBoost.cmake , який за замовчуванням встановлений у CMake.

Після пошуку Boost find_package()виклик заповнить багато змінних (перевірте посилання на FindBoost.cmake ). Серед них BOOST_INCLUDE_DIRS: Boost_LIBRARIES і Boost_XXX_LIBRARY змінні, причому XXX замінено конкретними бібліотеками Boost. За допомогою них можна вказати include_directories та target_link_libraries .

Наприклад, припустимо, що вам знадобиться boost :: program_options та boost :: regex, ви зробите щось на кшталт:

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

Деякі загальні поради:

  • Під час пошуку FindBoost перевіряє змінну середовища $ ENV {BOOST_ROOT}. Ви можете встановити цю змінну, перш ніж викликати find_package, якщо це необхідно.
  • Якщо у вас є кілька збірних версій прискорення (багатопотокові, статичні, спільні тощо), ви можете вказати потрібну конфігурацію, перш ніж викликати find_package. Зробіть це, встановивши деякі з наступних змінних On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • Шукаючи Boost у Windows, будьте уважні з автоматичним посиланням. Прочитайте "ПРИМІТКА для користувачів Visual Studio" у посиланні .
    • Моя порада - відключити автоматичне посилання та використовувати залежність cmake: add_definitions( -DBOOST_ALL_NO_LIB )
    • У деяких випадках може знадобитися чітко вказати, що використовується динамічне підвищення: add_definitions( -DBOOST_ALL_DYN_LINK )

3
Дякую за загальні поради. Вони мені дуже допомогли.
Тайлер Лонг

Неймовірно корисна відповідь! Врятували б мені багато часу, якби я знайшов це два роки тому. Прекрасна дописка.
Ela782

22

Адаптація відповіді @ LainIwakura для сучасного синтаксису CMake з імпортованими цілями:

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

Зауважте, що більше не потрібно вказувати каталоги включення вручну, оскільки це вже вирішено через імпортовані цілі Boost::filesystemта Boost::regex.
regexі filesystemможе бути замінено будь-якими потрібними бібліотеками.


1
Як би це виглядало, якби ви хотіли сказати, щоб зв’язати проти всіх прискорень? Я маю на увазі, не перераховуючи всі бібліотеки, які є прискореними.
Toby Brull

4
Якщо ви використовуєте лише частини заголовка, призначені лише для заголовка, "Boost :: boost" буде достатньо. Усі складені збільшити бібліотеки повинні бути вказані чітко.
oLen

2
@oLen Де я можу знайти список усіх імпортованих цілей cmake Boost :: *? Як мені знати, до якого я маю посилатися?
Маркус

8

Нехай це може допомогти деяким людям. У мене була неслухняна помилка: невизначена посилання на символ '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: помилка додавання символів: DSO відсутній у командному рядку. Був якийсь випуск cmakeList.txt і мені якось не вистачало явно включати бібліотеки "система" та "файлова система". Отже, я написав ці рядки в CMakeLists.txt

Ці рядки записуються на початку, перш ніж створити виконуваний файл, тому що на цьому етапі нам не потрібно пов'язувати збільшити бібліотеку з виконуваним проектом.

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)

Тепер, наприкінці файлу, я написав ці рядки, вважаючи "KeyPointEvaluation" моїм виконавчим проектом.

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

Я згоден з відповідями 1 і 2 . Однак я віддаю перевагу вказувати кожну бібліотеку окремо. Це робить залежність яснішою у великих проектах. Тим не менш, існує небезпека помилки імен змінних (залежно від регістру). У такому випадку відсутня пряма помилка cmake, але пізніше деякі проблеми з лінкером невизначених посилань, які можуть зайняти деякий час, щоб їх вирішити. Тому я використовую таку функцію 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)

Для згаданого вище прикладу це виглядає так:

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

Якби я написав "BOOST_PROGRAM_OPTIONS_LIBRARY", була б помилка, ініційована cmake, а не набагато пізніше, викликана лінкером.


2

Спробуйте сказати збільшити документацію :

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

Не забудьте замінити foo на назву проекту та компоненти на ваші!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.