Как правильно скомпилировать пакеты maturin? - PullRequest
1 голос
/ 10 июля 2020

Я разрабатываю библиотеку Rust, которая имеет Python привязок с использованием PyO3, которые построены с использованием maturin.

Проблема

Если я создаю привязки в своей ОС (Arch, с Glib c 2.31), то сгенерированный .whl не работает в старых системах, потому что Glib c несовместим и вызывает ошибку, например:

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)

Текущее решение

Чтобы решить эту проблему, мы строим наши привязки на centos 6.9 , который имеет Glib c 2.12, поэтому «должен быть совместим» почти со всеми Linux дистрибутивами.

Фактический вопрос

Это явно обходной путь, и должно быть лучшее решение.

Как правильно скомпилировать библиотеки maturin таким образом, чтобы они работали на большинстве из Linux дистрибутивов?

Насколько я понимаю, это то, для чего предназначен many linux standard , тогда почему он не работает? Что мне не хватает?

Моя гипотеза и тесты

Я предполагаю, что возможным решением было бы статически связать Glib c с библиотекой и, следовательно, настроить таргетинг на musl который предназначен для компиляции stati c.

Можно ли это сделать? Я нашел этот блог , в котором говорится, что это можно сделать, но я вижу, что внутри файлов .whl (которые представляют собой просто python устанавливаемые архивы) есть .so, поэтому общая библиотека .

Можно ли было бы создать общую библиотеку, которая статически связала библиотеку c с помощью musl?

Я нашел возможный рабочий пример этого: Внутри тензорного потока, который 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, похоже, не доволен этим.

? 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?

1 Ответ

0 голосов
/ 11 июля 2020

По-видимому, предполагаемый способ сделать это - скомпилировать библиотеку внутри официального manylinux1 docker.

Что можно сделать с помощью:

sudo docker run --rm -v $(pwd):/io konstin2/maturin build --release
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...