C++ 使用CMake添加仅标题依赖项
我有一个简单的项目,它需要三个只包含头的库来编译:,和 项目结构如下所示:C++ 使用CMake添加仅标题依赖项,c++,cmake,spdlog,nlohmann-json,C++,Cmake,Spdlog,Nlohmann Json,我有一个简单的项目,它需要三个只包含头的库来编译:,和 项目结构如下所示: └── src ├── app │ ├── CMakeLists.txt │ ├── src │ └── test ├── CMakeLists.txt ├── core │ ├── CMakeLists.txt │ ├── include │ ├── src │ └── test └── vendor
└── src
├── app
│ ├── CMakeLists.txt
│ ├── src
│ └── test
├── CMakeLists.txt
├── core
│ ├── CMakeLists.txt
│ ├── include
│ ├── src
│ └── test
└── vendor
├── install.cmake
├── nlohmann_json
├── spdlog
└── websocketpp
根CMakeLists.txt如下所示:
cmake_minimum_required(VERSION 3.6.1 FATAL_ERROR)
..
# External 3rd party libs that we include
include(vendor/install.cmake)
add_subdirectory(core)
add_subdirectory(app)
基本上,每个子目录都是一个库(例如,core
),而app
“聚合”了所有子目录。每个库(例如,core
)的构建方式如下(core/CMakeLists.txt
):
到目前为止还不错:您可以看到依赖项是作为git子模块获取的,谢天谢地,这使管理它们变得更容易。但是,当我使用mkdir build&&cd build&&cmake../src
编译我的项目时,我有以下错误:
CMake错误:安装(导出FooCoreConfig…)包括目标
foo core需要导出中不存在的目标websocketpp
设定
CMake错误:安装(导出FooCoreConfig…)包括目标
foo core,它需要不在导出集中的目标spdlog
包含标题,例如#include
或#include
会产生错误,表明未找到标题
说实话,我对CMake不太满意,我在过去的两天里一直在调试它。这可能很简单,但我不知道如何实现它。事实上,人们只需传递-I作为编译器标志,就可以像我所希望的那样使用库,但CMake抽象似乎让我感到困惑。如果有人能解释为什么这不起作用,我会非常高兴,希望能解释一下,将这些库包含到我的项目中的正确方法是什么。提前谢谢 正如您所说:您没有在导出集中安装目标。换言之,您缺少仅标头目标的
安装(导出…
行。例如,考虑到仅标头库websocketpp
,您应该:
add_library(websocketpp INTERFACE)
target_include_directories(websocketpp INTERFACE
$<BUILD_INTERFACE:${WEBSOCKETPP_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS websocketpp EXPORT websocketpp-config DESTINATION include)
# here is the missing line:
install(EXPORT websocketpp-config DESTINATION share/websocketpp/cmake)
add_库(websocketpp接口)
目标目录包括目录(websocketpp接口
$
$)
安装(目标websocketpp导出websocketpp配置目标包括)
#这是遗漏的一行:
安装(导出websocketpp配置目标共享/websocketpp/cmake)
其他库也是如此。谢谢,我添加了它,但是,对于
websocketpp
库,我收到了相同的消息:“CMake Error in core/CMakeLists.txt:export调用了target foo core,它需要不在导出集中的target websocketpp”和“如果调用此调用中的目标不容易引用,请考虑使用多个独立调用的AppEnter选项。"。奇怪的是,该文件似乎位于build/CMakeFiles/Export/share/websocketpp/cmake/websocketpp.cmake
,为什么找不到它?@arnaudoff这可能来自文件名,它应该遵循给定的模式。我编辑了我的答案,尝试使用修改后的名称websocketpp config
@arnaudoff我想我得到了:removecore/CMakeLists.txt
中的export
行。这不应用于目标安装。您将在执行make install
时生成导出。好的,这解决了导出集的问题,但我仍然得到标题包含错误,例如:“致命错误:nlohmann/json.hpp:没有这样的文件或目录#include”。我想这与生成器表达式中的路径有关,但至少对我来说它们看起来不错。有什么想法吗?@arnaudoff查看您的代码,set
和install
行建议到json.hpp
的路径是$在构建时,{CMAKE_CURRENT_SOURCE_DIR}/vendor/nlohmann_json/src/json.hpp
,这与#include
不一致。您应该有#include“json.hpp”
(注意使用“
而不是
作为系统头)。检查路径,并使其一致
# spdlog
if((NOT SPDLOG_INCLUDE_DIR) OR (NOT EXISTS ${SPDLOG_INCLUDE_DIR}))
message("Unable to find spdlog, cloning...")
execute_process(COMMAND git submodule update --init -- vendor/spdlog
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(SPDLOG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/spdlog/include/
CACHE PATH "spdlog include directory")
install(DIRECTORY ${SPDLOG_INCLUDE_DIR}/spdlog DESTINATION include)
# Setup a target
add_library(spdlog INTERFACE)
target_include_directories(spdlog INTERFACE
$<BUILD_INTERFACE:${SPDLOG_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS spdlog EXPORT spdlog DESTINATION include)
endif()
# websocketpp
if((NOT WEBSOCKETPP_INCLUDE_DIR) OR (NOT EXISTS ${WEBSOCKETPP_INCLUDE_DIR}))
message("Unable to find websocketpp, cloning...")
execute_process(COMMAND git submodule update --init -- vendor/websocketpp
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(WEBSOCKETPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp/
CACHE PATH "websocketpp include directory")
install(DIRECTORY ${WEBSOCKETPP_INCLUDE_DIR}/websocketpp DESTINATION include)
# Setup a target
add_library(websocketpp INTERFACE)
target_include_directories(websocketpp INTERFACE
$<BUILD_INTERFACE:${WEBSOCKETPP_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS websocketpp EXPORT websocketpp DESTINATION include)
endif()
# nlohmann/json
if((NOT NLOHMANN_JSON_INCLUDE_DIR) OR (NOT EXISTS ${NLOHMANN_JSON_INCLUDE_DIR}))
message("Unable to find nlohmann/json, cloning...")
execute_process(COMMAND git submodule update --init -- vendor/nlohmann_json
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(NLOHMANN_JSON_INCLUDE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/vendor/nlohmann_json/src/
CACHE PATH "nlohmann/json include directory")
install(FILES ${NLOHMANN_JSON_INCLUDE_DIR}/json.hpp DESTINATION include)
# Setup a target
add_library(nlohmann_json INTERFACE )
target_include_directories(nlohmann_json INTERFACE
$<BUILD_INTERFACE:${NLOHMANN_JSON_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS nlohmann_json EXPORT nlohmann_json DESTINATION include)
endif()
add_library(websocketpp INTERFACE)
target_include_directories(websocketpp INTERFACE
$<BUILD_INTERFACE:${WEBSOCKETPP_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS websocketpp EXPORT websocketpp-config DESTINATION include)
# here is the missing line:
install(EXPORT websocketpp-config DESTINATION share/websocketpp/cmake)