conan install 必须在包含 conanfile.txt 或 conanfile.py 的目录执行;若文件在 src/,则需先 cd src 再运行命令,不可在项目根目录或 build 目录直接执行,否则报 ConanException。

conan install 命令该在哪个目录执行
必须在包含 conanfile.txt 或 conanfile.py 的目录下运行 conan install,不是项目根目录(除非你把 conanfile 放那儿),也不是 build/ 目录。常见错误是把 conanfile.txt 放在 src/ 里,却在项目顶层执行命令,结果报错:ConanException: No conanfile.py or conanfile.txt found。
如果你沿用传统 Makefile 工程结构,建议把 conanfile.txt 和 Makefile 放在同一级目录(通常是项目根目录),这样 conan install . --build=missing 就能直接生效。
- 不推荐把 conanfile 放进子目录再用
conan install ./src—— 容易导致路径解析错乱,尤其当生成器要写入build/时 - 如果用
conanfile.py,它默认会读取当前目录的源码,所以self.source_folder默认就是.;若源码在src/,需显式设置self.folders.source = "src" -
conan install不会自动创建 build 目录,得自己mkdir build && cd build再运行,否则生成的 toolchain 文件可能污染源码树
CMakeToolchain 与 CMakeDeps 怎么配进老项目
传统 C++ 工程如果已用 CMake,迁移 Conan 最关键的是替换掉手写的 find_package() 和 include_directories()。Conan 2.x 推荐用 CMakeToolchain + CMakeDeps 生成器,而不是旧版的 cmake_find_package。
示例:在 conanfile.txt 中写:
立即学习“C++免费学习笔记(深入)”;
[requires] fmt/10.2.1 [generators] CMakeToolchain CMakeDeps
然后在 CMakeLists.txt 开头加:
cmake_minimum_required(VERSION 3.15)
project(MyApp LANGUAGES CXX)
<h1>必须先加载 toolchain,它覆盖编译器、标准、架构等基础设置</h1><p>include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake)</p><h1>再 find_package,此时依赖已由 CMakeDeps 注册</h1><p>find_package(fmt REQUIRED CONFIG)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE fmt::fmt)- 顺序不能反:toolchain 必须在
project()之后、任何find_package()之前include - 如果项目还用了
set(CMAKE_CXX_STANDARD ...),得删掉——它会被conan_toolchain.cmake覆盖,否则冲突 - 老项目常手动写
target_include_directories(main PRIVATE ${CMAKE_SOURCE_DIR}/third_party/...),这些全得删,让 Conan 管理头文件路径
Makefile 工程怎么接入 Conan 依赖
Conan 本身不生成 Makefile,但可以导出变量供 Makefile 使用。最轻量的方式是用 VirtualBuildEnv 和 VirtualRunEnv 生成 shell 脚本,再在 Makefile 中 include 或 source。
步骤:
- 在
conanfile.txt中添加:[generators] VirtualBuildEnv VirtualRunEnv
- 运行:
conan install . --output-folder=build --build=missing - 生成的
build/conanbuildenv.sh包含所有编译所需环境变量(PATH,LD_LIBRARY_PATH,PKG_CONFIG_PATH等) - 在 Makefile 里加一句:
include build/conanbuildenv.mk
(注意:Conan 生成的是 .sh,需用conan install --generator=MakeEnvironment才出 .mk;否则得自己写 wrapper)
更稳妥的做法是:保留 Makefile 控制构建流程,但把依赖编译和链接逻辑交给 Conan。例如,用 conan install 下载好库后,在 Makefile 中直接引用 build/conan_deps/ 下的头文件和 .a/.so 路径——但这要求你知道 Conan 缓存布局,且易受版本升级影响。
为什么 conan create 打包后下游找不到头文件
这是迁移自研库到 Conan 时最高频的失败点。根本原因不是代码问题,而是 package() 方法没按 Conan 约定路径拷贝内容。
Conan 包结构是强约定的:
- 头文件必须进
include/(不是headers/或src/) - 静态库进
lib/,动态库进bin/(Windows)或lib/(Linux/macOS) - 若用
CMakeDeps,还得提供xxx-config.cmake或确保find_package(xxx)能通过CONFIG模式找到模块
典型修复:
def package(self):
self.copy("*.h", dst="include", src="include")
self.copy("*.a", dst="lib", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)漏掉 dst="include" 或写成 dst="headers",下游 find_package() 就会静默失败——CMake 找不到 xxxTargets.cmake,也不会报错,只是头文件路径没加进去,编译直接 fatal error: xxx.h: No such file。
迁移老工程时最容易忽略的是:Conan 不信任你本地的 /usr/include 或 third_party/ 路径。一切依赖必须显式声明、显式打包、显式暴露。这个“显式性”是它可靠的前提,也是初期上手最硌手的地方。


















