V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
nowheremanx
V2EX  ›  Python

conda 中,如何兼容使用低版本 openssl 的.so 动态库?

  •  
  •   nowheremanx · 2 天前 · 688 次点击
    情况是这样的,正在写一个 python 的库叫作 mylib ,里面要用到一个 c/c++写的库,叫作 otherlib ,我只有编译好的.a 和.h 头文件。为了使用 otherlib 的功能,我写了个.c 文件,然后编译出 funcs.so 给 python 用,通过 ctypes 来交互。这个 otherlib 有点古老,需要低版本的 libcrypto.so ,不然有些 symbol 找不到( init 啥的函数)。我电脑里有已经编译好的 libcrypto.so.1.0.0 (在/opt/mypath/lib 下),所以编译的时候,要提供-L 和-Wl,rpath 这些参数给 gcc ,不然 funcs.so 的时候没办法找到这个版本的动态库。

    折腾了很久,把这些编译的过程都写在 setup.py 中,本地跑已经没问题,用户直接把包拷过去 pip install.也没问题。 问题出现在 conda package 打包。


    首先,我不能要求把 openssl 的依赖固定到低版本:虽然这个 otherlib 用了老版本的 libcrypto.so ( 1.0.0 或者 2.x.x ),但 mylib 中其他的依赖都已经用 3.x.x 。 其次,我设置的 rpath 参数不在 conda 的 build 环境中,一直给我报错,试了各种 whitelist 也没用。 这个库自带了 libressl ,我想着让 conda 直接编译了放到 env 里,但是 CONDA_PREFIX 这种东西指向的是 build 的环境,傻傻搞不清楚。

    说实话,搞不懂 conda build 到底是个什么概念,这些.so 文件的编译不应该是用户那里跑的吗,为什么在我打包的时候要跑一次,那赋值 rpath 就变得非常困难了。有一个 @ORIGIN 的符号,但是这个符号本身代表的是 python 这个程序?那难道我要把东西都编译到 @ORIGIN/../lib/mylib/?


    拓展一下,如果我要写一个 C++程序也用到这个 otherlib 库,但同时又有一个依赖需要高版本 libcrypto.so ,那我是不是就没办法编译了?


    这个问题可能是相当深入了,不知道有没有大神能讲清楚,谢谢!!!
    5 条回复    2025-02-07 17:04:35 +08:00
    lixile
        1
    lixile  
       2 天前
    funcs.so rpath 设置为 $ORIGIN 把你要的版本 libcrypto.sofuncs.so 放在同一路径下一起打包给 conda
    必要时 可改名你要的版本 libcrypto.so
    ospider
        2
    ospider  
       2 天前
    有个工具叫 auditwheel, 专门修改 python 打包进去的 so 文件符号名的
    nowheremanx
        3
    nowheremanx  
    OP
       1 天前
    差点因为这个技术问题想退出码农生涯了,折磨了 3 天,搞得胃酸倒流,腰酸背痛。 关键这些问题完全是浪费生命,我宁愿 CRUD 写写业务。

    然后反馈下最后解决方案吧。

    最后是另外做了一个 python 包,用户通过 pip 安装。然后 ctypes 载入.so 的动作一定要放在所有的 import 之前,不然总是会有 segmentation fault ,这个可能和 rpath 的设置有关,应该是其他库对于底层动态库的引用做了隐式改变。 这个坑我是这辈子都不想踩了,真恶心啊。
    pursuer
        4
    pursuer  
       1 天前
    c/c++的 ABI 和版本问题一直存在,所以微软搞了 COM 。同时依赖不同版本对于很多语言/平台都是比较麻烦的问题,只能指望开发人员做好兼容处理。

    “拓展一下,如果我要写一个 C++程序也用到这个 otherlib 库,但同时又有一个依赖需要高版本 libcrypto.so ,那我是不是就没办法编译了?”
    静态链接并做符号隔离(RTLD_LOCAL)可能可以解决,但如果可能,我觉得还是做成 RPC 的调用方式会简单一点。
    julyclyde
        5
    julyclyde  
       1 天前
    openssl 可以同时装多个版本的
    compat-openssl10
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2781 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 13:41 · PVG 21:41 · LAX 05:41 · JFK 08:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.