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

cbjzeqam  于 5个月前  发布在  Unix
关注(0)|答案(2)|浏览(61)

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

python setup.py build --static-deps

字符串

CFLAGS="-g -O2 -fPIC"
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


它没有错误,但如果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


我搜索了一下:get errors when import lxml.etree to python似乎没有一个好的答案。我归咎于它的链接问题,所以我认为静态链接应该是一个更好的解决方案。
但我的主要目标是减少部署工作,所以我会接受任何简单的方法。
请帮忙,谢谢。

cidc1ykv

cidc1ykv1#

问题似乎是您试图构建一个没有静态依赖项的静态库。
静态库(如libxml2.a)只是对象的存档(.o文件)。当你链接到这个对象时,链接器会将你从这些对象中调用的任何函数的代码复制到你的链接目标中。所以,结果将是一个不需要libxml2.a运行的独立目标;当你从libxml2调用函数时,一切都正常,因为代码在你的库中。
一个共享库,比如libxml2.so,基本上是一个可执行文件。当你链接到这个库时,链接器会创建重定位条目,这样,当你的目标和libxml2.so同时加载到内存中时,你从libxml2调用的任何函数都可以工作,因为代码在libxml2.so中。
在这里,你要做的实际上是构建一个混合体:一个共享库(这样它就可以作为一个模块加载),它可能动态链接到libpython.so(也可能是其他内置在操作系统中的东西),但静态链接到libxml2(和libxslt2)的代码。
现代的链接器做这件事绝对没有问题,但是它需要libxml2的静态库来做这件事。
因此,在构建您想要的东西之前,您需要安装libxml2.a(和libxslt2.a,甚至可能是libz.a)。
我在这里稍微简化了一点。在某些平台上,.so文件实际上只是真实的共享对象的前端,基本上是重定位表加上一个指向真实的文件的链接。在其他平台上,代码可以从.so文件中取出并就地“重定位”,和.a文件可以只是类似的前端共享对象。有一些平台是如此不同于ELF,这个术语是所有的误导比有用。
如果您想了解更多信息,请从this question和其他链接和相关问题开始。
如果没有,请相信您需要.a文件来进行静态链接。
如果你阅读installation文档,你会注意到:
在Linux上(以及大多数其他表现良好的操作系统),只要正确安装了libxml2libxslt,包括开发包,即头文件等,pip将设法构建源代码发行版。如果构建失败,请使用包管理工具查找libxml2-devlibxslt-devel等包,并确保它们已安装。或者,设置STATIC_DEPS=true将自动下载并构建这两个库。
因此,如果您根本没有这些库,构建lxml将下载依赖项,为您构建.a文件,并链接到它们。
但是如果你有它们,那么(a)pkg-config和/或xml2-config会找到它们并使用它们,(b)即使没有,lxml最终也可能使用-lxml2而不是到libxml2.a的绝对路径来构建,并链接到错误的路径。
你怎么能绕过它呢?好吧,你会认为会有一个简单的标志,告诉它不要这样做,但据我所知,没有。所以,你的选择包括:

  • 使用不包含libxml2libxslt2的假根进行构建。这在构建Debian软件包文档中有粗略的暗示。
  • 手动构建静态libxml2libxslt2,并将生成的xml2-configxslt2-config的绝对路径传递给setup.py,如构建源代码中所述。
  • 临时破解xml2-configxslt2-config(或者,如果您没有这些文件,则使用pkg-config使用的.pc文件),以使用LDFLAGS.a文件的绝对路径,而不是-L-l标志。
  • 在构建lxml时,暂时将.so文件完全从库路径中删除(通过重命名、设置不同的路径或其他方式)。
  • 假设版本号与您安装的.so文件的版本号不同(或可能不同),您可以通过遵循Mac构建说明来指定显式版本号来作弊。您可能需要手动下载tarball才能工作,但您不必构建它们。

如果这一切看起来像是一种痛苦,并且像是应该很容易的事情.好吧,记住你在这里要做的事情。Linux是围绕着为你的特定系统构建最好的源代码发行版的想法而设计的。如果你的系统有xml 2和xslt 2的共享库,如果你想构建代码来部署到一个没有它们的系统上,你的开发系统也应该没有它们;如果是这样,你应该知道如何解决这个问题。

7qhs6swi

7qhs6swi2#

Using libxml for Android
用途:./configure --enable-static --disable-shared make libxml2.la

相关问题