gpt4 book ai didi

cmake - 我将如何使用 CMake 包含 asio 库?

转载 作者:行者123 更新时间:2023-12-05 02:56:25 40 4
gpt4 key购买 nike

我正在尝试为一个类(class)做一个项目,我想使用 CMake 来构建该项目。我当前的项目看起来像

|-bin
|-CMakeLists.txt
|-include
|-asio-1.12.2
|-chat_message.hpp
|-chat_message.cpp
|-CMakeLists.txt
|-src
|-Server.cpp

尽管我的 Server.cpp 需要 /include/asio-1.12.2/include 中的 asio.hpp。教授有一个用标志编译它的makefile-DASIO_STANDALONE -Wall -O0 -g -std=c++11 -I./include -I./include/asio-1.12.2/include。我的 CMakeLists 文件如下所示:./CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
PROJECT(Server VERSION 0.0.1)
SET(CPP_STANDARD 11)
SET(CPP_STANDARD_REQUIRED True)
ADD_SUBDIRECTORY(include)
ADD_EXECUTABLE(Server src/Server.cpp)
TARGET_LINK_LIBRARIES(
Server PRIVATE
chat_message
asio
)

./include/CMakeLists.txt

ADD_LIBRARY(
chat_message
chat_message.cpp
chat_message.hpp
)
ADD_LIBRARY(
asio
asio-1.12.2/include/asio.cpp
asio-1.12.2/include/asio.hpp
)
TARGET_INCLUDE_DIRECTORIES(
chat_message PUBLIC "${CMAKE_SOURCE_DIR}/include"
asio PUBLIC "${CMAKE_SOURCE_DIR}/include/asio-1.12.2/include"
)

如何使用所需的标志将 asio 头文件链接到 Server.cpp 文件?

最佳答案

首先,作为Tzyvarev pointed out in the comments , 你必须拆分 target_include_directories()命令分为两个单独的命令。然后这将传播 asiochat_message的包含目录到您的 Server目标,它将把正确的包含标志添加到编译器标志。

注意:我建议从 CMAKE_SOURCE_DIR 切换至 CMAKE_CURRENT_SOURCE_DIR如果将来您决定更改项目结构,并相应地更改您的路径以使您的生活稍微轻松一些,因为您通常会将 CMakeLists.txt 文件与其创建的目标的源放在同一目录中。

-DASIO_STANDALONE选项可以添加 target_compile_definitions()调用:

target_compile_definitions(asio PUBLIC ASIO_STANDALONE)

请注意,您不需要 -D - CMake 将为您生成正确的编译器标志。此外,由于这是 asio 的要求target 和它的所有消费者都需要它,它应该被添加到那个,而不是它的消费者 - 然后它会根据需要传播到依赖项。

在您的 CMakeLists.txt 中,您设置了 CPP_STANDARDCPP_STANDARD_REQUIRED变量。你要找的是CMAKE_CXX_STANDARDCMAKE_CXX_STANDARD_REQUIRED分别。

这将为整个项目中的所有目标设置标志。

添加错误、优化和调试符号标志的方法有多种,您使用哪种方法取决于您的用例。以下并非详尽列表。

  • 如果您希望构建库的每个人都拥有这些,而不考虑构建配置(调试/发布/等),您可以设置 CMAKE_CXX_FLAGS CMakeLists.txt 中的变量
  • 如果您希望每个人都拥有这些标志,但仅限于某些构建类型,请设置 CMAKE_CXX_FLAGS_<CONFIG>变量,其中 <CONFIG>是选择的构建类型(DEBUG/RELEASE/MINSIZEREL/RELWITHDEBINFO 默认可用)
  • 如果您不想将标志强加给每个人,在调用 CMake 之前您可以设置 CXXFLAGS环境变量。但请注意,根据文档,如果 CMAKE_CXX_FLAGS 这将无效在您的 CMake 脚本中设置。
  • 如果你想为单个目标添加标志,你可以调用target_compile_options在其上,并设置适当的可见性选项以启用/禁用向消费者的传播。

但是一般来说,您在使用这些时确实需要考虑可移植性。例如,GCC 可能支持某个标志,而在 Clang 中可能会有所不同。

编辑到地址this评论

由于 header-only ASIO 库不喜欢使用上述编译器定义进行编译,因此有两种解决方法:

移除 ASIO_STANDALONE 编译器标志

从您的角度来看,这将是最简单的事情,但作为链式 react ,它需要您在系统上安装 Boost,因为没有上面的标志会导致预处理器运行通过一些 Boost 包括。可能还有其他影响,但这是我在继续下面的解决方案之前遇到的第一个。

保留flag,使用CMake接口(interface)库

add_library()可以允许您添加一个目标,该目标实际上不会生成任何已编译的对象/库/可执行文件,而只是一个逻辑 CMake 目标,它可以像任何其他目标一样拥有属性 - 包括目录,链接库等。所以至少你可以这样做:

add_library(asio INTERFACE)
target_compile_options(asio INTERFACE ASIO_STANDALONE)
target_include_directories(asio INTERFACE <dir where asio.hpp lives>)
target_link_libraries(asio INTERFACE <threads>) # Using ASIO requires you link your final executable/library with your system's threading library (e.g. pthread on linux)

然后当你将另一个目标链接到它时

target_link_libraries(any_lib PRIVATE asio)

any_lib将继承使用 ASIO 构建所需的所有属性。

您选择的解决方案将取决于您的用例,但如果您必须按照与您的教授相同的方式进行操作,那么请选择 INTERFACE 库路线。

关于cmake - 我将如何使用 CMake 包含 asio 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60592615/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com