2

我一直在盯着和谷歌搜索,但我看不到我做了什么。

我有一个在 32 位机器上工作的项目。我刚刚将存储库拉到 64 位机器(这是该项目的原始开发机器),现在在尝试构建测试二进制文件时出现以下链接错误

/usr/bin/ld: error: /usr/lib/libboost_test_exec_monitor-mt.a(unit_test_log.o): requires dynamic R_X86_64_PC32 reloc against 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&)' which may overflow at runtime; recompile with -fPIC
/usr/bin/ld: error: /usr/lib/libboost_test_exec_monitor-mt.a(unit_test_log.o): requires unsupported dynamic reloc 11; recompile with -fPIC

我真的看不出我可以改变什么。boost 库是直接从 ubuntu 存储库中提取的。任何有线索的人。

4

3 回答 3

14

您正在将静态库(Boost 库)链接到动态库。静态库通常不使用 -fPIC 构建,因为它们被假定为仅链接到一个程序,而不是另一个库。

在 32 位 x86 上,此类代码通过重新定位与加载地址不与位置无关的代码部分来静默修复;这使得受影响的页面无法共享。为此,需要将重定位条目从链接时间转换为运行时重定位。

此转换在 x86 64 位上失败;这两个错误信息的意思

  1. 重定位应用于 32 位值,但位移可能大于该值(出于安全原因,共享库位于随机地址,这使它们在 64 位平台上相距很远,并且
  2. 因此,静态库中没有对应于重定位条目的动态重定位类型。

因此,链接器无法生成可加载的代码,并且理所当然地拒绝这样做。

要解决这个问题,您需要链接 shared libboost_test_exec_monitor-mt,或者自己构建一个静态库。

于 2012-01-02T18:07:56.760 回答
2

可以通过两种方式设置共享库。一种是使用绝对地址,以便加载共享对象的每个二进制文件都获得它自己的共享代码副本,但调用没有额外的间接性并且尽可能快。另一种方式是使用“PIC”或与位置无关的代码。这增加了一个额外的间接层,但是共享库代码的一个副本可以服务于所有需要它的应用程序(因为额外的间接层是每个应用程序二进制文件)。

您看到的是,当您尝试构建 64 位时,第一个选项中的绝对地址无法强制使用特定的 64 位地址(可能代码中的某些目标文件不支持 64-位地址)并且编译器告诉您必须在启用 PIC 的情况下使用选项 2。为此,您需要使用-fPICg++/gcc 编译所有代码和库。您可能还需要链接图书馆,-shared但我不记得您必须这样做的确切时间。

于 2012-01-02T17:25:15.990 回答
0

好的,西蒙的回答真的帮助了我。

这个特定问题的最终解决方案是使用

libboost_unit_test_framework

(它带有一个共享库)代替

libboost_test_exec_monitor

(没有)

于 2012-01-08T16:15:16.323 回答