简体   繁体   English

编译 maturin 包的正确方法是什么?

[英]What's the correct way to compile maturin packages?

I'm developing a Rust library that has Python bindings using PyO3 which are build using maturin.我正在开发一个 Rust 库,该库使用 PyO3 进行 Python 绑定,这些绑定是使用 maturin 构建的。

The problem问题

If I build the bindings on my os (Arch, with Glibc 2.31) then the generated.whl don't work on older systems because the Glibc is not compatible and raises an error such as:如果我在我的操作系统(Arch,使用 Glibc 2.31)上构建绑定,则 generated.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)

The current workaround当前的解决方法

In order to solve this issue we are building our bindings on a centos 6.9 which has Glibc 2.12, therefore "should be compatible" with nearly all Linux distro.为了解决这个问题,我们正在centos 6.9上构建我们的绑定,它具有 Glibc 2.12,因此“应该兼容”几乎所有 Linux 发行版。

The actual question实际问题

This is clearly just a workaround and there should be a better solution.这显然只是一种解决方法,应该有更好的解决方案。

What's the correct way to compile maturin libraries in such a way that they works on most of Linux distributions?编译 maturin 库以使其适用于大多数 Linux 发行版的正确方法是什么?

From my understanding this is what the manylinux standard is for, then why doesn't it works?据我了解,这就是manylinux 标准的用途,那为什么它不起作用呢? What am I missing?我错过了什么?

My hypothesis & Tests我的假设和测试

I guess that a possible solution would be to statically link the Glibc into the library, and therefore targeting musl which is meant for static compilation.我想一个可能的解决方案是将 Glibc 静态链接到库中,因此针对用于static编译的 musl。

Is it possible to do this?是否有可能做到这一点? I've found this blog which suggests that it can be done but I see that inside of the.whl files (which are just python installable archives) there is a .so , therefore a shared library.我发现 这个博客表明它可以完成,但我看到在 .whl 文件(只是 python 可安装档案)内部有一个.so ,因此是一个共享库。

Would it be even possible to build a shared library that has statically linked the libc using musl?甚至可以构建一个使用 musl 静态链接 libc 的共享库吗?

I found a possible working example of this: Inside of the tensorflow who tf_nightly-2.4.0.dev20200710-cp36-cp36m-manylinux2010_x86_64 , there is the file /tensorflow/python/_pywrap_utils.so that:我找到了一个可能的工作示例:在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

But it seems to dynamically link anyway:但它似乎无论如何都是动态链接的:

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)```

So is this actually possible?那么这真的可能吗?

Some people , strongly advise against doing this, why is that? 有些人,强烈建议不要这样做,这是为什么呢? I get that different implementation of threads and allocators in the same executable could lead to compatibility issues.我得到在同一个可执行文件中线程和分配器的不同实现可能会导致兼容性问题。

I've tried to change in the Cargo.toml from我试图改变Cargo.toml

[lib]
crate-type = ["cdylib"]

to this ( as seen here )对此(如此处所示

[lib]
crate-type = ["staticlib"]

but maturin don't seem to be happy about that.但马图林似乎对此并不高兴。

💥 maturin failed
  Caused by: Cargo didn't build a cdylib. Did you miss crate-type = ["cdylib"] in the lib section of your Cargo.toml?

Maybe this could be done with the compilation flag crt-static ?也许这可以通过编译标志crt-static来完成?

Apparently, the supposed way to do this is to compile the library inside of the official manylinux1 docker.显然,这样做的假定方法是编译官方manylinux1 docker 内部的库。

Which can be done with:可以通过以下方式完成:

sudo docker run --rm -v $(pwd):/io konstin2/maturin build --release

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM