You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

预编译spdlog(含外部fmt库)编译报错:spdlog/fmt/fmt.h头文件未找到

问题描述

开发环境:Windows 10 + MSYS2 GCC
需求:在项目中使用依赖外部fmt库的预编译spdlog

已执行操作:

  1. 编译spdlog:
git clone https://github.com/gabime/spdlog.git
cd spdlog && mkdir build && cd build
cmake -DSPDLOG_FMT_EXTERNAL=ON .. && ninja
  1. 文件复制:
    • 将spdlog/build下的生成文件复制到项目目录MY_PROJECT/spdlog_precompiled
    • 将spdlog根目录下的include文件夹复制到MY_PROJECT目录(该目录包含spdlog/fmt/fmt.h)
  2. 项目CMakeLists.txt配置(NAME为目标名称):
set(spdlog_DIR ${CMAKE_SOURCE_DIR}/spdlog_precompiled)
find_package(spdlog REQUIRED)

target_link_libraries(
  ${NAME}
  spdlog::spdlog $<$<BOOL:${MINGW}>:ws2_32>)

target_include_directories(${NAME} ${CMAKE_SOURCE_DIR}/include)

编译错误信息:

C:/Development/Spirallo/WinCanSpiralloComponent/src/spirallolib/DebugLog.hpp:10:10: fatal error: spdlog/fmt/fmt.h: No such file or directory
   10 | #include "spdlog/fmt/fmt.h"
      |          ^~~~~~~~~~~~~~~~~~

即使在顶层CMakeLists.txt添加include_directories(include),错误仍存在。

问题分析与解决

核心错误点

  1. SPDLOG_FMT_EXTERNAL=ON的本质误解:启用该选项后,spdlog不会内置fmt代码,仅提供spdlog/fmt/fmt.h作为转发头文件,实际需要依赖独立编译的外部fmt库的头文件和库文件,你未引入外部fmt的依赖。
  2. CMake配置语法错误:target_include_directories缺少PRIVATE/PUBLIC/INTERFACE关键字,CMake会忽略这条配置,导致复制的include路径未被正确添加到目标编译路径中。
  3. 预编译spdlog的依赖缺失:编译spdlog时未指定外部fmt的路径,生成的spdlog配置文件无法正确关联fmt,后续项目中find_package(spdlog)也无法自动引入fmt依赖。

修正步骤

1. 先编译并引入外部fmt库

# 克隆fmt仓库并编译
git clone https://github.com/fmtlib/fmt.git
cd fmt && mkdir build && cd build
cmake .. && ninja
# 复制文件到项目目录
# 将build下的生成文件复制到 MY_PROJECT/fmt_precompiled
# 将fmt根目录的include/fmt文件夹复制到 MY_PROJECT/include/fmt

2. 重新编译spdlog(关联外部fmt)

cd spdlog/build
rm -rf * # 清空之前的编译产物
# 指定外部fmt的路径,再编译spdlog
cmake -DSPDLOG_FMT_EXTERNAL=ON -DFMT_DIR=/path/to/MY_PROJECT/fmt_precompiled .. && ninja
# 重新复制spdlog/build的生成文件到 MY_PROJECT/spdlog_precompiled

3. 修正项目CMakeLists.txt配置

# 先引入外部fmt
set(fmt_DIR ${CMAKE_SOURCE_DIR}/fmt_precompiled)
find_package(fmt REQUIRED)

# 引入预编译的spdlog
set(spdlog_DIR ${CMAKE_SOURCE_DIR}/spdlog_precompiled)
find_package(spdlog REQUIRED)

# 链接目标,同时关联fmt和spdlog
target_link_libraries(
  ${NAME}
  PRIVATE
  spdlog::spdlog
  fmt::fmt
  $<$<BOOL:${MINGW}>:ws2_32>
)

# 修正include路径配置,添加关键字
target_include_directories(${NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)

额外说明

如果项目中#include "spdlog/fmt/fmt.h"是为了使用fmt的API,更推荐直接#include <fmt/core.h>——启用外部fmt后,spdlog的转发头文件仅用于兼容旧代码,直接使用fmt原生头文件更规范。

内容的提问来源于stack exchange,提问作者Paweł Kłeczek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 14:12:07