Как опубликовать бинарные колеса Python для Linux на локальной машине

У меня есть пакет, содержащий расширения C, которые я хотел бы загрузить в pypi: https://github.com/Erotemic/netharn

Я построил колесо на Ubuntu 18.04, используя команду python setup.py bdist_wheel --py-limited-api=cp36, но когда я пошел на загрузку с помощью twine upload --skip-existing dist/*, я получил ошибку, что у него есть неподдерживаемый тег платформы:

HTTPError: 400 Client Error: Binary wheel 'netharn-0.0.4-cp36-abi3-linux_x86_64.whl' has an unsupported platform tag 'linux_x86_64'. for url: https://upload.pypi.org/legacy/

После небольшого поиска я обнаружил, что PEP 513 требует создания колеса для поддержки manylinux (он же Centos5): https://github.com/pypa/manylinux

Они приводят пример здесь: https://github.com/pypa/python-manylinux-demo/blob/master/travis/build-wheels.sh

Однако все примеры, которые я могу найти, всегда собирают свои двоичные файлы с использованием какого-либо сервера CI. Если возможно, я хотел бы иметь возможность создавать их локально. Я подумал, что должно быть просто скопировать команды докера и создать их в контейнере докера на моей собственной машине. Однако у меня проблемы. (Я убедился, что все существующие каталоги build и dist в репозитории были удалены)

Первое, что я сделал, — погрузился в интерактивную сессию докера, чтобы поиграть с вещами. Я выбрал образ x8_64 и смонтировал локальный каталог в свой репозиторий кода на /io в докер-машине. Затем я начал интерактивную сессию bash.

REPO_DPATH=$HOME/code/netharn
DOCKER_IMAGE=quay.io/pypa/manylinux1_x86_64
PRE_CMD=""
# Interactive test
docker run -it --rm -v $REPO_DPATH:/io $DOCKER_IMAGE $PRE_CMD bash

Внутри докера я сначала хотел создать колесо для python36 (на самом деле это единственный Python, в поддержке которого я заинтересован в данный момент).

PYBIN=/opt/python/cp36-cp36m/bin/

Простая установка моего файла requirements.txt не сработала, поэтому я сначала вручную установил несколько пакетов. После этого (виновником был imgaug, потому что он опирается на конкретную основную сборку), установка requirements.txt, похоже, сработала.

    cd /io
    "${PYBIN}/pip" install opencv_python
    "${PYBIN}/pip" install Cython
    "${PYBIN}/pip" install pytest
    "${PYBIN}/pip" install -e git+https://github.com/aleju/imgaug.git@master#egg=imgaug
    "${PYBIN}/pip" install torch  # this is in the requirements.txt, but will cause problems later
    "${PYBIN}/pip" install -r requirements.txt

Затем я запускаю команду колеса и связываю внешние общие библиотеки в колеса.

"${PYBIN}/pip" wheel /io/ -w wheelhouse/
for whl in wheelhouse/*.whl; do
    auditwheel repair "$whl" -w /io/wheelhouse/
done

Последний шаг — установить пакет и протестировать

    "${PYBIN}/pip" install netharn --no-index -f /io/wheelhouse

    (cd "$HOME"; "${PYBIN}/python" -m xdoctest netharn all)

Однако, когда я должен проверить это, я получаю

ImportError: /opt/python/cp36-cp36m/lib/python3.6/site-packages/torch/_C.cpython-36m-x86_64-linux-gnu.so: ELF file OS ABI invalid

Я думаю, это потому, что torch не поддерживает Centos5. Чего я не понимаю, так это того, как torch удалось загрузить общую библиотеку cpython-36m-x86_64-linux-gnu.so в pypi, но у меня возникли проблемы?


person Erotemic    schedule 05.06.2018    source источник
comment
torch не загружал cpython-36m-x86_64-linux-gnu.so, они загрузили много бинарных дисков linux1_x86_64.   -  person phd    schedule 05.06.2018
comment
Почему у меня в пакетах сайта есть _C.cpython-36m-x86_64-linux-gnu.so, а когда я пробую pip install torch -U, он говорит Requirement already up-to-date: torch in /home/joncrall/venv3.6/lib/python3.6/site-packages (0.4.0)? Я не собирал факел из исходного кода на этой машине, так почему же pip дает мне двоичный файл cpython-36m-x86_64-linux-gnu.so?   -  person Erotemic    schedule 06.06.2018
comment
Потому что этот .so находится в файле manylinux1_x86_64.whl.   -  person phd    schedule 06.06.2018
comment
немного поздно, но torch в какой-то момент (может быть, все еще) загружал колеса, которые они вручную пометили как manylinux, несмотря на то, что они не были manylinux — вот как :)   -  person Anthony Sottile    schedule 11.02.2020


Ответы (1)


Решение, которое работает с оговорками, описанными ниже.

pip install auditwheel twine
apt install patchelf
python setup.py bdist_wheel
auditwheel repair [[lib]]-linux_x86_64.whl -w . --plat manylinux_2_24_x86_64
twine upload [[lib]]-manylinux_2_24_x86_64.whl

Контекст

У меня есть библиотека C с оболочкой python, которой я не владею напрямую (что затрудняет CI), с очень небольшой пользовательской базой (не нужна настоящая поддержка manylinux) и официальным двоичным файлом conda, который не включает оболочку (не не хочу создавать конкурирующий канал Conda).

Вышеприведенное решает мои конкретные потребности в Ubuntu 20.04, но, пожалуйста, прочитайте ниже перед использованием.

Предостережения

  • Если вы контролируете свое репо, вам действительно следует использовать CI. Если это настроено, то нет необходимости в загрузке командной строки.
  • Он не поддерживает старый/более широкий дистрибутив manylinux_1, так как Ubuntu 20.04 слишком нов для него. Это по-прежнему должно поддерживать большую часть дистрибутивов Linux, но может не работать на старом оборудовании (например, университетские кластеры HPC).
  • Вероятно, было бы лучше собирать непосредственно из контейнера докеров. Рабочий процесс сборки + ремонта уродлив. Я предполагаю, что это не более чем переименование файла с некоторой очисткой .so.
person PattimusPrime    schedule 29.04.2021