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

CMake嵌套目标中源文件可引用fmt头文件但头文件不可用问题排查

问题分析:头文件引用fmt/core.h编译失败的原因

项目结构

.
└── library/
    ├── CMakeLists.txt
    ├── include/
    │   └── class1.hpp
    ├── src/
    │   └── class1.cpp
    ├── build/
    │   ├── _deps/
    │   │   └── fmt-build
    │   └── sample/
    │       └── app_using_library.exe
    └── sample/
        ├── CMakeLists.txt
        └── main.cpp

相关CMake配置

library的CMakeLists.txt

project(library)

include(FetchContent)

FetchContent_Declare(
        fmt
        URL https://github.com/fmtlib/fmt/releases/download/9.1.0/fmt-9.1.0.zip
)
FetchContent_MakeAvailable(fmt)

add_library(library STATIC 
  "src/class1.cpp" 
  "include/class1.hpp" 
)
target_include_directories(library PUBLIC include)
target_link_libraries(library PRIVATE fmt::fmt)

(注:原配置中add_library语句缺少闭合括号,属于语法错误,但并非导致当前问题的核心原因)

sample的CMakeLists.txt

project(app_using_library)
add_executable(app_using_library main.cpp)
target_link_libraries(app_using_library PRIVATE library)

问题现象

  • class1.hpp中包含#include "fmt/core.h",单独编译library目标时可正常通过,但编译依赖library的app_using_library时,编译器提示无法找到fmt/core.h。
  • class1.cpp中同样的#include "fmt/core.h"语句始终正常工作。
  • 完整错误日志:
FAILED: sample/CMakeFiles/app_using_library.dir/main.cpp.obj 
C:\msys64\mingw64\bin\g++.exe  -ID:/Programming/cpp/library/include -g -std=gnu++20 -MD -MT sample/CMakeFiles/app_using_library.dir/main.cpp.obj -MF sample\CMakeFiles\app_using_library.dir\main.cpp.obj.d -o sample/CMakeFiles/app_using_library.dir/main.cpp.obj -c D:/Programming/cpp/library/sample/main.cpp
In file included from D:/Programming/cpp/library/sample/main.cpp:2:
D:/Programming/cpp/library/include/class1.hpp:4:10: fatal error: fmt/core.h: No such file or directory
    4 | #include "fmt/core.h"
      |          ^~~~~~~~~~~~
compilation terminated.

原因解析

  1. 依赖传递性限制:library目标通过PRIVATE关键字链接fmt::fmt,这意味着fmt的依赖信息(包括头文件路径)仅作用于library自身的编译过程,不会传递给依赖library的其他目标(比如app_using_library)。
  2. 编译阶段差异:
    • 编译library的源文件(class1.cpp)时,CMake会自动将fmt的头文件路径加入编译器的include搜索列表,因此class1.cpp中的引用可以正常找到文件。
    • 编译app_using_library的main.cpp时,编译器仅能获取library通过PUBLIC声明的include目录(即library/include),但fmt的头文件路径因是PRIVATE依赖,不会被传递过来。而main.cpp包含了class1.hpp,此时需要找到fmt/core.h,但编译器搜索路径中无对应目录,因此报错。
  3. 单独编译与联合编译的区别:单独编译library时,仅处理自身编译任务,PRIVATE依赖的头文件路径生效;联合编译时,app_using_library作为依赖方无法继承library的PRIVATE依赖,导致头文件查找失败。

内容的提问来源于stack exchange,提问作者LordMustang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:15:35