Cách liên kết chương trình C ++ với Boost bằng CMake


109

Tệp CMake của tôi trông như thế nào khi liên kết chương trình của tôi với thư viện Boost trong Ubuntu?

Các lỗi hiển thị trong khi chạy make:

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

Tệp chính thực sự đơn giản:

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

Tôi đã làm được điều đó. Các dòng duy nhất mà tôi đã thêm vào tệp CMake của mình là:

target_link_libraries(
my_target_file
${Boost_PROGRAM_OPTIONS_LIBRARY}
)

Câu trả lời:


150

Trong CMake, bạn có thể sử dụng find_packageđể tìm thư viện bạn cần. Thường có một FindBoost.cmakecùng với cài đặt CMake của bạn.

Theo như tôi nhớ, nó sẽ được cài đặt /usr/share/cmake/Modules/cùng với các tập lệnh tìm kiếm khác cho các thư viện phổ biến. Bạn chỉ có thể kiểm tra tài liệu trong tệp đó để biết thêm thông tin về cách nó hoạt động.

Một ví dụ trong đầu tôi:

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

Tôi hy vọng mã này sẽ giúp.


2
Đã thêm một liên kết hoạt động từ kho Kitwares Github. Cũng đã thêm một liên kết đến tài liệu chính thức về FindBoost.cmake
MOnsDaR

1
Tại sao lại nói riêng về Tăng 1.40? Các chức năng cơ bản của thư viện ngừng thay đổi khi nào?
jgyou

6
Vì tại sao không? Đó chỉ là một ví dụ ... Điền vào bất cứ điều gì phù hợp với bạn nhất
MOnsDaR

5
Một chi tiết quan trọng là phải diễn ra target_link_libraries sau khi các add_executable find_package dây chuyền, vì vậy các thành phần tất cả các liên kết được biết đến.
Murphy

52

Sau đây là cấu hình của tôi:

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 không bắt buộc vì Boost_LIBRARIES sẽ là đường dẫn hoàn toàn đủ điều kiện.
RobertJMaynard

Trong trường hợp của tôi, link_directories là cần thiết.
mgruber 4

25

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

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

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, vì nó đã được xử lý thông qua mục tiêu được nhập Boost::program_options.


Nhược điểm của cách tiếp cận mục tiêu này là nếu phiên bản Boost của bạn mới hơn phiên bản CMake của bạn, điều này có thể sẽ thất bại. The FindBoost.cmakeban đầu chỉ xây dựng những thứ này nếu nó liệt kê rõ ràng phiên bản Boost của bạn. Tại một số thời điểm, điều này được cho là sẽ được cải thiện, nhưng tôi vẫn thấy thất bại với CMake 3.10.2 và Boost 1.66 (bản sao mới nhất từ ​​brew).
Henry Schreiner

4
stackoverflow bắt đầu không thành công vì có quá nhiều câu trả lời lỗi thời nên thường rất khó để tìm ra câu trả lời đúng (câu này).
Carlo Wood

3

Thư viện Boost nào? Nhiều người trong số họ là các mẫu thuần túy và không yêu cầu liên kết.

Bây giờ với ví dụ cụ thể thực sự được hiển thị cho chúng tôi biết rằng bạn muốn các tùy chọn chương trình Boost (và thậm chí còn cho chúng tôi biết rằng bạn đang sử dụng Ubuntu), bạn cần phải làm hai điều:

  1. Cài đặt libboost-program-options-devđể bạn có thể liên kết với nó.
  2. Bảo cmakeđể liên kết chống lại libboost_program_options.

Tôi chủ yếu sử dụng Makefiles vì ​​vậy đây là cách sử dụng dòng lệnh trực tiếp:

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

Có vẻ như nó không làm được gì nhiều.

Đối với CMake, bạn cần thêm boost_program_options vào danh sách thư viện và IIRC điều này được thực hiện thông qua SET(liblist boost_program_options)trong của bạn CMakeLists.txt.


11
Lời khuyên CMake của bạn là sai (xem câu trả lời được chấp nhận) và lời khuyên dòng lệnh của bạn không hữu ích lắm như câu hỏi về CMake.
Ela782

3

Hai cách, sử dụng đường dẫn cài đặt mặc định của hệ thống, thường là /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}
        )

Nếu bạn cài đặt Boost trong thư mục cục bộ hoặc chọn cài đặt cục bộ thay vì cài đặt hệ thống, bạn có thể thực hiện bằng cách này:

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

Lưu ý dir ở trên /home/xy/boost_install/lib/là nơi tôi cài đặt 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/

Nếu bạn quan tâm đến cách sử dụng Boost được cài đặt cục bộ, bạn có thể xem câu hỏi này Làm cách nào để CMake tìm được cài đặt Boost thay thế của tôi? .


2

Đây là cách của tôi:

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) sẽ xuất hiện lỗi CMAKE: - Đã định cấu hình xong CMake Error tại CMakeLists.txt: 102 (add_executable): Nhắm mục tiêu các liên kết "DB32" tới mục tiêu "Boost :: program_options" nhưng không tìm thấy mục tiêu . Có lẽ thiếu lệnh gọi find_package () đối với mục tiêu IMPORTED hoặc thiếu mục tiêu ALIAS?
munsingh

Xin chào, cảm ơn vì đã phản hồi. Có vẻ như CMake không thể xác định vị trí Boost trên hệ thống của bạn. Có lẽ bạn nên tạo một bản dựng mới của Boost từ nguồn. Trước đó, bạn có thể muốn thử những cách sau: Tìm gói find_package(Boost QUIET REQUIRED)và liên kết đến mục tiêu của bạn (DB32):target_link_libraries(DB32 PUBLIC Boost::headers)
adem
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.