Question

I have been staring and googling this but I cannot see what I have done.

I have a working project on a 32 bit machine. I have just pulled the repository to a 64 bit machine (which was the original development machine for the project) and I am now getting the following linking errors when trying to build the testing binary

/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

I really can't see what I could have changed. The boost libraries are pulled straight from the ubuntu repositories. Anyone with any clues.

Was it helpful?

Solution 3

Okay, Simon's answer really helped me along the way.

The ultimate solution to this particular problem was to use

libboost_unit_test_framework

(which comes with a shared library) in place of

libboost_test_exec_monitor

(which does not)

OTHER TIPS

You are linking a static library (the Boost one) into a dynamic library. Static libraries are not typically built with -fPIC, as they are assumed to be linked into a program only, not another library.

On 32 bit x86, such code is silently fixed up by relocating the portions of the code that are not position-independent to the load address; this makes the affected pages unshareable. For this to work, the relocation entry needs to be converted from a link time to a run time relocation.

This conversion fails on x86 64 bit; the two error messages mean

  1. The relocation is applied to a 32 bit value, but the displacement may be larger than that (shared libraries live at random addresses for security reasons, which places them wide apart on 64 bit platforms, and
  2. for this reason, there is no dynamic relocation type corresponding to the relocation entry from the static library.

Thus, the linker cannot generate code that would be loadable, and rightfully refuses to do so.

To solve this problem, you need to link against the shared libboost_test_exec_monitor-mt, or build a static library yourself.

Shared libraries can be set up in two ways. One is with absolute addresses, so that each binary that loads the shared object gets it own copy of the shared code, but the calls have no extra indirection and are as fast as possibly. The other way is with "PIC" or position independent code. This adds an extra layer of indirection but then one copy of the shared library code can serve all applications that need it (because the extra layer of indirection is per application binary).

What you're seeing is that when you try to build in 64-bit, the absolute addresses from the first option aren't able to force a particular 64-bit address (possibly some object file in your code doesn't support 64-bit addresses) and the compiler is telling you that you have to use option 2 with PIC enabled. In order to do this you'll need to compile all your code and libraries with -fPIC assuming g++/gcc. You may also need to link the library with -shared but I can't recall the precise times you have to do that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top