当前位置: 首页 > 知识库问答 >
问题:

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

芮学
2023-03-14

我现在有两个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

它没有错误,但是如果我:

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

我搜过:导入lxml.etree到python时出错似乎没有很好的答案。我认为这是链接问题,所以我认为静态链接应该是一个更好的解决方案。

但我的主要目标是减少部署所花费的工作量,因此我将接受任何简单的方法。

请帮忙。提前感谢。

共有1个答案

贝财
2023-03-14

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

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

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

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

现代链接器做这件事绝对没有问题,但它需要libxml2的静态库来做这件事情。

因此,您需要安装< code>libxml2.a(和< code>libxslt2.a,甚至< code>libz.a),然后才能构建您想要的东西。

我在这里过于简单了。在某些平台上,.so文件实际上只是真实共享对象的前端,基本上是重定位表加上指向真实文件的链接。在其他平台上,代码可以从 .so 文件中提取并就地“重新定位”,而 .a 文件可以只是类似于共享对象的前端。有些平台与ELF如此不同,以至于这个术语的误导性大于实用性。

如果你想了解更多,从这个问题和其他相关问题开始。

如果你不这样做,就相信你需要.a文件来存储你想要静态链接的任何内容。

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

在Linux(以及大多数其他性能良好的操作系统)上,只要正确安装了< code>libxml2和< code>libxslt,包括开发包,即头文件等,< code>pip就会设法构建源代码发行版。如果构建失败,使用您的包管理工具查找像< code>libxml2-dev或< code>libxslt-devel这样的包,并确保它们已安装。或者,设置< code>STATIC_DEPS=true将自动下载并构建两个库。

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

但是如果你确实有它们,那么(a)pkg-config和/或xml2-config会找到它们并使用它们,(b)即使没有,lxml最终也可能使用-lxml2而不是libxml2.a的绝对路径进行构建,并且无论如何都链接了错误的路径。

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

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

如果这一切看起来很痛苦,并且很容易…好吧,记住你在这里要做什么。Linux的设计思想是为您的特定系统构建最佳的源代码发行版。如果您的系统有xml2和xslt2的共享库,那么一切都设置好了,可以尝试使用它们。如果您想要构建代码来部署到一个没有这些的系统,那么您的开发系统应该也没有这些;如果是这样,你应该知道如何解决这个问题。

 类似资料:
  • 我们将用一个已安装好的 Linux 发行版(例如 Debian、Mandrake、Red Hat、SuSE)来构建 LFS 系统。这个已存在的 Linux 系统(宿主系统)将作为建立新系统的起点,提供包括编译器、连接器和 Shell 等创建新系统的必要工具。

  • 问题内容: 我需要创建一个Java util,它将通过Unix(和/或Linux)文件系统递归,并建立目录结构的对象模型,检索文件信息-大小,创建日期,上次访问日期等- 以及我需要在文件所在的物理存储设备上检索信息。理想情况下,该实用程序将是可移植的。我没有Java标准库的经验,只有Unix OS的经验有限。 是否有可以处理Unix文件系统的Java标准库?还是我必须通过某些API进行本机调用,然

  • 到目前为止,我一直在研究这样的概念 HDFS联邦 它通过为每个联合的HDFS分区提供一个单独的名称名来联合您的分布式存储(HDFS)。 null 我面临的问题是..假设我作为一个tenant1用户从hive创建了一个表,它创建的表/apps/hive/warehouse类似于/apps/oozie/data。我想的是它将在用户的hdfs主目录中创建表,因此只有tenant1用户才能访问它。但这并没

  • 问题内容: 我将很快开始一个新的C++项目(它可能也包含一些C组件),并且我正在寻找一个现代的,具有工业实力的(即非beta)构建系统。该软件将由3-5个开发人员在3-5年内创建,并将在Linux上运行(稍后 可能 会支持Mac OS X和Windows )。我正在寻找一种比例如具有更好的可理解性,易用性和可维护性,但仍足以处理复杂项目的功能。首选开源软件。 我开始寻找到,,和到目前为止,喜欢的功

  • 13. 构建系统 强烈建议您选择一个支持依赖管理的构建系统,而且这个构建系统能够使用发布到“Maven Central”库中的组件。我们建议您选择Maven或Gradle。Spring Boot有可能与其他构建系统(例如Ant)一起工作,但是其他构建系统不会得到特别好的支持。

  • 强烈建议您选择支持依赖关系管理且可以使用发布到“Maven Central”存储库的artifacts的构建系统。 我们建议您选择Maven或Gradle。 可以让Spring Boot与其他构建系统(例如Ant)一起工作,但它们并没有得到特别好的支持。

  • 本节说明了如何通过现有的 Unix 或 Linux 系统来安装 Debian GNU/Linux,而非使用 本手册后面要谈到的基于 ncurses、由菜单驱动的安装软件。这篇“交叉安装(cross-install)” 指南是应用户的要求而撰写的。他们原来是 Redhat、Mandrake 和 SUSE 的用户, 现转而使用 Debian GNU/Linux。在本节中,我们假设您对于输入 *nix

  • 本节说明了如何通过现有的 Unix 或 Linux 系统来安装 Debian GNU/Linux,而非使用 本手册后面要谈到的基于 ncurses,由菜单驱动的安装软件。这篇“交叉安装(cross-install)” HOWTO 是应用户的要求而撰写的。他们原来是 Redhat、Mandrake 和 SUSE 的用户, 现转而使用 Debian GNU/Linux。在本节中,我们假设您对于输入 *