Подтвердить что ты не робот

Как работать с зависимостями Linux/Python?

Из-за отсутствия поддержки для некоторых библиотек, которые я хочу использовать, я переместил некоторые разработки Python из Windows в Linux. Я потратил большую часть дня на бесполезное общение с зависимостями.

Вопрос

Всякий раз, когда я беру Linux, я обычно сталкиваюсь с проблемой зависимости, обычно с библиотеками разработки, независимо от того, установлены ли они с помощью apt-get, easy_install или pip. Я могу тратить дни на то, что должно быть простым заданием, тратить больше времени на работу библиотек, чем написание кода. Где я могу узнать о стратегии решения таких проблем, а не бесцельно искать людей, которые сталкиваются с одной и той же проблемой раньше?


Пример

Только один пример: я хотел сгенерировать некоторые QR-коды. Итак, я думал, что буду использовать github.com/bitly/pyqrencode, который основан на pyqrcode.sourceforge.net, но, предположительно, без зависимостей Java. Есть и другие (pyqrnative, github.com/Arachnid/pyqrencode), но это казалось лучшим выбором для моих нужд.

Итак, я нашел пакет на pypi и подумал, что это облегчит жизнь:

(Я, возможно, сделал жизнь более трудной для себя, используя virtualenv, чтобы держать вещи аккуратными и аккуратными.)

(myenv3)[email protected]:~/myenv3$ bin/pip install pyqrencode
Downloading/unpacking pyqrencode
  Downloading pyqrencode-0.2.tar.gz
  Running setup.py egg_info for package pyqrencode

Installing collected packages: pyqrencode
  Running setup.py install for pyqrencode
    building 'qrencode' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c qrencode.c -o build/temp.linux-i686-2.7/qrencode.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions build/temp.linux-i686-2.7/qrencode.o -lqrencode -o build/lib.linux-i686-2.7/qrencode.so

Successfully installed pyqrencode
Cleaning up...

(я думаю, я, вероятно, sudo apt-get install libqrencode-dev в какой-то момент до этого тоже.)

Итак, я попытался запустить тест script:

(myenv3)[email protected]:~/myenv3$ python test_qr.py 
Traceback (most recent call last):
  File "test_qr.py", line 1, in <module>
    from qrencode import Encoder
  File "qrencode.pyx", line 1, in init qrencode (qrencode.c:1520)
ImportError: No module named ImageOps

: (

Хорошо, исследования показали, что ImageOps, похоже, является частью PIL...

(myenv3)[email protected]:~/myenv3$ pip install pil
Downloading/unpacking pil
  Downloading PIL-1.1.7.tar.gz (506Kb): 122Kb downloaded
Operation cancelled by user
Storing complete log in /home/mat/.pip/pip.log
(myenv3)[email protected]:~/myenv3$ bin/pip install pil
Downloading/unpacking pil
  Downloading PIL-1.1.7.tar.gz (506Kb): 506Kb downloaded
  Running setup.py egg_info for package pil
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py

Installing collected packages: pil
  Running setup.py install for pil
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    building '_imaging' extension
    gcc ...
    building '_imagingmath' extension
    gcc ...
    --------------------------------------------------------------------
    PIL 1.1.7 SETUP SUMMARY
    --------------------------------------------------------------------
    version       1.1.7
    platform      linux2 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
                  [GCC 4.5.2]
    --------------------------------------------------------------------
    *** TKINTER support not available
    *** JPEG support not available
    *** ZLIB (PNG/ZIP) support not available
    *** FREETYPE2 support not available
    *** LITTLECMS support not available
    --------------------------------------------------------------------
    To add a missing option, make sure you have the required
    library, and set the corresponding ROOT variable in the
    setup.py script.

    To check the build, run the selftest.py script.
    ...
Successfully installed pil
Cleaning up...

Hmm, PIL установлен, но не взял библиотеки, которые я установил с sudo apt-get install libjpeg62 libjpeg62-dev libpng12-dev zlib1g zlib1g-dev ранее. Я не уверен, как сообщить pip, чтобы прокормить места в библиотеке до setup.py. Googling предлагает множество идей, которые я пробовал, но никто из них, похоже, не помогает, кроме как отправить меня кругами.

Ubuntu 11.04: установка PIL в virtualenv с помощью PIP предлагает использовать pillow вместо этого, поэтому попробуйте следующее:

(myenv3)[email protected]:~/myenv3$ pip install pillow
Downloading/unpacking pillow
  Downloading Pillow-1.7.5.zip (637Kb): 637Kb downloaded
  Running setup.py egg_info for package pillow

    ...
Installing collected packages: pillow
  Running setup.py install for pillow
    building '_imaging' extension
    gcc ...
    --------------------------------------------------------------------
    SETUP SUMMARY (Pillow 1.7.5 / PIL 1.1.7)
    --------------------------------------------------------------------
    version       1.7.5
    platform      linux2 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
                  [GCC 4.5.2]
    --------------------------------------------------------------------
    *** TKINTER support not available
    --- JPEG support available
    --- ZLIB (PNG/ZIP) support available
    --- FREETYPE2 support available
    *** LITTLECMS support not available
    --------------------------------------------------------------------
    To add a missing option, make sure you have the required
    library, and set the corresponding ROOT variable in the
    setup.py script.

    To check the build, run the selftest.py script.
    ...
Successfully installed pillow
Cleaning up...

Ну, на этот раз у нас есть поддержка JPEG и PNG, yay!

(myenv3)[email protected]:~/myenv3$ python test_qr.py 
Traceback (most recent call last):
  File "test_qr.py", line 1, in <module>
    from qrencode import Encoder
  File "qrencode.pyx", line 1, in init qrencode (qrencode.c:1520)
ImportError: No module named ImageOps

Тем не менее, ImageOps. Теперь я в тупике, отсутствует ImageOps в подушке, или это другая проблема, которая также была с пилом.

4b9b3361

Ответ 1

Здесь я вижу две отдельные проблемы:

  • Отслеживание всех модулей python, необходимых для вашего проекта.

  • Отслеживание всех динамических библиотек, необходимых для модулей python в вашем проекте.

Для первой проблемы я обнаружил, что buildout - это хорошая помощь, хотя для захвата требуется litle.

В вашем случае я бы начал с создания каталога для моего нового проекта. Затем я зашел в этот каталог и загрузил bootstrap.py

wget http://python-distribute.org/bootstrap.py 

Тогда я бы создал файл buildout.cfg:

[buildout]
parts = qrproject
        python
eggs = pyqrencode

[qrproject]
recipe = z3c.recipe.scripts
eggs = ${buildout:eggs}
entry-points= qrproject=qrprojectmodule:run
extra-paths = ${buildout:directory}

# This is a simple way of creating an interpreter that will have
# access to all the eggs / modules that this project uses.
[python]
recipe = z3c.recipe.scripts
interpreter = python
eggs = ${buildout:eggs}
extra-paths = ${buildout:directory}

В этом buildout.cfg я ссылаюсь на модуль qrprojectmodule (в точках входа в [qrproject]. Это создаст bin/qrproject, который запускает функцию, запущенную в модуле qrprojectmodule. Поэтому я также создам файл qrprojectmodule.py

import qrencode

def run():
    print "Entry point for qrproject. Happily imports qrencode module"

Теперь пришло время запуска bootstrap.py с двоичным кодом python, который вы хотите использовать:

python bootstrap.py

Затем запустите созданный файл bin/buildout

bin/buildout

Это создаст два дополнительных бинарных файла в bin/directory - bin/qrproject и bin/python. Первый - это ваш основной проект. Он будет создан автоматически каждый раз, когда вы запустите buildout и будете иметь все модули и яйца, которые вы хотите загрузить. Во-вторых, это просто удобный способ получить приглашение python, где загружаются все ваши модули и яйца, для легкой отладки. Замечательно, что bin/buildout автоматически установит любые яйца python, которые яйца (в вашем случае pyqrencode) указаны как зависимости.

На самом деле, вы, вероятно, получите ошибку компиляции на шаге, где вы запускаете bin/buildout. Это связано с тем, что вам необходимо решить проблему 2: все динамические библиотеки доступны в вашей системе. В Linux обычно лучше всего получить помощь от вашей системы упаковки. Я предполагаю, что вы используете деривацию Debian, такую ​​как Ubuntu.

Веб-сайт pyqrencode указывает, что вам нужна библиотека libqrencode для работы pyqrencode. Поэтому я использовал диспетчер пакетов для поиска:

$ apt-cache search libqrencode
libqrencode-dev - QR Code encoding library -- development
libqrencode3 - QR Code encoding library
qrencode - QR Code encoder into PNG image

В этом случае я хочу пакет -dev, поскольку он устанавливает связанные библиотеки и файлы заголовков, необходимые для компиляции C-модулей python. Кроме того, система зависимостей в диспетчере пакетов гарантирует, что если я установлю libqrencode-dev, я также получу libqrencode3, как это требуется во время выполнения, т.е. После компиляции модуля.

Итак, я устанавливаю пакет:

sudo apt-get install libqrencode-dev

Как только это завершится, перезапустите bin/buildout и модуль pyqrencode (надеюсь) скомпилировать и установить. Теперь попробуйте запустить bin/qrproject

$ bin/qrproject 
Entry point for qrproject. Happily imports qrencode module

Успех!: -)

Итак, вкратце:

  • Используйте buildout для автоматической загрузки и установки всех модулей/яиц python, которые вам нужны для вашего проекта.

  • Используйте диспетчер системных пакетов для установки любых динамических (C) библиотек, необходимых для используемых вами модулей python.

Помните, что во многих случаях уже имеются упакованные версии ваших модулей python, доступных в системе пакетов. Например, файл pil можно установить, установив пакет изображений python на Ubuntu. В этом случае вам не нужно устанавливать его с помощью buildout, и вам не нужно беспокоиться о доступных библиотеках - диспетчер пакетов установит все зависимости, необходимые для запуска модуля. Однако выполнение этого с помощью buildout облегчает распространение вашего проекта и запуск его в других системах.

Ответ 2

Ваша история напоминает мне о моем раннем опыте работы с Linux, и почему я люблю APT.

Нет универсального решения вашей общей проблемы; лучшее, что вы можете сделать, это воспользоваться работой или другими. Пакеты Debian делают отличную работу по пометке зависимостей пакетов, поэтому apt-get будет тянуть то, что вам нужно. Итак, моя стратегия - просто не создавать и устанавливать вещи самостоятельно, а использовать apt-get везде, где это возможно.

Обратите внимание, что Ubuntu основан на Debian и, таким образом, получает выгоду от работы пакетов Debian. Я не использовал Fedora, но я слышал, что пакеты не так хорошо организованы, как у Debian.