Буст-тестирование ошибок fpic

Я смотрел и гуглил это, но я не вижу, что я сделал.

У меня есть рабочий проект на 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

Я действительно не вижу, что я мог изменить. Буст-библиотеки извлекаются прямо из репозиториев Ubuntu. Любой, у кого есть подсказки.

3 ответа

Решение

Хорошо, ответ Саймона действительно помог мне на этом пути.

Конечным решением этой конкретной проблемы было использование

libboost_unit_test_framework

(который поставляется с общей библиотекой) вместо

libboost_test_exec_monitor

(чего нет)

Вы связываете статическую библиотеку (Boost) в динамическую библиотеку. Статические библиотеки обычно не создаются с -fPIC, так как предполагается, что они связаны только с программой, а не с другой библиотекой.

На 32-битном x86 такой код незаметно исправляется путем перемещения частей кода, не зависящих от позиции, к адресу загрузки; это делает затронутые страницы недоступными. Чтобы это работало, запись перемещения должна быть преобразована из времени соединения в перемещение во время выполнения.

Это преобразование завершается неудачно на 64-битной x86; два сообщения об ошибках означают

  1. Перемещение применяется к 32-битному значению, но смещение может быть больше этого (разделяемые библиотеки живут по случайным адресам из соображений безопасности, что приводит к их разнесению на 64-битных платформах, и
  2. по этой причине нет динамического типа перемещения, соответствующего записи перемещения из статической библиотеки.

Таким образом, компоновщик не может генерировать код, который будет загружаемым, и по праву отказывается это делать.

Чтобы решить эту проблему, вам нужно сделать ссылку на общий libboost_test_exec_monitor-mtили создайте статическую библиотеку самостоятельно.

Совместно используемые библиотеки могут быть настроены двумя способами. Один - с абсолютными адресами, так что каждый двоичный файл, который загружает общий объект, получает свою собственную копию общего кода, но вызовы не имеют дополнительной косвенности и выполняются настолько быстро, насколько это возможно. Другой способ - с помощью PIC или кода, независимого от позиции. Это добавляет дополнительный уровень косвенности, но затем одна копия кода совместно используемой библиотеки может обслуживать все приложения, которым это необходимо (поскольку дополнительный уровень косвенности относится к двоичному файлу приложения).

То, что вы видите, это то, что когда вы пытаетесь встраивать 64-битные, абсолютные адреса из первого варианта не могут форсировать конкретный 64-битный адрес (возможно, какой-то объектный файл в вашем коде не поддерживает 64- битовые адреса), и компилятор говорит вам, что вы должны использовать опцию 2 с включенным PIC. Для этого вам нужно скомпилировать весь ваш код и библиотеки с -fPIC при условии g++/gcc. Вам также может понадобиться связать библиотеку с -shared но я не могу вспомнить точное время, когда вы должны это сделать.

Другие вопросы по тегам