使用 FetchContent_Declare 时如何包含外部模块标头?

Tyr*_*eus 6 c++ git cmake

我想在我的新项目中使用现代 CMake 项目结构约定,以遵循良好实践并与许多其他项目保持一致,但我面临包含路径的问题。

\n

我的目录结构如下:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 extern\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.cpp\n
Run Code Online (Sandbox Code Playgroud)\n

我想使用FetchContent_Declare而不是git 子模块来管理第三方库。

\n

根: CMakeLists.txt

\n
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)\nset(ProjectName "MyApp")\n\nproject(${ProjectName})\n\nadd_subdirectory(extern)\nadd_subdirectory(src)\n
Run Code Online (Sandbox Code Playgroud)\n

外部: CMakeLists.txt

\n
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)\n\ninclude(FetchContent)\nFetchContent_Declare(\n  extern_spdlog\n\n  GIT_REPOSITORY https://github.com/gabime/spdlog.git\n  GIT_TAG        v1.8.2)\n\nFetchContent_GetProperties(extern_spdlog)\nif(NOT extern_spdlog_POPULATED)\n  FetchContent_Populate(extern_spdlog)\n  add_subdirectory(\n    ${extern_spdlog_SOURCE_DIR}\n    ${extern_spdlog_BINARY_DIR}\n  )\nendif()\n
Run Code Online (Sandbox Code Playgroud)\n

代码CMakeLists.txt

\n
cmake_minimum_required(VERSION 3.16)\n\nset(BINARY ${CMAKE_PROJECT_NAME})\n\nfile(GLOB_RECURSE SOURCES LIST_DIRECTORIES true *.h *.cpp)\nset(SOURCES ${SOURCES})\n\nadd_executable(${BINARY}_run ${SOURCES})\n\nadd_library(${BINARY}_lib STATIC ${SOURCES})\n\ntarget_link_libraries(${BINARY}_run extern_spdlog)\n
Run Code Online (Sandbox Code Playgroud)\n

还有main.cpp

\n
#include <spdlog/spdlog.h>\n\nint main(int argc, char* argv[]) {\n    spdlog::info("Welcome to spdlog!");\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

CMake 执行并且spdlog库被正确克隆,并且可以在构建目录中找到:build/_deps/extern_spdlog-src

\n

如果我调用make目录build,那么我会得到fatal error: spdlog/spdlog.h: No such file or directory.

\n

如何为应用程序中使用的外部库添加包含目录?

\n

小智 2

我最初对此也感到困惑。FetchContent目标的名称通常与导入的目标的名称匹配并没有帮助。对我有用的内容与第一条评论所述相似(尽管不相同)。我使用了target_link_libraries(target spdlog::spdlog)(如果您想使用预编译库或者spdlog::spdlog_header_only如果您想使用仅标头源版本。