我正在开发一个使用PyO3进行Python绑定的Rust库,该库是使用maturin构建的。
问题所在
如果我在os (Arch,使用Glibc 2.31)上构建绑定,则生成的.whl不能在旧系统上工作,因为Glibc不兼容,并引发如下错误:
ImportError: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found
(required by /home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/my_package.cpython-37m-x86_64-linux-gnu.so)当前的解决办法
为了解决这个问题,我们正在一个具有Glibc2.12的centos 6.9上构建我们的绑定,因此“应该与几乎所有的Linux发行版兼容”。
实际问题
这显然只是一个解决办法,应该有一个更好的解决办法。
--在大多数Linux发行版上编译maturin库的正确方法是什么?
根据我的理解,这就是manylinux标准的用途,那么为什么它不起作用呢?我遗漏了什么?
我的假设与检验
我猜想,一个可能的解决方案是静态地将Glibc链接到库中,从而锁定用于静态编译的musl。
有可能这样做吗?我已经找到了这个博客,这表明可以这样做,但我看到在.whl文件(这只是一个可安装的python文件)中有一个.so,因此是一个共享库。
是否有可能构建一个使用musl静态链接libc的共享库?
我找到了一个可能的工作示例:在tensorflow who tf_nightly-2.4.0.dev20200710-cp36-cp36m-manylinux2010_x86_64中,有一个文件/tensorflow/python/_pywrap_utils.so:
file _pywrap_utils.so [2]
_pywrap_utils.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), statically linked, BuildID[md5/uuid]=aee3c5fa4ae1243775857b2643b80ea0, not stripped但无论如何,它似乎是动态链接的:
ldd _pywrap_utils.so
linux-vdso.so.1 (0x00007fffb3782000)
libtensorflow_framework.so.2 => not found
_pywrap_tensorflow_internal.so => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f5c95672000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f5c95658000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f5c95491000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f5c9534a000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f5c95a9f000)```这真的有可能吗?
有些人,强烈建议不要这么做,为什么?我知道,在同一个可执行文件中,线程和分配器的不同实现可能会导致兼容性问题。
我试图在Cargo.toml中更改
[lib]
crate-type = ["cdylib"]对此(如图所示)
[lib]
crate-type = ["staticlib"]但马图林似乎对此并不满意。
maturin failed
Caused by: Cargo didn't build a cdylib. Did you miss crate-type = ["cdylib"] in the lib section of your Cargo.toml?也许这可以用编译标志crt-static来完成?
发布于 2020-07-10 21:09:10
显然,做这件事的方法将在正式的manylinux1坞内编译库。
这可以通过以下方式来完成:
sudo docker run --rm -v $(pwd):/io konstin2/maturin build --releasehttps://stackoverflow.com/questions/62838212
复制相似问题