c++ - 如何在 CMake 中构建其他文件夹
问题描述
我的文件夹结构如下:
|-CMakeLists.txt
|-main.cpp
|-network
---------- CMakeLists.txt
---------- network.h
---------- network.cpp
其中 network 是包含最后 3 个项目的文件夹。
我正在努力在 CMake 中构建它,因为文档对我来说非常陌生。在我的根 CMakeLists.txt 中,如下所示:
cmake_minimum_required(VERSION 3.11.0)
project(Test)
set(CMAKE_CXX_STANDARD 11)
include_directories ("${PROJECT_SOURCE_DIR}/network")
add_subdirectory (${PROJECT_SOURCE_DIR}/network)
add_executable(server main.cpp)
target_link_libraries (network)
find_package(Boost 1.67 REQUIRED COMPONENTS thread)
# Check for libray, if found print message, include dirs and link libraries.
if(Boost_FOUND)
message("Boost Found")
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(server ${Boost_LIBRARIES})
target_link_libraries(server Boost::thread)
elseif(NOT Boost_FOUND)
error("Boost Not Found")
endif()
在网络文件夹中的 CMakeLists.txt 中,如下所示:
cmake_minimum_required(VERSION 3.11.0)
project(Test)
set(CMAKE_CXX_STANDARD 11)
install(FILES ${MY_HEADER_FILES} DESTINATION ./)
add_executable(network network.cpp)
我自己做了这个,看看是否可以让 CMake 将该文件夹中的文件添加到根项目中。显然,这一切都失败了,因为我很难从文档中理解 CMake。我很抱歉。由于无法识别“network.cpp”中的实现,我收到一个错误:
main.cpp:(.text+0x409): undefined reference to `Socket::GetThis()'
我确定实现没有任何问题,因为它使用另一轮方法工作,但我想使用以前的结构构建我的项目,但我不知道如何制作根 CMakeLists 和网络 CMakeLists 以便他们一起工作。
如何设计 CMakeLists,以便将网络标头和实现包含在根项目中。此外,网络库也将使用 Boost。我也应该在那里找到包裹吗?
解决方案
target_link_libraries (network)
您想将“服务器”可执行文件与“网络”库链接。就像这样:
target_link_libraries(server PUBLIC network)
PUBLIC
可以省略,但我喜欢在任何地方指定它。
还:
add_executable(network network.cpp)
真的应该network.spp
是可执行文件吗?我猜 network.cpp 中没有main
。你应该:
add_library(network network.cpp)
而且我想network
包含路径是网络库不可或缺的。所以我会在里面network/CMakeLists.txt
做:
target_include_directories(network PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
另请注意,target_compile_feature
首选优于set(CMAKE_CXX_STANDARD 11)
.
此外,没有任何error()
功能。有message(FATAL_ERROR)
。
总而言之,我会这样写:
# root/CMakeLists.txt
cmake_minimum_required(VERSION 3.11.0)
project(Test)
# this tells cmake that all c++ files that are in this file
# and all in add_subdirectory projects
# will compile with C++11 (by default)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(network)
add_executable(server main.cpp)
# tell cmake to link server with network library
# ie. server executable uses network library
target_link_libraries(server PUBLIC network)
find_package(Boost 1.67 REQUIRED COMPONENTS thread)
# Check for libray, if found print message, include dirs and link libraries.
if(Boost_FOUND)
message(STATUS "Boost Found")
target_include_directories(server PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(server PUBLIC ${Boost_LIBRARIES} Boost::thread)
elseif(NOT Boost_FOUND)
message(FATAL_ERROR "Boost Not Found")
endif()
和:
# network/CMakeLists.txt
add_libraries(network network.cpp)
# tell cmake, that all targets that link with network library
# will have include path added
target_include_directories(network PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
我只将服务器可执行文件与 boost 链接起来。我不知道您的network
图书馆是否也需要与 boost 链接,如果需要,请移动 boost 信息netowrk/CMakeLists.txt
并target_link_libraries(network PUBLIC ${Boost_LIBRARIES})
推荐阅读
- scala - 使用 mockito 模拟可变参数元组
- java - TCP 套接字未读取第二个响应
- arrays - 如何使用数组过滤器“where”来选择没有图像的变体?
- python - 难以从 python 脚本执行 shell 脚本
- java - 为什么我们不需要初始化实例变量
- javascript - 如何按键排序对象数组?无法正确处理
- php - 在 php 和 sql 中创建访客结帐
- javascript - 触摸/单击和输入事件侦听器未触发 iOS
- python - 如何在 Pandas Dataframe 中向 datetime64 对象添加分钟
- ruby-on-rails - 一个模型在另一个模型中的 CRUD