Rub*_*-96 3 cmake boost-asio asio
我正在尝试为一个班级开发一个项目,并且我想使用 CMake 来构建该项目。我当前的项目看起来像
|-bin
|-CMakeLists.txt
|-include
|-asio-1.12.2
|-chat_message.hpp
|-chat_message.cpp
|-CMakeLists.txt
|-src
|-Server.cpp
Run Code Online (Sandbox Code Playgroud)
虽然我的 Server.cpp 需要/include/asio-1.12.2/include. 教授有一个 makefile,可以用 flags 来编译它
-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
)
Run Code Online (Sandbox Code Playgroud)
./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"
)
Run Code Online (Sandbox Code Playgroud)
如何将 asio 头文件链接到带有所需标志的 Server.cpp 文件?
首先,正如Tzyvarev 在评论中指出的那样,您必须将target_include_directories()命令拆分为两个单独的命令。然后,这会将asioandchat_message的包含目录传播到您的Server目标,这会将正确的包含标志添加到编译器标志中。
注意:我建议从CMAKE_SOURCE_DIR切换到CMAKE_CURRENT_SOURCE_DIR并相应地更改路径,以便将来您决定更改项目结构时使您的生活稍微轻松一些,因为您通常会将 CMakeLists.txt 文件保留在与源相同的目录中对于它创建的目标。
-DASIO_STANDALONE可以通过调用添加该选项target_compile_definitions():
target_compile_definitions(asio PUBLIC ASIO_STANDALONE)
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要-D - CMake 将为您生成正确的编译器标志。此外,由于这是目标的要求asio,并且其所有使用者都需要它,因此应该将其添加到目标中,而不是其使用者 - 然后它将根据需要传播到依赖项。
在 CMakeLists.txt 中,您已设置CPP_STANDARD和CPP_STANDARD_REQUIRED变量。你要找的分别是CMAKE_CXX_STANDARD和CMAKE_CXX_STANDARD_REQUIRED。
这将为整个项目的所有目标设置标志。
添加错误、优化和调试符号标志的方法有多种,您使用哪一种取决于您的用例。以下并不是详尽的列表。
CMAKE_CXX_FLAGS_<CONFIG>,其中<CONFIG>选择了构建类型(DEBUG/RELEASE/MINSIZEREL/RELWITHDEBINFO 默认情况下可用)CMAKE_CXX_FLAGS在 CMake 脚本中设置,这将无效。但一般来说,使用这些时您确实需要考虑可移植性。例如,GCC 可能支持某个标志,但在 Clang 中可能有所不同。
由于纯头文件 ASIO 库不喜欢使用上面提到的编译器定义进行编译,因此有两种方法可以解决它:
从您的角度来看,这将是最简单的事情,但作为连锁反应,它将要求您在系统上安装 Boost,因为没有上面的标志将导致预处理器经历一些 Boost包括。可能还有其他影响,但这是我在继续下面的解决方案之前遇到的第一个影响。
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)
Run Code Online (Sandbox Code Playgroud)
然后当你将另一个目标与它链接时
target_link_libraries(any_lib PRIVATE asio)
Run Code Online (Sandbox Code Playgroud)
any_lib将继承使用 ASIO 构建所需的所有属性。
您选择的解决方案将取决于您的用例,但如果您必须按照与教授相同的方式进行操作,那么请选择 INTERFACE 库路线。
| 归档时间: |
|
| 查看次数: |
9930 次 |
| 最近记录: |