conan create 不自动感知 conanfile.py 中 version 字段变更,需手动修改并确保本地无同版本缓存、远程允许覆盖或使用新版本号;推荐通过 Git 标签、文件或环境变量动态生成 version,避免硬编码。

conan create 时版本号写死在 conanfile.py 里,改了就得重跑
Conan 不会自动感知 conanfile.py 中 version 字段的变更并触发新包上传。你手动改了 version = "1.2.3" 后直接 conan create .,它确实会生成新版本包,但前提是:本地缓存里没有同名同版本的包(否则跳过构建),且远程仓库没被强制覆盖限制。
常见错误现象是:改完版本号运行 conan create,终端输出 Package already exists 或静默跳过 build 步骤——其实是因为 conan create 默认只检查“配方+设置+选项”组合是否已存在二进制,而版本号变更后,这个组合天然不同,理应重建。但如果之前用过 --build=never 或缓存残留了旧构建痕迹,就可能误判。
- 确保每次升级都清掉上一次的 build 目录(比如
build/或cmake-build-debug) - 显式加
--build=missing或--build=always,避免复用旧构建产物 - 如果用
conan export-pkg打已有二进制,必须同步更新conanfile.py的version,否则导出的包元数据版本和文件实际内容不一致
用 Python 表达式动态生成 version,别硬编码
把 version 写成静态字符串,每次发版都要手动改,容易漏、易错、难自动化。更稳妥的做法是让它从外部来源读取:
支持的常见方式包括:
- 从 Git 标签读:
version = tools.Version(self.version or git.get_tag())(Conan 2.x 推荐用tools.files.load(self, ".version")或git.run("describe --tags")) - 从文件读:
version = tools.files.load(self, "VERSION").strip() - 从环境变量注入:
version = os.getenv("CONAN_VERSION", "0.0.0"),CI 流水线里设CONAN_VERSION=1.2.4即可
注意:conan create 运行时会执行整个 conanfile.py,所以只要表达式能求值成功,self.version 就会被正确识别。但别在 version 字段里调用耗时操作(如网络请求),否则本地开发体验差。
远程仓库拒绝覆盖同名同版本包,这是保护机制不是 bug
大多数 Conan 远程(Artifactory、ConanCenter、自建 server)默认禁止覆盖已存在的 name/version@user/channel。你改了代码、没改版本号就重 conan create + conan upload,会卡在 upload 阶段报错:
ERROR: Recipe 'mylib/1.2.3@user/stable' already exists. Please use --force to overwrite.
这不是 Conan 客户端的问题,是服务端策略。强行加 --force 有风险:下游用户可能已拉取旧包,突然被覆盖会导致构建不一致或二进制污染。
- 真正做版本升级,就应该走新版本号(哪怕只是 patch 级)
- 如果只是修复 recipe 逻辑(比如
package()漏拷头文件),但二进制完全一样,建议用revision机制(Conan 2.x 默认开启),而不是 bump 版本号 - 确认远程是否启用
revisions:conan remote show <remote_name></remote_name>看输出里有没有revisions_enabled: True
升级后旧版本包要不要删?一般不删
Conan 缓存和远程仓库都支持多版本共存。conan remove mylib/1.2.2@user/stable 是可以执行的,但没必要主动清理旧版——除非磁盘空间告急,或旧版存在严重安全漏洞且你明确知道没人依赖它。
真正该关注的是:下游项目里的 conanfile.txt 或 conanfile.py 是否锁定了旧版本。例如写了 mylib/1.2.2 而不是 mylib/[>=1.2.3],那即使你上传了 1.2.3,他们也不会自动升级。
所以版本升级的关键动作不在打包侧,而在消费侧的依赖声明方式:
- 用版本范围(
mylib/[>=1.2.3,)替代固定版本 - 配合
conan lock生成conan.lock文件,让 CI 和团队共享确定性依赖图 - 定期运行
conan install --update检查可升级项,而不是等 break 了才想起看版本
版本号本身只是个标识符,真正的升级成本藏在 ABI 兼容性、头文件变更、构建依赖调整这些地方——这些没法靠工具自动发现,得靠人 review package_id() 实现和 changelog。


















