วิธีเชื่อมโยงโปรแกรม 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

1
ทำไมต้อง Boost 1.40 โดยเฉพาะ ฟังก์ชันพื้นฐานของไลบรารีหยุดเปลี่ยนแปลงเมื่อใด
jgyou

6
เพราะทำไมไม่? เป็นเพียงตัวอย่าง ... เติมสิ่งที่เหมาะกับคุณที่สุด
MOnsDaR

5
รายละเอียดที่สำคัญคือการวางtarget_link_libraries หลังจากadd_executable และ find_packageเส้นเพื่อให้ส่วนประกอบทั้งหมดที่เชื่อมโยงเป็นที่รู้จักกัน
Murphy

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

ในกรณีของฉันจำเป็นต้องใช้ 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 (สำเนาใหม่ล่าสุดจากการชง)
Henry Schreiner

5
stackoverflow เริ่มล้มเหลวเนื่องจากมีคำตอบที่ล้าสมัยจำนวนมากซึ่งบ่อยครั้งที่ยากที่จะหาคำตอบที่ถูกต้อง (อันนี้)
Carlo Wood

3

ห้องสมุด Boost ใด หลายคนเป็นเทมเพลตที่บริสุทธิ์และไม่จำเป็นต้องมีการเชื่อมโยง

ตอนนี้มีตัวอย่างที่เป็นรูปธรรมซึ่งบอกเราว่าคุณต้องการตัวเลือกโปรแกรม Boost (และยิ่งบอกเราว่าคุณใช้ Ubuntu) คุณต้องทำสองสิ่ง:

  1. ติดตั้งlibboost-program-options-devเพื่อให้คุณสามารถเชื่อมโยงกับมันได้
  2. บอกจะเชื่อมโยงกับcmakelibboost_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}
        )

โปรดทราบว่า dir ข้างต้น/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" แต่ไม่พบเป้าหมาย . บางทีการเรียก find_package () สำหรับเป้าหมาย IMPORTED หรือเป้าหมาย ALIAS หายไป
munsingh

สวัสดีขอบคุณสำหรับข้อเสนอแนะ ดูเหมือนว่า CMake ไม่สามารถค้นหา Boost ในระบบของคุณได้ บางทีคุณอาจจะดีกว่าที่จะสร้าง Boost ใหม่จากแหล่งที่มา ก่อนหน้านั้นคุณอาจต้องการลองสิ่งต่อไปนี้: ค้นหาแพ็คเกจที่มีfind_package(Boost QUIET REQUIRED)และเชื่อมโยงไปยังเป้าหมายของคุณ (DB32):target_link_libraries(DB32 PUBLIC Boost::headers)
adem
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.