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

发布于 2024-12-05 17:37:20 字数 6041 浏览 0 评论 0原文

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

问题

每当我选择 Linux 时,我通常会遇到某种依赖关系问题,通常是与开发库有关,无论它们是通过 apt-get、easy_install 还是 pip 安装的。我可能会在本应是简单的任务上浪费数天时间,花更多的时间让库工作而不是编写代码。 我可以在哪里了解处理此类问题的策略,而不是漫无目的地搜索以前遇到过同样问题的人?


一个例子

只是一个例子:我想生成一些二维码。所以,我想我会使用 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。 09/how-to-install-python-imaging-in-a-virtualenv-with-no-site-packages/" rel="nofollow noreferrer">想法 我尝试过,但没有一个除了让我兜圈子之外,似乎还有很多帮助。

Ubuntu 11.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 也存在另一个问题。

Due to lack of support for some libraries I want to use, I moved some Python development from Windows to Linux development. I've spent most of the day messing about getting nowhere with dependencies.

The question

Whenever I pick up Linux, I usually run into some kind of dependency issue, usually with development libraries, whether they're installed via apt-get, easy_install or pip. I can waste days on what should be simple tasks, spending longer on getting libraries to work than writing code. Where can I learn about strategy for dealing with these kind of issues rather than aimlessly googling for someone who's come across the same problem before?


An example

Just one example: I wanted to generate some QR codes. So, I thought I'd use github.com/bitly/pyqrencode which is based on pyqrcode.sourceforge.net but supposedly without the Java dependencies. There are others (pyqrnative, github.com/Arachnid/pyqrencode) but that one seemed like the best bet for my needs.

So, I found the package on pypi and thought using that would make life easier:

(I've perhaps made life more difficult for myself by using virtualenv to keep things neat and tidy.)

(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...

(I guess I probably sudo apt-get install libqrencode-dev at some point prior to that too.)

So then I tried to run the test script:

(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

:(

Well, investigations revealed that ImageOps appears to be part of 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...

Hmm, PIL's installed but hasn't picked up the libraries I installed with sudo apt-get install libjpeg62 libjpeg62-dev libpng12-dev zlib1g zlib1g-dev earlier. I'm not sure how to tell pip to feed the library locations to setup.py. Googling suggests a variety of ideas which I've tried, but none of them seem to help much other than to send me round in circles.

Ubuntu 11.04: Installing PIL into a virtualenv with PIP suggests using the pillow package instead, so let's try that:

(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...

Well, we seem to have the JPEG and PNG support this time, yay!

(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

Still no ImageOps though. Now I'm stumped, is ImageOps missing from pillow, or is it a different problem that was also there with pil.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

霓裳挽歌倾城醉 2024-12-12 17:37:20

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

  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 中我' m 引用模块qrprojectmodule(在[qrproject]下的入口点中。这将创建一个运行函数的bin/qrproject运行在所以我还将创建文件 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/前者是你的。项目的主要二进制文件。它会在您每次运行 buildout 时自动创建,并且会加载您想要加载的所有模块和 Eggs。第二种方法只是获取加载所有模块和 Eggs 的 Python 提示符,以便于调试。这里的好处是 bin/buildout 会自动安装 Eggs(在你的例子中为 pyqrencode)指定为依赖项的任何 python Eggs。

实际上,您可能会在运行 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 模块/eggs。

  2. 使用系统的包管理器安装您使用的 python 模块所需的任何动态 (C) 库。

请注意,在许多情况下,软件包系统中已经提供了 Python 模块的打包版本。例如,可以通过在 Ubuntu 上安装 python-imaging 包来使用 pil。在这种情况下,您不需要通过构建来安装它,也不需要担心库是否可用 - 包管理器将安装模块运行所需的所有依赖项。然而,通过构建可以更轻松地分发项目并使其在其他系统上运行。

I see two separate problems here:

  1. Keeping track of all the python modules you need for your project.

  2. Keeping track of all the dynamic libraries you need for the python modules in your project.

For the first problem, I have found that buildout is good help, althought it takes a litle while to grasp.

In your case, I would start by creating a directory for my new project. I would then go into that directory and download bootstrap.py

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

I would then create a buildout.cfg file:

[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}

In this buildout.cfg I'm referencing the module qrprojectmodule (in entry-points under [qrproject]. This will create a bin/qrproject that runs the function run in the module qrprojectmodule. So I will also create the file qrprojectmodule.py

import qrencode

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

Now it's time to run bootstrap.py with the python binary you want to use:

python bootstrap.py

Then run the generated bin/buildout

bin/buildout

This will create two additional binaries in the bin/ directory - bin/qrproject and bin/python. The former is your project's main binary. It will be created automatically each time you run buildout and will have all the modules and eggs you want loaded. The second is simply a convenient way to get a python prompt where all your modules and eggs are loaded, for easy debugging. The fine thing here is that bin/buildout will automatically install any python eggs that the eggs (in your case pyqrencode) have specified as dependencies.

Actually, you will probably get a compilation error in the step where you run bin/buildout. This is because you need to address problem 2: All dynamic libraries being available on your system. On Linux, it's usually best to get help from your packaging system. I'm going to assume you're using a Debian derivate such as Ubuntu here.

The pyqrencode web site specifies that you need the libqrencode library for pyqrencode to work. So I used my package manager to search for that:

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

In this case, I want the -dev package, as that installs linkable libraries and header files required to compile python C-modules. Also, the dependency system in the package manager will make sure that if I install libqrencode-dev, I will also get libqrencode3, as that is required at runtime, i.e. after compilation of the module.

So, I install the package:

sudo apt-get install libqrencode-dev

Once that has completed, rerun bin/buildout and the pyqrencode module will (hopefully) compile and install successfully. Now try to run bin/qrproject

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

Success! :-)

So, in summary:

  1. Use buildout to automatically download and install all the python modules/eggs you need for your project.

  2. Use your system's package manager to install any dynamic (C) libraries required by the python modules you use.

Be aware that in many cases there are already packaged versions of your python modules available in the package system. For example, pil is available by installing the python-imaging package on Ubuntu. In this case, you don't need to install it via buildout, and you don't need to worry about libraries being available - the package manager will install all dependencies required for the module to run. Doing it via buildout can however make it easier to distribute your project and make it run on other systems.

亣腦蒛氧 2024-12-12 17:37:20

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

对于您的一般问题,没有通用的解决方案;你能做的最好的事情就是利用工作或其他人的优势。 Debian 打包程序在标记软件包的依赖关系方面做得非常出色,因此 apt-get 将提取您需要的内容。因此,我的策略就是避免自己构建和安装东西,并尽可能使用 apt-get。

请注意,Ubuntu 基于 Debian,因此受益于 Debian 打包者的工作。我没有使用过 Fedora,但我听说这些软件包不像 Debian 中的软件包那样组织良好。

Your story reminds me of my early experiences with Linux, and why I love APT.

There is no universal solution to your general problem; the best you can do is to take advantage of the work or others. The Debian packagers do a great job of flagging the dependencies of packages, so apt-get will pull in what you need. So, my strategy is simply to avoid building and installing stuff on my own, and use apt-get wherever possible.

Note that Ubuntu is based on Debian and thus gains the benefit of the work of the Debian packagers. I haven't used Fedora but I hear that the packages are not as well-organized as the ones from Debian.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文