Boost测试fpic连接错误

boost testing fpic linking error

本文关键字:错误 连接 fpic 测试 Boost      更新时间:2023-10-16

我一直在盯着谷歌,但我看不出我做了什么。

我有一个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存储库中提取。有任何线索的人。

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

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

该转换在x86 64位上失败;两个错误信息表示

  1. 重定位应用于32位值,但位移可能大于32位(出于安全原因,共享库位于随机地址,这使得它们在64位平台上相距很远,
  2. 由于这个原因,没有动态重定位类型对应于来自静态库的重定位表项。

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

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

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

你看到的是,当你试图构建64位时,从第一个选项的绝对地址不能强制一个特定的64位地址(可能在你的代码中的一些对象文件不支持64位地址),编译器告诉你,你使用选项2与PIC启用。为了做到这一点,您需要使用-fPIC(假设是g++/gcc)编译所有代码和库。您可能还需要将库与-shared连接起来,但我不记得您必须这样做的确切时间。

好吧,Simon的回答真的帮了我大忙。

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

libboost_unit_test_framework

(带有共享库)代替

libboost_test_exec_monitor