conan中shared选项控制库链接类型:shared=true生成动态库,shared=false(默认)生成静态库;该选项在conanfile.py中声明,可通过命令行、profile或default_options指定,不同值产生不同二进制id,且需注意依赖传递一致性以避免链接错误。

conan中shared选项决定库的链接类型
Conan 不强制所有依赖统一为静态或动态,而是靠每个依赖包自己的 shared 选项控制。这个选项在 conanfile.py 的 options 字段里声明,下游项目通过 conan install 时传参或 profile 指定其值,最终影响编译出的库是 .a/.lib 还是 .so/.dll。
-
shared=True:生成动态库,链接时用-lxxx(Linux/macOS)或导入库(Windows),运行时需确保LD_LIBRARY_PATH或PATH包含对应路径 -
shared=False(默认):生成静态库,目标可执行文件体积增大,但无运行时依赖 - 不是所有包都支持
shared;比如某些仅头文件库(fmt,range-v3)压根没这个选项,调用conan install -o shared=True会报错option 'shared' doesn't exist - 同一包不同
shared值会产生完全不同的二进制 ID,Conan 会分别缓存——zlib/1.2.13@#abc(static)和zlib/1.2.13@#def(shared)互不干扰
如何在项目中指定 shared=True/False
有三种常用方式,优先级从高到低:命令行 > profile > conanfile.py 默认值。实际构建中建议固定一种,避免 CI 中因环境差异导致链接失败。
- 命令行直接指定:
conan install . -o zlib:shared=True -o openssl:shared=False(注意是zlib:shared,不是zlib/shared) - 写进 profile 文件(如
profiles/embedded):[options] zlib:shared=True openssl:shared=False
再运行conan install . --profile=embedded - 在
conanfile.py中硬编码(不推荐用于多配置项目):default_options = {"zlib:shared": True, "openssl:shared": False}
链接静态库时容易漏掉的依赖传递问题
当把某个依赖设为 shared=False,它所依赖的下层库(比如 openssl 依赖 zlib)并不会自动跟着变静态。如果 openssl 是静态链接,但 zlib 是动态的,conan install 仍可能成功,而 cmake build 阶段出现 undefined reference to inflate 这类符号缺失错误。
- 检查完整依赖树是否一致:
conan graph info . --build-order=missing看输出里各节点的shared值 - 更稳妥的做法是全局统一:
conan install . -o "*:shared=False"(星号通配所有依赖) - 某些包(如
protobuf)静态链接时还要求fPIC=True,否则 Linux 下报relocation R_X86_64_32 against ... can not be used when making a shared object;得一并加上-o protobuf:fPIC=True
CMake 中如何确认链接的是静态还是动态库
Conan 生成的 conanbuildinfo.cmake 或 conan_toolchain.cmake 会根据 shared 选项设置 CONAN_LIBS_XXX 和 CONAN_PKG_LIBS_XXX 变量,但 CMake 本身不校验你最终链接的是哪个。真正起作用的是 Conan 在 package_info() 里写的 self.cpp_info.libs 和 self.cpp_info.system_libs。
- 查看生成的库文件类型:
file ~/.conan/data/zlib/1.2.13/_/_/package/xxx/lib/libz.a(静态) vslibz.so(动态) - 在 CMakeLists.txt 中加一句验证:
message(STATUS "zlib libs: ${CONAN_LIBS_ZLIB}"),输出含z(静态)还是z.so(动态) - 若用
find_package(OpenSSL REQUIRED)+target_link_libraries(... OpenSSL::SSL),CMake 会自动选对libssl.a或libssl.so,前提是 Conan 提供的FindOpenSSL.cmake正确读取了shared状态
shared=False,而是混合模式下隐式依赖未对齐——比如你只改了 openssl,却忘了它底层用的 zlib 和 cares 也得同步设静态,否则链接器会在最后一步才报错,排查成本远高于一开始全量约束。











