You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链接器选择共享库版本规则及Rocky Linux 8 Python依赖差异咨询

共享库版本选择与Python依赖差异问题解答

一、链接器如何决定要链接的共享库具体版本?

链接器对共享库版本的选择分为编译时和运行时两个阶段:

  • 编译阶段:
    当用gcc等编译器链接共享库时,通过-lxxx参数指定库名(比如-lcrypto),链接器会在系统库路径(如/lib64、/usr/lib64)中查找对应的库文件。它真正关注的是库的SONAME(共享库名称)——这是库开发者编译时通过-Wl,-soname,xxx参数设置的版本标识(比如libcrypto.so.1.1),而非文件名(可能是libcrypto.so这样的软链接)。链接器找到库后,会将其SONAME写入生成的可执行文件或共享库的依赖表中。
  • 运行阶段:
    动态链接器(ld.so)会读取可执行文件/共享库的依赖表,根据SONAME去系统中查找对应的库文件。系统中通常会有软链接链到具体版本的库(比如libcrypto.so -> libcrypto.so.1.1),确保运行时能找到正确版本。

二、Rocky Linux 8中Python依赖库差异的原因

首先需要明确:你看到的是两个完全不同的库,而非同一库的不同版本:

  • libcrypto.so.1.1:属于OpenSSL项目,是提供加密算法、TLS/SSL支持的核心库,Python的ssl模块依赖它。
  • libcrypt.so.1:属于glibc,是提供传统密码哈希功能(如crypt()函数)的系统库,Python的crypt模块依赖它。

两者的依赖差异来源如下:

  1. 系统默认Python(3.6):
    Rocky Linux 8的系统Python包由发行版维护者构建,在构建时明确将libcrypto.so.1.1设为直接依赖(确保ssl模块功能正常),因此ldd会直接显示该依赖。实际上它也依赖libcrypt.so.1,只是你截取的输出只包含了前者。

  2. 自行编译的Python 3.10:
    Python 3.10的构建系统调整了依赖处理方式:

    • 对于OpenSSL的libcrypto,改为间接依赖:Python的ssl模块通过动态加载libssl.so(而libssl.so本身依赖libcrypto.so.1.1)实现功能,因此libpython3.10.so的直接依赖表中不会出现libcrypto.so.1.1,只有查看ssl模块时才会看到该依赖。
    • 对于libcrypt.so.1,由于Python的crypt模块需要直接调用glibc的密码哈希函数,因此被设为直接依赖,ldd输出会直接显示它。

三、PyInstaller打包失败的解决方法

PyInstaller基于它运行时所使用的Python环境分析依赖。你用系统Python运行PyInstaller时,它会检测到系统Python的libcrypto.so.1.1依赖并打包,但实际运行的是你编译的Python(依赖libcrypt.so.1),导致加载失败。解决方式:

  • 使用你编译的Python环境运行PyInstaller:确保python3.10是当前环境的默认Python,再执行打包命令,它会正确分析并打包libcrypt.so.1。
  • 手动指定依赖:如果无法切换Python环境,可在PyInstaller的.spec文件中添加binaries参数,手动将libcrypt.so.1加入打包列表:
    binaries = [('/lib64/libcrypt.so.1', '.')]
    

内容的提问来源于stack exchange,提问作者IngoMeyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:35:23