2014-10-20 88 views
-1

我现在有两个unix系统,一个用于服务,另一个用于构建(具有所有要构建的环境,但它是旧的)。我需要在服务机器中使用python中的lxml。以下命令我想:如何在Unix/Linux系统中创建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 

它没有错误,但如果我:

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 似乎并不有一个很好的答案。我认为这是链接问题,所以我认为它静态链接应该是一个更好的解决方案。

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

请大家帮忙。提前致谢。

+0

首先,您是否拥有完全相同的Python版本并在两台机器上构建?其次,你是否有依赖关系的静态库('libxml2.a','libxslt.a','libz.a',或者它需要的东西)? – abarnert 2014-10-20 21:56:45

+0

我认为是蟒蛇版本。第二个问题是什么意思?我有这些库的.so库,否则,'python setup.py build'不会通过,对吧?根据doc,'python setup.py build --static-deps'将会下载最新的libxml2和libxslt,它就是这样。 – HuStmpHrrr 2014-10-20 23:00:51

+0

如果你构建了一个与'.so'链接的东西,它将在运行时需要'.so'。这可能是你的问题。 – abarnert 2014-10-20 23:10:31

回答

3

这个问题似乎是你试图建立一个没有静态依赖关系的静态库。

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

共享库,如libxml2.so,基本上是一个可执行文件。链接器链接时,链接器会创建重定位条目,以便当您的目标和libxml2.so同时加载到内存中时,由于代码位于libxml2.so中,所以您调出的任何函数都可以工作。

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

一个现代的链接器完全没有问题 - 但它需要静态库libxml2来做到这一点。

所以,你需要得到libxml2.a(和libxslt2.a,甚至可能是libz.a)安装之前,你可以建立你想要的。


我在这里稍微简化了一点。在某些平台上,.so文件实际上只是真正的共享对象的前端,基本上是重定位表加上实际文件的链接。在其他平台上,可以从.so文件中取出代码,并在原地“重新定位”,.a文件可以只是类似的前端到共享对象。还有一些平台与ELF截然不同,这个术语更具误导性而非实用性。

如果您想了解更多信息,请从this question以及其他相关的问题开始。

如果你不这样做,只要相信你需要.a文件就可以静态链接任何东西。只要

在Linux(和大多数其他乖巧的操作系统),pip将设法构建源分布:


如果你读了installation文档,你会发现, libxml2libxslt已正确安装,包括开发包(即头文件等)。如果构建失败,请使用包管理工具查找类似libxml2-devlibxslt-devel的包,并确保它们已安装。 或者,设置STATIC_DEPS=true将自动下载并构建两个库。

所以,如果你没有这些库都,建设lxml将下载的依赖性,构建了.a文件给你,并且对他们的链接。

但是,如果你做的他们,然后(一)pkg-config和/或xml2-config是要找到并使用它们,和(b),即使没有,lxml最终可能-lxml2不是建立绝对路径为libxml2.a,并且无论如何都链接错误的路径。

你怎么能解决这个问题?那么,你会认为会有一个简单的标志,告诉它不要这样做,但据我所知,没有。因此,您的选项包括:

  • 使用不包含libxml2libxslt2的假根构建。这在Building Debian packages文档中松散地暗示。
  • 手动构建静态仅libxml2libxslt2并通过绝对路径向所得xml2-configxslt2-configsetup.py,如在Building the sources说明。
  • 暂时砍了xml2-configxslt2-config(或者,如果你没有这些,通过pkg-config使用的.pc文件)使用绝对路径.a文件LDFLAGS,而不是-L-l标志。
  • 在构建lxml时(通过重命名它们,设置不同的路径或其他方式),暂时将.so文件从您的库路径中取出。
  • 假设版本号与您安装的.so文件的版本号不同(或可能不同),您可以按照Mac build instructions指定明确的版本号来作弊。您可能必须手动下载tarball才能正常工作,但您不必构建它们。

如果这一切看起来像是一种痛苦,而且应该很容易......好的,请记住你在这里要做的事情。 Linux是围绕构建源代码发布的想法而设计的,它是您的特定系统可能的最佳方式。如果您的系统具有xml2和xslt2的共享库,则设置所有内容以尝试使用它们。如果你想构建代码来部署到没有这些系统的系统,那么你的开发系统预计也没有它们;如果确实如此,你应该知道如何解决这个问题。

+0

嗨。我建立了一个新的虚拟机来测试它。我在我的新vm中找到了Debian,'python setup.py build --static-deps'很完美。而我在构建之前只有1个命令:'sudo apt-get install gcc build-essential binutils python-dev'。看起来并非如此,因为你说我缺乏静态库。 – HuStmpHrrr 2014-10-21 00:03:41

+0

@HuStmpHrrr:我猜你的新VM没有'libxml2.so'吗? (或者也许它,但也有'libxml2.a',但这似乎不太可能。) – abarnert 2014-10-21 00:17:17

+0

不,我没有。一切都很干净。我在开始时甚至没有gcc。 – HuStmpHrrr 2014-10-21 00:53:46