default_options仅作用于当前包,不传递给依赖;须通过requires()、configure()或命令行显式设置依赖选项,且嵌套依赖需逐层透传。

conanfile.py 中的 default_options 只控制本包行为,不传递给依赖
很多人误以为在 default_options 里写 "zlib:shared": True 就能强制 zlib 以 shared 方式构建——其实它只对当前包生效,对 requires 列表里的依赖完全无效。Conan 的选项传递是显式、分层的,必须通过 requires 或 configure() 显式声明。
修改依赖选项的三种可靠方式
实际项目中,最常用且推荐的方式有以下几种,按优先级排序:
-
方式一(推荐):在
requires()方法中直接指定
适合单个依赖、临时调整或条件化控制:def requirements(self): self.requires("zlib/1.2.13", options={"shared": True}) self.requires("openssl/3.0.10", options={"fips": False, "no_asm": True}) -
方式二:用
configure()统一设置,避免重复
适合多个依赖共用同一组选项,或需根据self.settings动态判断:def configure(self): if self.settings.os == "Windows": self.options["zlib"].shared = True self.options["openssl"].shared = True -
方式三:命令行覆盖(调试用)
不建议写死在 recipe 中,但可用于 CI 或本地验证:conan install . -o zlib:shared=True -o openssl:fips=False
容易踩的坑:嵌套依赖的选项不会自动继承
假设 A → B → C,你在 A 的 requires 中设置了 B/1.0 并传了 options={"use_foo": True},但 B 自己没把该选项透传给 C,那 C 的行为依然按 B 的 default_options 或其 configure() 决定。这意味着:
- 你无法靠“上游设一次”就控制整条链路;
- 若 B 的配方没暴露
use_foo作为自己的options,你传了也无效; - 查看依赖选项是否可被设置,用
conan inspect B/1.0看输出里的options字段。
Conan 1.x 和 2.x 在选项语法上基本一致,但注意 configure() 的调用时机
Conan 2.x 中 configure() 是标准生命周期方法,会被自动调用;Conan 1.x 虽也支持,但部分旧版 recipe 可能遗漏该方法导致选项未生效。如果你发现 self.options["xxx"].yyy = zzz 没起作用,先确认:conan --version 输出是否 ≥ 2.0,再检查目标依赖的配方是否定义了对应 option 名称——拼错、大小写不匹配、或该包根本没声明这个 option,都会静默失败。











