conan通过--options按包名指定shared=true/false实现细粒度链接控制,支持每个依赖独立配置;包作者可在conanfile.py中用default_options强制约束下游行为,但需确保被依赖包实际声明并支持该选项,且abi(如crt、libstdc++、c++标准)保持一致。

conan install 时用 --options 显式指定 shared=True/False
Conan 默认不强制所有依赖统一链接方式,每个包可独立控制是否生成动态库。关键在于安装时传入 shared 选项:
conan install . --output-folder=build --build=missing --options="zlib:shared=True" --options="openssl:shared=False"注意这里不是全局开关,而是按包名加冒号写法;多个包就重复写多个
--options。漏掉某个包,它就会走自己 conanfile.py 里定义的 default_options(比如很多包默认 shared=False),结果可能和预期不一致。
在 conanfile.py 里用 requires + default_options 锁死下游行为
如果你是包作者(比如封装自己的库 A),又依赖了第三方库 B,想确保所有使用者都用 B 的动态版本,就不能只靠用户手动输 --options——容易漏、难复现。正确做法是在你的 conanfile.py 中显式约束:
一款AI工具,主要用于在主代理响应前,并行运行Kimi K2.5和GPT 5.3 Codex,注入双方观点以增强认知多样性,适合需要提升相关任务效率的用户。
class A(ConanFile):
name = "A"
requires = "zlib/1.2.13"
default_options = {
"zlib:shared": True,
"openssl:shared": False
}这样只要别人 conan install 你的包,zlib 就自动按动态链接构建,无需额外参数。但要注意:如果 zlib 本身不支持 shared=True(比如某些嵌入式变体禁用了动态构建),安装会直接失败,报错类似 ERROR: zlib/1.2.13: 'shared' is not a valid option。
为什么 shared=True 有时不生效?看包本身的 options 声明和 configure()
不是所有 Conan 包都真正实现了 shared 选项。常见原因有三个:
- 包作者没在
options字典里声明"shared": [True, False],选项根本不存在 - 包在
configure()方法里强行覆盖了self.options.shared = False(比如为兼容某平台禁用动态库) - 包的
package_id()没把shared加进 hash,导致不同shared值对应同一个二进制 ID,缓存被复用
conan inspect zlib/1.2.13 --raw options,看输出里有没有 shared 行;再查它的源码或 conancenter 页面,确认是否标明 “Shared library support: Yes”。
ABI 兼容性比“能不能编成 so”更关键
即使成功生成了 .so 或 .dll,如果依赖链里混用了不同 CRT(Windows)、不同 libstdc++ 版本(Linux)或不同 C++ 标准(compiler.cppstd=17 vs 20),运行时照样崩溃。Conan 的 shared=True 只管链接形态,不管 ABI 对齐。所以实际项目中,建议:
- 用
conan profile show default确认当前 profile 的compiler.libcxx、compiler.version等设置是否统一 - 避免在同一个 build 中混用
shared=True和shared=False的包,尤其当它们共用同一份头文件(如 OpenSSL 的ssl.h)时 - 交叉编译场景下,
shared选项必须和目标 sysroot 支持的动态链接能力匹配,否则conan create阶段就链接失败










