conan install 必须在含 conanfile 的目录执行,ci 中常见错误是路径错位导致找不到 conanfile;需 cd 至项目根目录再运行,并显式指定 settings、使用 conan.lock 锁定依赖、避免不必要的源码编译。

conan install 必须在含 conanfile 的目录执行
CI 脚本里最常犯的错误是路径错位:把 conan install 放在 build/ 目录下运行,但 conanfile.txt 或 conanfile.py 实际在项目根目录。结果报错 ConanException: No conanfile.py or conanfile.txt found。
正确做法是先 cd 到声明依赖的那个目录——通常就是项目根目录(和 CMakeLists.txt 同级),再执行安装命令:
-
cd $PROJECT_ROOT(确保变量或路径准确) -
conan install . --build=missing -if build(-if build指定输出到build/目录,不污染源码) - 不要写成
conan install ../ --build=missing,相对路径易出错
CI 中必须显式指定 settings 且与编译器一致
本地开发时 conan profile detect 可能自动识别环境,但 CI 环境(如 GitHub Actions 的 ubuntu-latest)没有默认 profile 或 profile 不匹配,会导致下载错二进制包、链接失败甚至静默降级为源码编译。
务必在 conan install 中硬编码关键 -s 参数:
-
-s os=Linux(或Windows/Macos) -
-s compiler=gcc(或clang/msvc) -
-s compiler.version=11(必须和 CI 中gcc --version输出一致) -
-s compiler.libcxx=libstdc++11(GCC 5+ 必须显式设,否则可能用错 ABI) -
-s build_type=Release(和你 CMake 的CMAKE_BUILD_TYPE对齐)
漏掉 compiler.libcxx 是 Linux CI 最隐蔽的坑:链接时出现 undefined reference to `std::string::_M_create' 类错误,实际就是 libcxx 不匹配。
用 conan lock 确保构建可复现
不加 --lockfile 的 conan install 在 CI 中极不稳定:Conan Center 上的包版本更新、远程索引刷新、甚至网络抖动都可能导致某次构建拉到不同 patch 版本的依赖(比如 fmt/10.2.1 → fmt/10.2.2),引发行为差异或编译失败。
标准做法是两步走:
- 本地开发完成时运行:
conan lock create . --base --lockfile-out conan.lock(生成锁定文件) - CI 中运行:
conan install . --lockfile=conan.lock -if build --build=missing - 提交
conan.lock到 Git —— 它才是 CI 构建的“真相依据”
注意:conan.lock 文件内容包含完整依赖图哈希,每次 conan install 都会校验它;如果本地改了 conanfile 却没更新 lock 文件,CI 会直接失败,这反而是保护机制。
避免在 CI 中触发不必要的源码编译
CI 时间宝贵,应尽量复用 Conan Center 提供的预编译二进制。但以下情况会让 --build=missing 退化为全量编译:
- settings 组合太“冷门”:比如
compiler.version=13.3(新 GCC)还没被 Conan Center 收录 - 用了
-o *:shared=True但该包在远程只有静态库二进制 - 依赖本身声明了
build_policy="always"(极少见,但私有包可能这么配)
对策:
- CI 前先跑一次
conan remote list确认连的是https://center.conan.io(不是旧的conancenter) - 用
conan search "fmt/10.2.1" -r center手动查目标包是否存在对应二进制(CI 脚本中可加检查) - 若必须编译,把
--build=missing改为--build=zlib,openssl(只编译真正缺失的少数几个),避免全量拖慢流水线
最易被忽略的一点:CI 镜像里 Python 版本过低(如系统自带 Python 3.6)会导致 Conan 2.x 启动失败,必须在 CI 步骤开头明确装好 Python 3.8+ 和 pip。











