如何处理Linux / Python依赖?

时间:2011-09-18 18:36:03

标签: python linux dependencies dependency-management

由于缺乏对我想要使用的某些库的支持,我将一些Python开发从Windows迁移到Linux开发。我一天中大部分时间都在忙着无处依赖。

问题

每当我拿起Linux时,我经常遇到某种依赖性问题,通常是开发库,无论是通过apt-get,easy_install还是pip安装。我可以浪费时间来完成简单的任务,花费更长的时间来使用库来编写代码。 我在哪里可以了解处理这类问题的策略,而不是漫无目的地搜索之前遇到同样问题的人?


示例

仅举一个例子:我想生成一些QR码。所以,我以为我会使用基于github.com/bitly/pyqrencode但基本上没有Java依赖关系的pyqrcode.sourceforge.net。还有其他人(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

:(

好吧,investigations透露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。谷歌搜索提出了我尝试过的各种ideas,但除了让我绕圈子外,它们似乎没有什么帮助。

Ubuntu 11.04: Installing PIL into a virtualenv with 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 个答案:

答案 0 :(得分:12)

我在这里看到两个不同的问题:

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

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

  3. 对于第一个问题,我发现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,它在模块 qrprojectmodule 中运行 run 函数。所以我还将创建文件 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 / qrproject bin / 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)库。

    3. 请注意,在许多情况下,软件包系统中已经提供了python模块的打包版本。例如,通过在Ubuntu上安装 python-imaging 包可以获得pil。在这种情况下,您不需要通过buildout安装它,并且您不必担心库可用 - 包管理器将安装模块运行所需的所有依赖项。但是,通过buildout执行此操作可以更轻松地分发项目并使其在其他系统上运行。

答案 1 :(得分:0)

你的故事让我想起了我早期使用Linux的经历,以及为什么我喜欢APT。

您的一般问题没有通用的解决方案;你能做的最好的事情就是利用这项工作或其他工作。 Debian打包器在标记包的依赖关系方面做得很好,因此apt-get将提供您需要的内容。因此,我的策略只是避免自己构建和安装内容,并尽可能使用apt-get。

请注意,Ubuntu基于Debian,从而获得了Debian打包器工作的好处。我没有使用Fedora,但我听说这些软件包的组织结构不如Debian那样。