буст-тестирование ошибок fpic - PullRequest
2 голосов
/ 02 января 2012

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

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

14 голосов
/ 02 января 2012

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

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

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

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

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

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

2 голосов
/ 02 января 2012

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

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

0 голосов
/ 08 января 2012

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

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

libboost_unit_test_framework

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

libboost_test_exec_monitor

(чего нет)

...