【问题标题】:Using asio standalone headers library使用 asio 独立头文件库
【发布时间】:2016-04-09 13:20:26
【问题描述】:

这就是我的CMakeLists.txt 的样子

我从here 下载了asio 库。它由许多必须包含在项目中的头文件组成。问题是这些标头位于目录内,而 #include 语句与正确的目录不匹配。

例如,他们有一个asio/async_result.hpp 文件。该文件包括asio/detail/config.hpp。不过应该是../asio/detail/config.hpp

我该怎么办?轻松重命名所有这 200 个头文件以适应正确的目录结构?为什么他们开箱即用就错了?

【问题讨论】:

  • 只是给未来读者的一个提示:asio 现在是boost::asio 的一部分。不要单独安装,而是从 boost 中获取。
  • Asio 中的包含指令要求 Asio 在包含路径中可用。通过include_directories()server_client 目录添加到包含路径到您的CMakeLists.txt 文件是否可以解决问题(例如include_directories(${CMAKE_CURRENT_SOURCE_DIR})
  • @TannerSansbury 我正在写这个问题的答案
  • @MarcusMüller Standalone asio 仍然存在,并且正在开发成为标准库的一部分,所以我觉得在不久的将来独立版本将是一个更好的选择。
  • @MarcusMüller 如果您不使用 Boost 的其他部分,那么独立的可能更可取。独立版本仅包含标头,但 Boost 版本不是 - 如果您不必与任何 Boost 库链接,仅此一项就足以让您更喜欢它。

标签: c++ cmake boost-asio


【解决方案1】:

这是一个简单的 CMake 脚本,它使用 ASIO 独立构建示例 HTTP 客户端,设置为生成 Visual Studio 2019 项目

cmake -H. -Bbuild -G "Visual Studio 16 2019" -A x64 

https://think-async.com/Asio/AsioStandalone.html

(没有提升)。假定文件夹 asio-1.12.2 中的源代码

cmake_minimum_required(VERSION 3.1)
project (asio)

set(CMAKE_CXX_STANDARD 11)
add_definitions(-DASIO_STANDALONE)
add_definitions(-DASIO_HAS_STD_ADDRESSOF)
add_definitions(-DASIO_HAS_STD_ARRAY)
add_definitions(-DASIO_HAS_CSTDINT)
add_definitions(-DASIO_HAS_STD_SHARED_PTR)
add_definitions(-DASIO_HAS_STD_TYPE_TRAITS)
add_definitions(-DASIO_HAS_VARIADIC_TEMPLATES)
add_definitions(-DASIO_HAS_STD_FUNCTION)
add_definitions(-DASIO_HAS_STD_CHRONO)
add_definitions(-DBOOST_ALL_NO_LIB)
add_definitions(-D_WIN32_WINNT=0x0501)
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS)

include_directories(asio-1.12.2/include)
add_executable(sync_client asio-1.12.2/src/examples/cpp11/socks4/sync_client.cpp)

【讨论】:

    【解决方案2】:

    您必须先安装这些标头。在大多数系统上(当然,除了 windows),都有一个典型的路径,这些包含文件最终会出现。

    在您的计算机上查找 asio 并配置编译器是项目构建系统(例如 Cmake)的工作,以便它在这些文件夹中查找,并在您这样做时找到正确的文件

    #include <asio/handler_type.hpp>
    

    永远不要在您使用的库创建您的项目(当然,除非您想更改/扩展该库)。在其他地方创建一个项目并告诉 cmake 寻找 asio。

    此外,除非您的源代码是库本身的一部分,否则您永远不应包含 _detail.hpp 文件;这些通常不是库用户使用的 API 的一部分,而是内部结构。

    编辑

    如上所述,asio 现在是 boost 的一部分,所以正确安装 boost 包括它的boost::asio 模块,指示 cmake

     find_package(Boost COMPONENTS asio)
    

    并使用例如

     #include <boost/asio.hpp>
     #include <boost/thread/thread.hpp>
    

    更多示例请参考官方Boost asio Tutorial

    【讨论】:

    • 我该如何安装标头?
    • @Shiro 将它们复制到正确的目录中。通常,库附带安装脚本和说明。
    • 顺便说一下,今天有人会使用boost::asio 而不是asio,因为asio 在很久以前就被包含在boost 中,并且在boost 社区中不断发展。
    • 大部分开发发生在 Asio 库中,然后被移植到 Boost.Asio。如果不希望引入对 Boost 的依赖,使用尚未登陆 Boost.Asio 的功能,或者希望尝试 Networking TS 更改,则非 Boost Asio 是一种选择。
    • 就其价值而言,我的经验是,非 Boost Asio 的稳定版本提供的稳定 API 与 Boost.Asio 的稳定版本一样多。
    【解决方案3】:

    这是我的工作更新CMakeLists.txt

    cmake_minimum_required(VERSION 3.3)
    project(server_client)
    
    # take a look at the -I command
    # this will incude all the header files in your project. So simple
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -I C:/Users/Shiro/Desktop/asio-1.10.6/include")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS} -static")
    # Don't forget this! The libws2_re.lib library is 100% required for windows !
    # I also added libwsock32.lib, not sure if thats necessary
    # Those .lib files are located at C:\MinGW\lib on my machine
    # That directory is located automatically, you don't have to add the full path
    link_libraries(ws2_32 wsock32)
    
    
    set(SOURCE_FILES chat_server.cpp)
    add_executable(server_client ${SOURCE_FILES})
    

    在我的来源.cpp 文件中,您必须添加

    // this is required otherwise asio tries to include 
    // other boost libraries which you won't have installed
    // or you could add a -DASIO_STANDALONE flag right next to -std=c++11 in CMakeLists.txt
    #define ASIO_STANDALONE  
    
    #ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x0501 // windows stuff, not sure what this does
    #endif
    
    #include <asio.hpp> // include asio library
    

    【讨论】:

    • 这是一种糟糕的风格;通常最好使用现有的 CMake“查找...”模块来设置包含和链接器选项,或者自己编写一个;像这样,使用 cmake 真的收获很少。同样,对于独立的 asio,没有“标准”cmake 模块可以精简,(but googling finds some that you'd only have to amend with a few hints for windows),但对于 boost::asio,您可以获得经过充分测试、强大的库查找例程。
    • 在这里对“我承认我不知道自己在做什么”#define 投反对票:您将windows version constant 任意设置为 Windows XP,具有无法预料的副作用。将您的操作系统和操作系统版本硬编码到您的代码中会使它变得不可移植。同样,您应该在 CMake 中检测您的 Windows 版本并进行适当的设置。
    • @MarcusMüller 您是说-I 标志是在我的项目中包含仅标头库的不好方法?在我的 IDE Clion 中,该库可以完美地识别该库。你到底在建议什么?就_WIN32_WINNT 版本而言,我相信windows XP 版本只是最低要求,因此使用它可以运行到windows XP 机器及更高版本。这是我在没有定义该标志的情况下编译时从warning 得到的印象。
    • @MarcusMüller 此外,仅标头库比 boost 库更便携。当您可以复制并粘贴asio 的2MB 头库然后在您的Linux 机器上使用g++ 编译时执行-I asio 时,谁愿意经历安装额外库的过程?如果有的话,boost 只会占用大量磁盘空间并执行相同的工作,而且安装需要更多时间。这就是图书馆 header-only 的意义所在
    • boost::asio 和独立的asio 一样只有标题。关于“如果他只能获得标题 asio,谁愿意安装完整的提升”?也许有人对构建工具不太有经验。特别是,我在想你:) 这就是我推荐它的原因。你对独立的asio 更满意,所以去吧。我还是不推荐。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多