conan install 必须在 conanfile 所在目录执行,否则无法找到配置文件;CMakeLists.txt 必须 include Conan 生成的 toolchain 文件;package_info() 中需正确设置 includedirs;target_include_directories 必须作用于具体 target。

conan install 必须在 conanfile 所在目录执行
很多人执行 conan install 后,CMake 里 find_package() 能成功、头文件却始终找不到,根本原因常是命令跑错了位置。Conan 不会自动向上查找 conanfile.txt 或 conanfile.py ——它只认当前工作目录下是否存在该文件。
常见错误场景:
- 把
conanfile.py放在deps/子目录,却在项目根目录运行conan install deps/→ 报错No conanfile.py or conanfile.txt found - 用 CMake 的 out-of-source 构建习惯,在
build/目录下运行conan install ..→ Conan 不解析路径,直接失败
正确做法:先 cd 进 conanfile 所在目录(通常和 CMakeLists.txt 同级),再执行 conan install . --build=missing。
CMakeLists.txt 中必须 include Conan 生成的配置文件
Conan 本身不改写 CMake 变量;它靠生成的配置文件(如 conan_toolchain.cmake 或旧版 conanbuildinfo.cmake)把头文件路径注入 CONAN_INCLUDE_DIRS 等变量。如果你没 include 它,CMake 就完全不知道这些路径存在。
关键点:
- Conan 2.x 推荐用
CMakeToolchain+CMakeDeps生成器,对应 CMake 3.23+:conan install . -g CMakeToolchain -g CMakeDeps - 生成的文件默认在当前目录(不是
build/),但 CMake 配置阶段是在build/下运行的,所以CMakeLists.txt里要写:include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake) - 如果仍用旧版
cmake_find_package,生成的是conanbuildinfo.cmake,需配conan_basic_setup()或手动include并设置target_include_directories(... PRIVATE ${CONAN_INCLUDE_DIRS})
package_info() 中 includedirs 没设对,头文件路径就为空
即使 Conan 成功安装了包,CMake 也加载了配置文件,CONAN_INCLUDE_DIRS 仍可能为空——问题出在包自身的 package_info() 方法里。
典型错误写法(在包的 conanfile.py 中):
- 漏掉
self.cpp_info.includedirs = ["include"],或写成self.cpp_info.includedirs = [] - 头文件实际拷到了
include/mylib/,但includedirs只写了["include"],没加self.cpp_info.set_property("cmake_target_name", "mylib::mylib")导致find_package(mylib CONFIG)找不到 target - 用了 components 拆分,但没为 component 显式设置
self.cpp_info.components["core"].includedirs = ["include"]
验证方法:安装后运行 conan info . --graph=deps.dot,打开 deps.dot 查看该包的 includedirs 字段是否非空;或直接进缓存路径 ~/.conan/data/<pkg>/<ver>/package/<hash>/</hash></ver></pkg> 看是否存在 include/ 目录且有头文件。
target_include_directories 没传给具体 target,include 就只是摆设
CMake 的 include_directories() 是全局作用域,而 target_include_directories() 是 target 级别。如果你只在顶层写了 include_directories(${CONAN_INCLUDE_DIRS}),但没把它传给你的 add_executable() 或 add_library() target,那编译时依然找不到头文件。
务必用现代写法:
add_executable(myapp main.cpp)-
target_include_directories(myapp PRIVATE ${CONAN_INCLUDE_DIRS})(PRIVATE 表示仅 myapp 编译时可见) - 若该库会被其他 target 链接,用
PUBLIC,否则下游无法继承头文件路径
注意:Conan 2.x 的 CMakeDeps 生成器会自动帮你生成 find_package(mylib CONFIG) 对应的 target,此时你只需 target_link_libraries(myapp PRIVATE mylib::mylib),它已隐含了头文件路径——前提是 mylib 的 package_info() 正确设置了 includedirs 和 libs。
最易被忽略的一点:Conan 包的 package() 方法负责把头文件拷到 include/,而 package_info() 负责告诉下游“头文件在哪儿”;两者缺一不可。很多人只调通了前者,却忘了后者,结果 CMake 看得见包、看不见头文件。


















