根本原因是package()方法未将头文件拷贝至约定的include/目录,conan包结构强制要求include/下含头文件,否则下游find_package()失效;需用self.copy("*.h", dst="include", src="...", keep_path=true)并验证缓存路径。

conan create 找不到头文件(xxx.h)的根本原因
不是代码写错了,也不是路径拼错了,而是 package() 方法没把头文件拷到约定位置。Conan 包结构是硬性约定:include/ 目录必须存在且含头文件,否则下游 find_package() 或 target_include_directories() 都会失效。
-
package()里漏了self.copy("*.h", dst="include", src="...")—— 最常见错误 -
src路径写错,比如源码在src/include/却写了src="include",实际应为src="src/include" - 用了
exports_sources = ["*.h"]但没在package()中显式拷贝——exports_sources只影响源码分发,不参与二进制包构建 - 头文件在子目录(如
mylib/core/xxx.h),但只拷了"*.h",没加keep_path=True,导致层级丢失
package() 中拷头文件的正确写法
以项目根目录下 include/mylib/xxx.h 为例:
def package(self):
self.copy("*.h", dst="include", src="include", keep_path=True)
self.copy("*.hpp", dst="include", src="include", keep_path=True)
关键点:
-
dst="include"是强制要求,不能写成dst="headers"或省略 -
keep_path=True保留原始目录结构,让下游能用#include <mylib></mylib> - 如果头文件分散在多处(如
src/和include/),需调用多次self.copy() - 避免用
self.copy("*", dst="include", src=".", keep_path=True)—— 会混入无关文件,污染包体积
验证头文件是否真进了包
运行 conan create . user/channel 后,别急着用,先检查缓存里的实际内容:
- 查路径:
~/.conan2/p/b/<hash>/package/include/</hash>(Linux/macOS)或%USERPROFILE%\.conan2\p\b\<hash>\package\include\</hash>(Windows) - 确认该目录下有对应头文件,且路径层级与
#include语句匹配 - 用
conan info . --graph=graph.dot看依赖图,再打开graph.dot检查包 ID 和路径是否一致 - 如果用
conanfile.txt创建包(不推荐),它根本不支持package(),必须改用conanfile.py
CMakeLists.txt 中如何正确消费这些头文件
下游项目用 find_package(MyLib CONFIG REQUIRED) 后,CMakeDeps 生成的 MyLibConfig.cmake 会自动设置 INTERFACE_INCLUDE_DIRECTORIES。但你得确保:
- CMakeLists.txt 中
find_package()的名字和conanfile.py里name = "mylib"严格一致(大小写敏感) - 不要手动加
target_include_directories(... PRIVATE ${CONAN_INCLUDE_DIRS_MYLIB})—— 这是旧版conanbuildinfo.cmake的写法,CMakeDeps 下已废弃 - 如果 Intellisense 在 VS Code 里仍报错,检查
c_cpp_properties.json是否包含"${workspaceFolder}/build/generators",否则找不到自动生成的 config 文件
最易被忽略的一点:Conan v2 不再默认导出 include/ 下所有子目录,keep_path=True 必须显式写,否则 #include <mylib></mylib> 就永远找不到。











