在Windows上为Python 2.7构建lxml

35 投票
4 回答
64193 浏览
提问于 2025-04-16 00:00

我正在尝试在64位的Windows机器上为Python 2.7构建lxml库。但是我找不到适合Python 2.7的lxml安装包。所以我决定从源代码编译它。我在这个网站上按照说明进行操作:

http://lxml.de/build.html

在静态链接的部分。我遇到了一个错误:

C:\Documents and Settings\Administrator\Desktop\lxmlpackage\lxml-2.2.6\lxml-2.2.
6>python setup.py bdist_wininst --static
Building lxml version 2.2.6.
NOTE: Trying to build without Cython, pre-generated 'src/lxml/lxml.etree.c' need
s to be available.
ERROR: 'xslt-config' is not recognized as an internal or external command,
operable program or batch file.

** make sure the development packages of libxml2 and libxslt are installed **

Using build configuration of libxslt
Building against libxml2/libxslt in one of the following directories:
  ..\libxml2-2.7.6--win32--w2k--x64\lib
  ..\libxslt-1.1.26--win32--w2k--x64--0002\lib
  ..\zlib-1.2.4--win32--w2k--x64
  ..\iconv-1.9.1--win32--w2k--x64-0001\lib
running bdist_wininst
running build
running build_py
running build_ext
building 'lxml.etree' extension
error: Unable to find vcvarsall.bat

有没有人能帮我解决这个问题?我尝试设置路径来使用Microsoft Visual Studio。我可以从命令行运行vcvarsall.bat,但在使用Python时遇到了问题。

4 个回答

3

Jorj McKie 的说法差不多是对的:确实,单单安装 VCForPython27.msi 不够,而且确实在 distutils 里有个问题,导致它找不到 find_vcvarsall。实际上,这个问题并不是直接出在 distutils 上,而是出在 VCForPython27.msi 的打包方式和 vcvarsall.bat 的位置(文件夹的结构和 VS2008 SDK 不一样)。

在这个问题修复之前,可能在 Python 2.7.11 版本中,可以用一个简单的替代方法:使用 setuptools 来代替 distutils。

如果你还是想用 distutils,这里有另一个手动的解决办法:

1) Enter MSVC for Python command prompt
2) SET DISTUTILS_USE_SDK=1
3) SET MSSdk=1
4) you can then build your C extensions: python.exe setup.py ...

这是 Gregory Szorc 提出的错误报告和解决方法:http://bugs.python.org/issue23246

更多信息以及在 IPython 中使用 %%cython 魔法的解决办法: https://github.com/cython/cython/wiki/CythonExtensionsOnWindows

3

按照推荐的解决方案,我做了以下几步:

  1. 从微软下载了VCForPython27.msi
  2. 安装了它(我的系统是Win7,Python版本是2.7.9 32位),
  3. 把环境变量VS90COMNTOOLS更新为安装目录的值(C:\Program Files (x86)\Common Files\Microsoft\Visual C++ for Python\9.0)

但是我的问题还是没有解决(我想用C语言构建一个Python扩展)。

在一切正常之前,我不得不做以下两个非常麻烦的调整:

  1. 修改"msvc9compiler.py"文件,这个文件在"C:\Python27\Lib\distutils"目录下,把find_vcvarsall函数的指向改为"Visual C++ for Python",而不是指向"VC"
  2. "C:\Program Files (x86)\Common Files\Microsoft\Visual C++ for Python\9.0\"下的文件夹复制到"C:\Program Files (x86)\Common Files\Microsoft\Visual C++ for Python\"(也就是上移一个文件夹层级)。

我也不知道到底是谁做错了,可能是我。

补充说明:移动文件夹之所以有效,是因为有一个关于这个问题的distutils bug

即使设置了VS90COMNTOOLS,msvc9compiler也无法找到vcvarsall.bat,因为它安装在%installdir%/vcvarsall.bat,而不是%installdir%/VC/vcvarsall.bat

解决这个问题的临时办法是使用Visual C++命令提示符:

  1. 进入MSVC for Python命令提示符

  2. 输入SET DISTUTILS_USE_SDK=1

  3. 输入SET MSSdk=1

  4. 输入python.exe setup.py ...

61

我敢打赌你不是在用 VS 2008 来做这个 :)

在 distutils 里有一个叫 def find_vcvarsall(version): 的函数(猜猜看,它是用来找 vcvarsall.bat 文件的),里面有这样的注释:

一开始它会在注册表里查找 VS 2008 的 productdir。 如果找不到,就会退回去 查找 VS90COMNTOOLS 环境变量。

如果你没有使用 VS 2008,那你就没有注册表的键值,也没有合适的环境变量,这就是为什么 distutils 找不到 vcvarsall.bat 文件的原因。它不会检查这个 bat 文件是否可以通过 PATH 环境变量找到。

解决办法是定义 VS90COMNTOOLS 变量,让它指向 Visual Studio 的工具目录。

说到这里,可以看看 Python 文档中的 11.4. distutils.msvccompiler — Microsoft Compiler 部分,里面提到:

通常,扩展模块需要 使用与编译 Python 相同的编译器 来编译。

Martin v. Loewis 在 python-list 邮件列表中一封标题为 Download Visual Studio Express 2008 now 的邮件中也提到过类似的内容:

Python 2.6、2.7 和 3.1 都是用 这个版本(也就是 2008)构建的。 由于另一个悠久的传统,Python 扩展模块必须使用与 Python 本身相同的编译器版本(更 具体地说,是 CRT 版本)来构建。 所以,要为这些版本构建扩展模块, 你需要有 VS 2008 或 VS 2008 Express 的副本。

根据以上的说法,如果你想为 Python 2.7 构建 lxml,你应该使用 VS 2008,因此虽然设置 VS90COMNTOOLS 可以帮助找到 vcvarsall.bat 文件,但这并不是唯一的解决方案。

话虽如此 :) 有些人确实尝试用旧的 CRT 和新的编译器一起使用:
我可以用 Visual Studio 2010 的 C++ 编译器和 Visual Studio 2008 的 C++ 运行库吗?
如何强制 C++ 编译器使用特定的 CRT 版本?
VS 2008 - 链接到旧的 C 运行时

我想感谢 Kev Dwyer(指出使用的 VS 版本的重要性)和 Stefan Behnel(告诉我 distutils 是处理编译器配置的地方),在 lxml 邮件列表的讨论中 在 Windows 下构建 lxml 时出现问题 - 错误:无法找到 vcvarsall.bat。我还想感谢来自 freenode #distutils IRC 频道的 agronholm,确认 distutils 确实包含查找 vcvarsall.bat 文件的代码。

撰写回答