conanfile.py 中的 requires 仅声明直接依赖,间接依赖由 conan 自动推导并解析,不应手动重复添加,否则易引发版本冲突或重复链接;其真实引入路径可通过 conan graph info 查看,版本归一化行为体现在 conan.lock 的 overrides 中。

conanfile.py 中的 requires 只声明直接依赖
你在 conanfile.py 的 requires 属性里写的每一项,比如 fmt/10.2.1 或 spdlog/1.13.0,都是直接依赖——即你项目代码里明确用到、且在配方中主动声明的库。Conan 不会因为你写了它,就自动把它的依赖也当成你的直接依赖;那些是间接依赖,由 Conan 在解析依赖图时自动推导出来。
常见错误现象:有人在 requires 里重复写某个库的子依赖(比如 fmt 用了 zlib,于是手动加一行 zlib/1.3.1),结果导致版本冲突或重复链接。其实只要 fmt 的配方本身声明了对 zlib 的 requires,Conan 就会把它作为间接依赖拉进来,无需你干预。
-
requires是“我主动要”的清单,不是“最终用到的所有库”清单 - 间接依赖不会出现在你的
conanfile.py里,但会体现在conan.lock文件的graph节点中 - 如果某间接依赖行为异常(比如符号未定义),别急着改
requires,先查它是否被其他直接依赖以不同版本/选项引入,造成冲突
conan install 输出里的 “Requirement” 和 “Provided” 区分很关键
执行 conan install . --build=missing 时,终端输出会列出所有解析出的依赖项。注意看每行开头的标记:
- Requirement 开头的,是直接依赖(你写的)或其传递链上的中间依赖(即间接依赖)
- Provided 开头的,表示该包已被另一个依赖“提供”过,当前这次引入是冗余的,Conan 会跳过或复用已有的二进制
例如你看到:
Requirement zlib/1.3.1 from 'conancenter' - Cache Requirement fmt/10.2.1 from 'conancenter' - Cache Requirement spdlog/1.13.0 from 'conancenter' - Cache Requirement zlib/1.3.1 from 'fmt/10.2.1' - Provided
最后一行说明:虽然 spdlog 或 fmt 都依赖 zlib,但 zlib/1.3.1 已经被前面某一项满足了,后面就不重复下载构建。
这个提示能帮你快速识别哪些是真正新增的间接依赖,哪些只是“路过”。如果某间接依赖反复出现多个版本(比如 zlib/1.2.11 和 zlib/1.3.1 同时存在),大概率是直接依赖之间存在版本策略不一致,需要统一约束。
用 conan graph info 查间接依赖的真实路径
当不确定某个库为什么被拉进来,或者想确认它是被谁带进来的,运行:
conan graph info . --format=json | jq '.graph.nodes[] | select(.ref | contains("zlib"))'
(需安装 jq;若无,可去掉 | jq ... 直接看原始 JSON)
返回结果里重点关注 required_by 字段,它列出所有“要求它”的上游节点。如果只有一个,比如 fmt/10.2.1,那它就是纯粹的间接依赖;如果有多个(如 fmt/10.2.1 和 openssl/3.2.1),说明它被多个直接依赖共同需要,这时它的构建选项(shared、fPIC 等)必须兼容所有上游,否则会触发重建或失败。
- 间接依赖的
options和settings实际由它所有上游依赖的交集决定,不是你单独能控制的 - 想强制统一某间接依赖的行为?得在直接依赖上用
override=True或通过conf全局约束,而不是在requires里重写它 -
conan graph info比看conan.lock更直观,尤其适合调试多层嵌套场景
间接依赖版本冲突时,conan.lock 里的 overrides 是实际生效点
当你两个直接依赖分别要求 zlib/1.2.11 和 zlib/1.3.1,Conan 默认会选择一个(通常是更高版本),并在 conan.lock 的 overrides 区域记录:
"overrides": {
"zlib/1.2.11": "zlib/1.3.1"
}
这意味着所有原本要 zlib/1.2.11 的地方,都被静默替换为 zlib/1.3.1。这不是“升级”,而是版本归一化——但可能引发 ABI 不兼容问题。
- 这个覆盖行为发生在 lock 文件生成阶段,不是
conan install运行时才决定的 - 如果你发现某间接依赖行为异常,第一反应不该是删 lock 文件重试,而是检查
overrides是否做了你不期望的合并 - 想禁用自动 override?用
--lockfile-preserve或显式在conanfile.py中写tool_requires+python_requires控制解析逻辑
真正容易被忽略的是:间接依赖的编译选项(比如 zlib:shared=True)可能被某个直接依赖强制设为 False,而你在 conanfile.py 里根本看不到这行配置——它藏在上游配方的 default_options 或 configure() 里。调试时得顺着 required_by 一层层查,不能只盯自己写的文件。











