Любопытный казус привел к исследованию совместимости процессора Apple M1, и оказалось, что не все так просто...

Впрочем, обо всем по порядку. Мой коллега, владелец MacBook Pro с M1 обратился ко мне с просьбой помочь с установкой библиотеки.

У меня почти такой же MacBook, но на Intel Core i5, macOS Big Sur. При попытке поставить библиотеку

pip install qvd

ERROR: Could not find a version that satisfies the requirement qvd (from versions: none)

ERROR: No matching distribution found for qvd

Обычно такое бывает, когда в составе пакета есть какой-то модуль, несовместимый с текущей ОС. В такой ситуации первое, что я делаю - пытаюсь установить библиотеку в docker container, там у меня очень широкий выбор возможных ОС и настроек.

Dockerfile:

FROM python:3.8-slim-buster

RUN apt-get update && apt-get install -y netcat

COPY . /app
WORKDIR /app

RUN pip install --upgrade pip
RUN pip install -r requirements.txt

CMD ["python", "main.py"]

requirements.txt:

qvd==0.0.10

main.py:

import qvd


if __name__ == '__main__':
  print('Hello, qvd')

Далее выполняем команду:

docker build -t testqvd:latest .

И оп-ля, все работает, библиотека встает, образ собирается, контейнер запускается:

docker run testqvd

Hello, qvd

Добавлю (не имеет отношения к данной теме), что библиотека работает по-настоящему, я подключал настоящие файлы и обрабатывал их этой библиотекой.

Отдаю проект коллеге, но у него не собирается!

docker -v

Docker version 20.10.7, build f0df350

У нас обоих версия docker совпадает. В чем может быть причина? Ведь выполнение кода из Dockerfile реально идет в образе python:3.8-slim-buster, он одинаковый у нас. Надо погружаться глубже, разбираться с pip

Для начала посмотрим, почему qvd не ставится на Big Sur:

pip install -vvv qvd

Эта команда выводит очень много текста, но главное, что понятно -  none of the wheel's tags (cp37-none-win_amd64) are compatible (run pip debug --verbose to show compatible tags), таких строчек очень много и среди них встречаются только win и manylinux.

Запустим

pip debug --verbose

и получим список подходящих тэгов pip. Никаких win там, конечно, нет, а есть py32-none-macosx_10_13_x86_64 (и похожие). Всех интересующихся, что это значит отсылаю сюда: https://github.com/pypa/manylinux

Тэги совместимости не совпадают, вероятно, по веским причинам - есть библиотеки, которые не смогут запуститься на Big Sur. ОК, понятно, нет вопросов, но есть вопросы, почему при сборке образа на одной и той же ОС из одного и того же источника есть такое существенное отличие.

Добавляю в Dockerfile строчку:

FROM python:3.8-slim-buster

RUN apt-get update && apt-get install -y netcat

COPY . /app
WORKDIR /app

RUN pip install --upgrade pip
RUN pip debug --verbose > /tmp/pip.txt
RUN pip install -r requirements.txt

CMD ["python", "main.py"]

и запускаю сборку вот такой командой:

docker build -t testqvd:latest -o /tmp/buildlogs

В результате получаю файл /tmp/buildlogs/tmp/pip.txt с результатами тэгов pip во время сборки. То же самое делает мой коллега. И они (тэги) получаются разными, у меня, например, - py38-none-manylinux_2_16_x86_64, у коллеги py37-none-manylinux_2_28_aarch64

Вот так, процессор M1 (очевидно) не совпадает с Intel Core и никакими хитрыми docker - технологиями исправить ничего нельзя. Я пока поостерегусь переходить на M1 и другим разработчикам отсоветую.

Комментарии (13)


  1. Berserkr
    04.11.2021 08:17
    +6

    Серьезно? И инвайт за это?


    1. Kromeshnaja
      04.11.2021 09:12
      +2

      Синдром вахтёра?


    1. funca
      04.11.2021 09:41
      +4

      Надо ещё влепить минусов статье и слить автору карму, чтобы всем показать как он неправ. Хабр это же теперь филиал дзен для лириков, а не технических тем.

      Ректор университета просмотрел смету, которую ему принес декан физфака, и, вздохнув, сказал: — Почему это физики всегда требуют такое дорогое оборудование? Вот, например, математики просят лишь деньги на бумагу, карандаши и ластики. И, подумав, добавил: — А философы, те ещё лучше. Им даже ластики не нужны.



  1. IRT
    04.11.2021 08:20
    +29

    Вы серьзно или шутите? Даже я, ни коим боком не относящийся к Python-разработке, и то в курсе, что эти ваши Wheel в питоне в основном служат для дистрибуции предкомпилированных бинарных библиотек под определенную архитектуру. И раз их не нашлось готовых под Darwin/ARM64, то их надо собрать под процессор M1 из исходников, разве нет? И никакой докер в вопросах кроссплатформенности вам не поможет, поскольку это не система виртуализации и программы в докере выполняются на реальном процессоре с соответствующей архитектурой. И в одном и том же контейнере под разными процессорами будет выполняться разный код.


    1. funca
      04.11.2021 09:28
      +4

      Вообще-то Docker Desktop для MacOS/m1 может запускать как наивные ARM так и x86 контейнеры. Нужно лишь установить Rosetta 2 и при запуске контейнера указать флажок --platform linux/amd64 в командной строке. Это штатная фича из коробки. Производительность так себе, ибо процессор эмулируется, но для разработки на локалхосте в большинстве случаев этого достаточно.

      Без флажка, по умолчанию, docker пытается собирать нативные контейнеры под ARM, что может приводить к таким вот казусам как в статье.


      1. vsb
        04.11.2021 11:02
        +1

        Кстати говоря можно и на x86 запускать ARM-контейнеры (по крайней мере в Linux).


      1. vanyas
        04.11.2021 11:10
        +4

        Вот именно, всё работает в x86 эмуляции, а не: "никакими хитрыми docker - технологиями исправить ничего нельзя"


    1. apro
      04.11.2021 11:56
      +3

      поможет, поскольку это не система виртуализации

      Насколько я знаю под macos в docker используется именно виртуализация, если точнее то https://developer.apple.com/documentation/hypervisor . Именно поэтому docker настолько медленнее под macos по сравнению с linux.


      1. symbix
        04.11.2021 13:11
        +1

        На маке через гипервизор запускается линуксовая "хостнода", а в ней уже контейнеры. К ней можно screen-ом подцепиться.

        Все тормоза от взаимодействия между "внешней" и "внутренней" хостнодой - в основном тупит I/O.


  1. nikita_dol
    04.11.2021 09:24
    +4

    Обычно, для запуска кода, который не хочет работать под m1, используют этот префикс:

    arch -x86_64 {command}


  1. 42p
    04.11.2021 10:25
    +10

    При наследовании образа укажите --platform=linux/amd64 (укажите свою)
    Например
    FROM --platform=linux/amd64 debian:buster-slim

    И пакеты будут находиться корректно. Потому что поиск пакетов учитывает то, что система запускается на arm и ищет пакеты под соотвествующую архитектуру. А их делают не всегда.


  1. qant
    04.11.2021 14:37
    +3

    Статья конечно так себе... но за то сколько дельных и полезных комментариев! Спасибо вам народ!


  1. grigoryvp
    05.11.2021 09:03
    +1

    Это "бинарный пакет", qvd · PyPI. Автор библиотеки собрал ее из Rust исходников на своем ноутбуке под несколько комбинаций операционка-проц-версия-пайтона. При этом сами исходники он не приложил. Получилась очень "калечная" версия библиотеки которая не будет работать в окружении, сильно отличающемся от окружения создавшего ее разработчика. Хорошим тоном считается делать версию с исходниками, которая бы собиралась на компьютере разработчика. Например, как это делают авторы подавляющего большинства библиотек с нативным кодом: Pillow · PyPI - обратите внимание на "source" дистрибьюцию в списке. Ну и зацените, насколько больше список предсобранных комбинаций.