conan的选项传递是单向且显式的,仅在conanfile.py中声明default_options不会自动生效到下游项目;必须在conan install时通过-o、profile或configure()方法显式传入,否则依赖仍使用conan默认值。

包选项必须在 conan install 阶段显式传入,仅在 conanfile.py 里声明 default_options 不会自动生效到下游项目。
为什么改了 default_options 却没用
Conan 的选项传递是“单向且显式”的:上游包(比如 A)定义了 shared=True,下游项目(B)即使不写任何选项,也不会继承这个值——它只会用 Conan 默认的 shared 值(通常是 False),除非你明确告诉它要怎么传。
常见错误现象:
- 修改了依赖包的
default_options = {"shared": True},但conan install后生成的库仍是静态链接 - 用
conan create打包时选项生效,但被其他项目requires时失效 - CI 构建结果和本地不一致,因为 CI 没传选项,而你本地用了 profile 或命令行参数
conan install 必须带 -o 或 --options
让选项落地的唯一可靠方式,是在执行 conan install 时直接指定。例如:
conan install . -o zlib:shared=True -o openssl:shared=False --build=missing
注意点:
-
-o pkg_name:option_name=value是标准语法,不能漏掉pkg_name:前缀 - 如果依赖链很深(比如
B → A → zlib),你得在B的 install 命令里直接控制zlib的选项,Conan 不会自动穿透多层继承 - 用
conan install --output-folder=build时,选项仍需加在同一条命令上,不能分两次 - 避免用
-o shared=True这种全局写法——它只作用于当前项目(conanfile.py自身),不传递给依赖
在 conanfile.py 里用 requires() + self.options[...] 控制传递
如果你希望下游项目能统一开关某个依赖的行为(比如所有依赖都用动态版),可以在自己的 conanfile.py 中做中转:
def requirements(self):
self.requires("zlib/1.2.13")
self.requires("openssl/1.1.1w")
<p>def configure(self):</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2808" title="Conan 2.31.2"><img
src="https://img.php.cn/upload/manual/001/431/639/6ab11b67ca9f7425.png" alt="Conan 2.31.2" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2808" title="Conan 2.31.2" class="overflowclass">Conan 2.31.2</a>
<p class="overflowclass">Conan 2.31.2 官方历史源码包,适合复现依赖解析、CMake 配置、二进制包兼容性和跨平台构建环境。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2808" title="Conan 2.31.2" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><h1>把当前项目的 shared 选项,透传给 zlib 和 openssl</h1><pre class="brush:php;toolbar:false;">if self.options.shared:
self.options["zlib"].shared = True
self.options["openssl"].shared = True
这样用户只需运行 conan install . -o shared=True,就能批量控制多个依赖的选项。
关键约束:
-
configure()必须在requirements()之后调用,否则self.options["zlib"]会报KeyError - 不能在
configure()里修改未声明的选项(比如self.options["zlib"].fPIC但 zlib 包本身没定义fPIC) - Conan 2.x 中
configure()已废弃,应改用layout()+tool_requires组合,但选项透传逻辑仍靠self.options["xxx"]赋值
Profile 文件里写死选项最稳定
对 CI 或团队统一构建场景,把选项固化在 profile 里比每次敲命令更可靠:
[options] zlib:shared=True openssl:shared=False mylib:enable_foo=True
然后用 conan install . -pr=myprofile --build=missing 即可复现。
注意:
- profile 文件路径必须用
-pr=显式指定,Conan 不会自动加载defaultprofile 的选项部分 - profile 中的
[options]优先级高于conanfile.py的default_options,但低于命令行-o - 别把敏感配置(如
compiler.version)和选项混在一个 profile 里——编译器设置属于[settings],选项属于[options],写错位置会导致静默忽略
真正容易被忽略的是:选项生效与否,和 conan create 无关,只取决于 conan install 时是否传入、以及是否正确作用于目标依赖名。哪怕 conanfile.py 里写了十遍 default_options,只要 install 命令没提它,它就只是个注释。










