如何处理Linux / Python的依赖关系?

由于缺乏对一些我想使用的库的支持,我将一些Python开发从Windows移植到了Linux开发中。 我花了大半天的时间搞乱依赖关系。

这个问题

每当我拿起Linux时,通常会遇到某种依赖性问题,通常是使用开发库,无论它们是通过apt-get,easy_install还是pip安装的。 我可以浪费时间在简单的任务上,花更多的时间在图书馆工作,而不是写代码。 我在哪里可以学习处理这些问题的策略,而不是漫无目的地用Googlesearch一个遇到同样问题的人呢?


一个例子

只是一个例子:我想要生成一些QR码。 所以,我想我会使用基于pyqrcode.sourceforge.net github.com/bitly/pyqrencode,但据说没有Java的依赖。 还有其他的( pyqrnative , github.com/ Arachnid / pyqrencode ),但是这似乎是我需要的最好的select。

所以,我在pypi上find了这个软件包,并且认为使用这个软件包会让生活更轻松:

(通过使用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之前的某个时间点。)

所以我试图运行testing脚本:

 (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安装的库sudo apt-get install libjpeg62 libjpeg62-dev libpng12-dev zlib1g zlib1g-dev早些时候sudo apt-get install libjpeg62 libjpeg62-dev libpng12-dev zlib1g zlib1g-dev 。 我不知道如何告诉点将图书馆的位置喂给setup.py。 谷歌searchbuild议我尝试了各种各样的想法 ,但没有一个似乎帮助不仅仅是把我圈出来。

Ubuntu 11.04:使用PIP将PIL安装到virtualenv中build议使用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 

尽pipe如此,仍然没有ImageOps。 现在我被困住了,ImageOps是从枕头中失踪的,还是与pil同样存在的另一个问题。

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

  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]下的入口点) ,这将创建一个bin / qrproject,运行模块qrprojectmodule中的函数run ,所以我也将创建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 / qrprojectbin / python 。 前者是你的项目的主要二元组。 它会在每次运行buildout时自动创建,并且会包含所有需要加载的模块和蛋。 第二个简单的方法是获得一个python提示符,在那里你所有的模块和蛋都被加载了,方便调试。 这里的好处是,bin / buildout会自动安装任何python的鸡蛋(在你的情况pyqrencode)指定为依赖关系。

实际上,在运行bin / buildout的步骤中,您可能会遇到编译错误。 这是因为您需要解决问题2:系统上的所有动态库都可用。 在Linux上,通常最好从包装系统获得帮助。 我将假设你在这里使用Debian衍生产品,如Ubuntu。

pyqrencode网站指定你需要pyqrencode的libqrencode库来工作。 所以我用我的包管理器来搜索:

 $ 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模块的打包版本。 例如,pil可以在Ubuntu上安装python-imaging软件包。 在这种情况下,您不需要通过构建来安装它,而且您也不必担心库可用 – 程序包管理器将安装模块运行所需的所有依赖关系。 通过构建可以使分发项目更容易,并使其在其他系统上运行。

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

你的一般问题没有普遍的解决办法; 你所能做的最好的就是利用工作或其他的工作。 Debian软件包在标记软件包的依赖方面做得非常好,所以apt-get会引入你所需要的东西。 所以,我的策略是简单地避免自己构建和安装东西,并尽可能使用apt-get。

请注意,Ubuntu基于Debian,因此可以从Debian软件包的工作中获益。 我没有使用过Fedora,但是我听说这个软件包没有Debian那么好。