Как бороться с зависимостями Linux / Python? - PullRequest
13 голосов
/ 18 сентября 2011

Из-за отсутствия поддержки некоторых библиотек, которые я хочу использовать, я перевел некоторые разработки на 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)mat@ubuntu:~/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 в какой-то момент до этого тоже.)

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

(myenv3)mat@ubuntu:~/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)mat@ubuntu:~/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)mat@ubuntu:~/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...

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

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

(myenv3)mat@ubuntu:~/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, ууу!

(myenv3)mat@ubuntu:~/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 отсутствует в подушке, или это другая проблема, которая была также с Pil.

Ответы [ 2 ]

12 голосов
/ 18 сентября 2011

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

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

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

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

В вашем случае я бы начал с создания каталога для моего нового проекта. Затем я бы зашел в этот каталог и скачал 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, который запускает функцию run в модуле 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 / - 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

Успех! : -)

Итак, в итоге:

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

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

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

0 голосов
/ 18 сентября 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...