一尘不染

如何处理Linux / Python依赖项?

linux

由于缺乏对我想使用的某些库的支持,我将一些Python开发从Windows迁移到Linux开发。我整天的大部分时间都在搞弄依赖关系无所适从。

问题

每当我选择Linux时,无论是通过apt-get,easy_install还是pip进行安装,我通常都会遇到某种依赖问题,通常与开发库有关。我本可以将几天的时间浪费在应该是简单的任务上,而不是编写代码,而要花更长的时间使库工作。
在哪里可以了解解决此类问题的策略,而不是漫无目的地搜索曾经遇到过相同问题的人?


一个例子

仅举一个例子:我想生成一些QR码。所以,我想我会用github.com/bitly/pyqrencode这是基于pyqrcode.sourceforge.net但据说没有Java的依赖关系。还有其他(pyqrnativegithub.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。谷歌搜索提出了我尝试过的各种想法,但是除了让我转圈而论外,这些想法似乎无济于事。

Ubuntu11.04:建议使用PIP将PIL安装到virtualenv中,而不是使用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也存在其他问题。


阅读 300

收藏
2020-06-07

共1个答案

一尘不染

我在这里看到两个单独的问题:

  1. 跟踪项目所需的所有python模块。

  2. 跟踪项目中python模块所需的所有动态库。

对于第一个问题,我发现扩建是很好的帮助,尽管要花一点时间才能掌握。

在您的情况下,我将从为新项目创建目录开始。然后,我进入该目录并下载 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] 。这将创建一个斌/
qrproject运行该功能 运行 在模块 qrprojectmodule ,所以我也将创建文件 qrprojectmodule.py

import qrencode

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

现在该使用您要使用的python二进制文件运行 bootstrap.py 了:

python bootstrap.py

然后运行生成的 bin / buildout

bin/buildout

这将在 bin / 目录中创建另外两个二进制文件 -bin / qrprojectbin / python
。前者是项目的主要二进制文件。每次您运行buildout时,它都会自动创建,并包含您要加载的所有模块和鸡蛋。第二个简单的方法是获得python提示符的简便方法,该提示符会在其中装载所有模块和鸡蛋,以便于调试。很好的是,bin
/ buildout将自动安装已将鸡蛋(在您的情况下为pyqrencode)指定为依赖项的所有python鸡蛋。

实际上,在运行 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软件包,因为它安装了编译python C模块所需的可链接库和头文件。另外,程序包管理器中的依赖系统将确保,如果我安装
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. 使用系统的软件包管理器来安装您使用的python模块所需的任何动态(C)库。

请注意,在很多情况下,软件包系统中已经提供了python模块的打包版本。例如,可以通过在Ubuntu上安装 python-imaging
软件包来获得pil 。在这种情况下,您不需要通过buildout进行安装,也不必担心库是否可用-
程序包管理器将安装模块运行所需的所有依赖项。但是,通过构建完成它可以使分发项目并使它在其他系统上运行更加容易。

2020-06-07