Làm cách nào để bạn thêm thư viện Boost trong CMakeLists.txt?


125

Tôi cần thêm thư viện Boost vào CMakeLists.txt của mình. Làm thế nào để bạn làm điều đó hoặc làm thế nào để bạn thêm nó?


dòng này rosbuild_add_boost_directories () làm gì?
laksh

Xem tài liệu chính thức tại đây
adem

Câu trả lời:


171

Đặt cái này vào CMakeLists.txttệp của bạn (thay đổi bất kỳ tùy chọn nào từ TẮT sang BẬT nếu bạn muốn):

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

Rõ ràng là bạn cần đặt các thư viện bạn muốn ở nơi tôi đặt *boost libraries here*. Ví dụ: nếu bạn đang sử dụng thư viện filesystemregexbạn sẽ viết:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
Lưu ý rằng bạn không cần chỉ định các thành phần cho các thư viện chỉ tiêu đề, chẳng hạn như lexical_cast. Vì vậy, bạn chỉ cần lệnh find_packageinclude_directories.
miguel.martin

1
Trên Windows, nó cũng có thể giúp đỡ để thêm video này vào tập tin cmake của bạn: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB) nếu không bạn có thể chạy vào stackoverflow.com/questions/28887680/...
Stéphane

có thể đặt BOOST_USE_STATIC_LIBS thành BẬT và TẮT Boost_USE_STATIC_RUNTIME không? & ngược lại.
mực

5
Nghĩa *boost libraries here*là gì?
IgorGanapolsky

2
Bạn cũng có thể sử dụng FIND_PACKAGE(Boost REQUIRED COMPONENTS system)nếu bạn không biết chính xác phiên bản của động lực để sử dụng
smac89

78

Bạn có thể sử dụng find_package để tìm kiếm các thư viện tăng cường có sẵn. Nó ngăn chặn tìm kiếm Boost thành FindBoost.cmake , được cài đặt mặc định với CMake.

Khi tìm thấy Boost, lệnh find_package()gọi sẽ chứa nhiều biến (kiểm tra tham chiếu cho FindBoost.cmake ). Trong số này BOOST_INCLUDE_DIRS, các biến thể Boost_LIBRARIES và Boost_XXX_LIBRARY, với XXX được thay thế bằng các thư viện Boost cụ thể. Bạn có thể sử dụng chúng để chỉ định thư mục includetarget_link_libraries .

Ví dụ: giả sử bạn cần boost :: program_options và boost :: regex, bạn sẽ làm như sau:

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

Một số mẹo chung:

  • Khi tìm kiếm, FindBoost sẽ kiểm tra biến môi trường $ ENV {BOOST_ROOT}. Bạn có thể đặt biến này trước khi gọi find_package nếu cần.
  • Khi bạn có nhiều phiên bản xây dựng của boost (đa luồng, tĩnh, chia sẻ, v.v.), bạn có thể chỉ định cấu hình mong muốn của mình trước khi gọi find_package. Làm điều này bằng cách thiết lập một số biến sau để On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • Khi tìm kiếm Boost trên Windows, hãy cẩn thận với liên kết tự động. Đọc phần "LƯU Ý dành cho người dùng Visual Studio" trong tài liệu tham khảo .
    • Lời khuyên của tôi là vô hiệu hóa liên kết tự động và sử dụng xử lý phụ thuộc của cmake: add_definitions( -DBOOST_ALL_NO_LIB )
    • Trong một số trường hợp, bạn có thể cần chỉ định rõ ràng rằng một Tăng cường động được sử dụng: add_definitions( -DBOOST_ALL_DYN_LINK )

3
Cảm ơn bạn vì những lời khuyên chung. Họ đã giúp tôi rất nhiều.
Tyler Long

Câu trả lời vô cùng hữu ích! Sẽ giúp tôi tiết kiệm rất nhiều thời gian nếu tôi tìm thấy điều này hai năm trước. Viết lên tuyệt vời.
Ela782

22

Điều chỉnh câu trả lời của @ LainIwakura cho cú pháp CMake hiện đại với các mục tiêu đã nhập, đây sẽ là:

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

Lưu ý rằng không cần thiết phải chỉ định các thư mục bao gồm theo cách thủ công nữa, vì nó đã được xử lý thông qua các mục tiêu được nhập Boost::filesystemBoost::regex.
regexfilesystemcó thể được thay thế bằng bất kỳ thư viện tăng cường nào bạn cần.


1
Điều này sẽ trông như thế nào nếu bạn muốn nói rằng liên kết chống lại tất cả sự thúc đẩy? Ý tôi là không cần liệt kê tất cả các thư viện đang được tăng cường.
Toby Brull,

4
Nếu bạn chỉ sử dụng các phần chỉ có tiêu đề của boost, thì 'Boost :: boost' là đủ. Tất cả các thư viện tăng cường đã biên dịch phải được chỉ định rõ ràng.
oLen

2
@oLen Tôi tìm danh sách tất cả các mục tiêu cmake Boost :: * đã nhập ở đâu? Làm cách nào để biết tôi phải liên kết đến?
Markus

8

Có thể điều này có thể hữu ích cho một số người. Tôi đã gặp lỗi nghịch ngợm: tham chiếu không xác định tới biểu tượng '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: lỗi thêm ký hiệu: Thiếu DSO trong dòng lệnh Có một số vấn đề về cmakeList.txt và bằng cách nào đó tôi đã thiếu để đưa vào thư viện "hệ thống" và "hệ thống tệp" một cách rõ ràng. Vì vậy, tôi đã viết những dòng này trong CMakeLists.txt

Những dòng này được viết ở phần đầu trước khi tạo tệp thực thi của dự án, vì ở giai đoạn này, chúng ta không cần liên kết thư viện tăng cường với tệp thực thi dự án của chúng ta.

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)

Bây giờ ở cuối tệp, tôi đã viết những dòng này bằng cách coi "KeyPointEvaluation" là dự án thực thi của tôi.

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

Tôi đồng ý với câu trả lời 12 . Tuy nhiên, tôi muốn chỉ định từng thư viện riêng biệt. Điều này làm cho sự thiếu hụt rõ ràng hơn trong các dự án lớn. Tuy nhiên, có nguy cơ gõ nhầm tên biến (phân biệt chữ hoa chữ thường). Trong trường hợp đó, không có lỗi cmake trực tiếp nhưng một số vấn đề về trình liên kết tham chiếu không xác định sau này, có thể mất một thời gian để giải quyết. Do đó tôi sử dụng hàm cmake sau:

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)

Đối với ví dụ được đề cập ở trên, điều này trông giống như:

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

Nếu tôi đã viết "BOOST_PROGRAM_OPTIONS_LIBRARY" thì sẽ có một lỗi do cmake kích hoạt và không lâu sau đó do trình liên kết kích hoạt.


2

Hãy thử như nói tài liệu Boost :

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

Đừng quên thay thế foo thành tên dự án của bạn và các thành phần của bạn!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.