Python 如何在Unix/Linux系统中静态构建lxml?

Python 如何在Unix/Linux系统中静态构建lxml?,python,unix,build,lxml,Python,Unix,Build,Lxml,我现在有两个unix系统,一个用于服务,一个用于构建(拥有所有要构建的环境,但它很旧)。我需要在python服务机器中使用lxml。我尝试了以下命令: python setup.py build --static-deps 或 但结果是: ld: fatal: relocations remain against allocatable but non-writable sections collect2: ld returned 1 exit status error: command '/

我现在有两个unix系统,一个用于服务,一个用于构建(拥有所有要构建的环境,但它很旧)。我需要在python服务机器中使用lxml。我尝试了以下命令:

python setup.py build --static-deps

但结果是:

ld: fatal: relocations remain against allocatable but non-writable sections
collect2: ld returned 1 exit status
error: command '/usr/lib/python2.6/pycc' failed with exit status 1
我想知道如何进行静态构建,以便能够轻松地部署到我的服务箱中

另外,如果我

python setup.py build
它没有错误,但如果我:

Python 2.6.4 (r264:75706, Apr 17 2011, 11:24:50) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: ld.so.1: isapython2.6: fatal: relocation error: file /usr/lib/python2.6/site-packages/lxml/etree.so: symbol __xmlStructuredErrorContext: referenced symbol not found
Python 2.6.4(r264:757061011年4月17日11:24:50)[C]在sunos5上
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>从lxml导入etree
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ImportError:ld.so.1:isapython2.6:致命:重新定位错误:文件/usr/lib/python2.6/site-packages/lxml/etree.so:symbol\uu xmlStructuredErrorContext:未找到引用的符号
我已经搜索过了: 似乎没有一个好的答案。我认为这是链接问题,所以我认为静态链接应该是一个更好的解决方案

但我的主要目标是减少部署的工作量,所以我会接受任何简单的方法


请帮忙。提前感谢。

问题似乎是您试图构建一个没有静态依赖项的静态库

静态库,如
libxml2.A
,只是对象(
.o
文件)的存档。当您针对该对象进行链接时,链接器会将您从这些对象中调用的任何函数的代码复制到链接目标中。因此,结果将是一个独立的目标,不需要运行
libxml2.a
;当您从
libxml2
调用函数时,一切正常,因为代码在您的库中

共享库(如
libxml2.so
)基本上是一个可执行文件。当您针对此链接时,链接器会创建重定位条目,这样,当您的目标和
libxml2.so
同时加载到内存中时,您从
libxml2
中调用的任何函数都会起作用,因为代码位于
libxml2.so

这里要做的实际上是构建一个混合库:一个共享库(因此可以作为模块加载),它可能会动态链接到
libpython.so
(也可能是内置到操作系统中的其他东西),但它会在代码中静态链接到
libxml2
(和
libxslt2

现代的链接器在这方面绝对没有问题,但它需要
libxml2
的静态libs来完成这项工作

因此,您需要先安装
libxml2.a
(和
libxslt2.a
,甚至可能安装
libz.a
),然后才能构建所需的内容


我这里有点过于简单化了。在某些平台上,
。因此
文件实际上只是实际共享对象的前端,基本上是重定位表加上到实际文件的链接。在其他平台上,代码可以从
中提取出来,因此
文件可以“重新定位”,而
.a
文件可以是与共享对象类似的前端。还有一些平台与ELF如此不同,以至于这个术语与其说是有用的,不如说是误导

如果您想了解更多信息,请从和其他相关问题开始

如果你没有,只要相信你需要
.a
文件来静态链接任何东西就行了


如果您阅读文档,您会注意到:

在Linux(以及大多数其他性能良好的操作系统)上,
pip
将能够构建源代码分发,只要
libxml2
libxslt
安装正确,包括开发包,即头文件,等等。如果生成失败,请使用包管理工具查找
libxml2 dev
libxslt-devel
之类的包,并确保已安装它们或者,设置
STATIC\u DEPS=true
将自动下载并构建这两个库。

因此,如果您根本没有这些库,构建
lxml
将下载依赖项,为您构建
.a
文件,并针对它们进行链接

但是如果您确实拥有它们,那么(a)
pkg-config
和/或
xml2-config
将找到它们并使用它们,并且(b)即使没有,
lxml
也可能最终生成
-lxml2
,而不是指向
libxml2.a
的绝对路径,并链接到错误的路径

你怎么能逃避呢?嗯,你可能认为会有一个简单的标志告诉它不要这样做,但据我所知,没有。因此,您的选择包括:

  • 使用不包含
    libxml2
    libxslt2
    的伪根生成。这在文档中有粗略的暗示
  • 手动仅构建静态的
    libxml2
    libxslt2
    ,并将生成的
    xml2 config
    xslt2 config
    的绝对路径传递给
    setup.py
    ,如中所述
  • 临时破解
    xml2-config
    xslt2-config
    (或者,如果您没有这些文件,则破解
    pkg-config
    使用的
    .pc
    文件),以使用
    LDFLAGS
    .a
    文件的绝对路径,而不是
    -L
    标志
  • 在构建
    lxml
    时,暂时将
    .so
    文件从库路径中完全移除(通过重命名、设置其他路径或其他方式)
  • 假设版本号与
    的版本号不同(或可能不同)。因此,您可以按照指定的显式版本号进行欺骗。您可能需要手动下载tarball才能工作,但不必构建它们
如果这一切看起来像是一种痛苦,像是一些应该很容易的事情……好吧,记住你在这里试图做什么。Linux是围绕i
Python 2.6.4 (r264:75706, Apr 17 2011, 11:24:50) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: ld.so.1: isapython2.6: fatal: relocation error: file /usr/lib/python2.6/site-packages/lxml/etree.so: symbol __xmlStructuredErrorContext: referenced symbol not found