2011-07-11 32 views

Trả lời

124

Đặt này trong tập tin CMakeLists.txt của bạn (thay đổi bất kỳ tùy chọn từ OFF sang ON 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 bạn cần phải đặ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 filesystemregex bạn muốn viết:

find_package(Boost 1.45.0 COMPONENTS filesystem regex) 
+1

Lưu ý rằng bạn không cần phải 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_package' và' include_directories'. –

+1

Trên Windows, nó cũng có thể giúp thêm tệp này vào tệp cmake của bạn: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB) nếu không bạn có thể chạy vào http://stackoverflow.com/questions/28887680/linking-boost-library-with-boost-use- static-lib-off-on-windows –

+0

là có thể thiết lập BOOST_USE_STATIC_LIBS thành ON và Boost_USE_STATIC_RUNTIME OFF? & ngược lại. – squid

68

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

Khi tìm Boost, cuộc gọi find_package() sẽ có nhiều biến (kiểm tra tham chiếu cho FindBoost.cmake). Trong số này có các biến số BOOST_INCLUDE_DIRS, 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 các thông số này để chỉ định include_directoriestarget_link_libraries.

Ví dụ, giả sử bạn sẽ cần phải tăng :: program_options và đẩy mạnh :: regex, bạn sẽ làm điều gì đó như:

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ố lời khuyên chung:

  • Khi tìm kiếm, FindBoost 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 nâng cấp (đa luồng, tĩnh, chia sẻ, v.v.), bạn có thể chỉ định cấu hình bạn muốn trước khi gọi hàm find_package. Thực hiện việc này bằng cách đặt một số biến sau đây thành On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED, Boost_USE_STATIC_RUNTIME
  • Khi tìm kiếm Tăng trên Windows, hãy cẩn thận với liên kết tự động. Đọc "LƯU Ý cho Người dùng Visual Studio" trong reference.
    • Lời khuyên của tôi là để vô hiệu hóa tính năng tự động liên kết và xử lý phụ thuộc sử dụng cmake của: add_definitions(-DBOOST_ALL_NO_LIB)
    • Trong một số trường hợp, bạn có thể cần phải xác định một cách rõ ràng rằng một Boost động được sử dụng: add_definitions(-DBOOST_ALL_DYN_LINK)
+3

Cảm ơn bạn đã biết các mẹo chung. Họ đã giúp tôi rất nhiều. –

+0

Câu trả lời vô cùng hữu ích! Có thể đã cứu tôi rất nhiều thời gian tôi đã tìm thấy điều này hai năm trước đây. Tuyệt vời viết lên. – Ela782

2

Tôi đồng ý với câu trả lời 12. Tuy nhiên, tôi muốn chỉ định riêng từng thư viện. Điều này làm cho các depencencies 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 đề liên kết tham chiếu không xác định sau này, có thể mất chút thời gian để giải quyết.Vì vậy, tôi sử dụng chức năng 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ụ nêu trên, điều này có vẻ 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 kích hoạt bởi cmake và không sau đó được kích hoạt bởi trình liên kết.

5

Thích ứng @ câu trả lời LainIwakura cho cú pháp CMake hiện đại với mục tiêu nhập khẩu, điều nà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 nó không phải là cần thiết nữa để xác định thư mục bao gồm bằng tay, vì nó đã được thực hiện thông qua các mục tiêu được nhập Boost::filesystemBoost::regex.
regexfilesystem có thể được thay thế bằng bất kỳ thư viện tăng nào bạn cần.

+1

Làm thế nào điều này sẽ nhìn nếu bạn muốn nói để liên kết với tất cả các tăng? Tôi có nghĩa là không có danh sách tất cả các thư viện có trong tăng. –

+1

Nếu bạn chỉ sử dụng các phần chỉ hỗ trợ tiêu đề, 'Boost :: boost' sẽ là đủ. Tất cả các thư viện tăng biên dịch phải được xác định rõ ràng. – oLen

0

Có thể điều này có thể hữu ích đối với một số người. Tôi đã có một lỗi nghịch ngợm: tài liệu tham khảo không xác định đến biểu tượng //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 '_ZN5boost6system15system_categoryEv': Lỗi ký thêm: DSO mất tích từ dòng lệnh Đã có một số vấn đề của cmakeList.txt và bằng cách nào đó tôi đã mất tích để bao gồm một cách rõ ràng các thư viện "hệ thống" và "hệ thống tập tin". 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 ngay từ đầu trước khi tạo thực thi dự án, vì ở giai đoạn này, chúng tôi không cần liên kết thư viện tăng cường với dự án thực thi của chúng tôi.

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ờ ở phần cuối của tệp, tôi đã viết những dòng này bằng cách xem xét "KeyPointEvaluation" làm 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() 
Các vấn đề liên quan