如何使用 CMake 自动链接 boost 库

Posted

技术标签:

【中文标题】如何使用 CMake 自动链接 boost 库【英文标题】:How to auto-link boost libraries with CMake 【发布时间】:2020-02-12 03:24:06 【问题描述】:
project(learn)

cmake_minimum_required(VERSION 3.11)

set(CMAKE_CXX_STANDARD 17)

if($CMAKE_SYSTEM_NAME STREQUAL "Linux")
    message("Current OS is Linux")
    include_directories("/mnt/e/c++/boost_1_72_0")
    link_directories("/mnt/e/c++/boost_1_72_0/stage/lib")
    link_libraries(pthread boost_thread boost_fiber boost_context)
elseif($CMAKE_SYSTEM_NAME STREQUAL "Windows")
    message("Current OS is Windows")
    include_directories("E:/c++/boost_1_72_0")
    link_directories("E:/c++/boost_1_72_0/stage/lib")
endif($CMAKE_SYSTEM_NAME STREQUAL "Linux")

add_executable(learn_asio learn_asio.cpp)

learn_asio.cpp:

#include <boost/asio.hpp>
#include <boost/fiber/all.hpp>
#include <boost/thread.hpp>
#include <iostream>

using boost::asio::async_write;
using boost::asio::buffer;
using boost::asio::io_context;
using boost::asio::use_future;
using boost::asio::ip::make_address;
using boost::asio::ip::tcp;
using boost::fibers::async;
using boost::fibers::fiber;
using boost::system::error_code;

int main()
  io_context ioc;
  tcp::socket socket(ioc);

  tcp::endpoint ep(make_address("192.168.1.20"), 80);

  auto ret_f = socket.async_connect(ep, boost::asio::use_future);

  boost::thread_group t;
  t.create_thread([&ioc]() 
    ioc.run();
    std::cout << "jfiejf" << std::endl;
  );

  ret_f.wait_for(std::chrono::seconds(3));

  t.join_all();

  return 0;

我的图书馆文件夹: 根据上面的代码,我可以成功构建我的代码。但我讨厌代码:

link_libraries(pthread boost_thread boost_fiber boost_context)

在 linux 平台上。为什么我在 Windows 平台上不需要它? 我记得 Linux 也可以自动链接库。 我怎样才能实现它?

【问题讨论】:

我把代码贴在上面了。你能看出哪里出了问题吗? 【参考方案1】:

Boost docs:

自动链接

大多数 Windows 编译器和链接器都具有所谓的“自动链接支持”,从而消除了第二个挑战。 Boost 头文件中的特殊代码检测您的编译器选项并使用该信息将正确库的名称编码到您的目标文件中;链接器从您告诉它搜索的目录中选择具有该名称的库。

GCC 工具链(Cygwin 和 MinGW)是明显的例外; GCC 用户应参考linking instructions for Unix variant OSes 以了解要使用的适当命令行选项。

请注意,已知自动链接功能有时会失败(例如,当您的 Boost 库使用非标准设置安装时)。您可以定义BOOST_ALL_NO_LIB禁用 Windows 上的功能。

不过,您不应该将 Boost 路径硬编码到 CMakeLists.txt 中。最好使用平台无关的find_package

set( Boost_USE_STATIC_LIBS OFF )
set( Boost_USE_MULTITHREADED ON )
set( Boost_USE_STATIC_RUNTIME OFF )

find_package( Boost 1.72.0 COMPONENTS thread fiber context )

if ( Boost_FOUND )
    include_directories( $Boost_INCLUDE_DIRS )
    link_libraries( learn_asio $Boost_LIBRARIES )
else()
    message( FATAL_ERROR "Required Boost packages not found. Perhaps add -DBOOST_ROOT?" )
endif()
    

【讨论】:

以上是关于如何使用 CMake 自动链接 boost 库的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在 cmake 中自动链接 Qt5 库?

CMake配置工程链接库

Clion使用MinGW编译好的boost库

在 CMake 中链接 boost 文件系统的问题

cmake - 如何链接Boost的sub_directory头文件(例如:/archive/text_oarchive.hpp)?

Linux下使用CMake进行编译的时候寻找Boost库