У меня есть тривиальное кусок кода C++, который выглядит примерно так:Почему GNU ld разрешает символы по-разному при связывании исполняемых файлов с общими объектами?
#include <boost/timer/timer.hpp>
int main(void) {
boost::timer::auto_cpu_timer t;
return 0;
}
Я попытался собрать и связать его (с GCC 4.8.1 и GNU л.д. 2.23.52.20130828) следующим образом:
$ g++ -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Одним из решений является прямое упоминание -lboost_system
в командной строке, и это работает. Тем не менее, я могу также сделать:
$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer
Согласно документации Л.Д. «с --copy-дт-необходимо-записей динамических библиотек, указанных в командной строке будет рекурсивно обыскали, после их DT_NEEDED тэгов к другим библиотекам, для разрешения символов, требуемых выходным двоичным кодом ", поэтому все это имеет смысл: ld вычисляет из boost_timer, что ему также необходимо связать с boost_system, чтобы разрешить все символы.
Однако я понял, что это также работает:
$ g++ -fPIC -shared -o test test.cc -lboost_timer
Очевидно, что я в настоящее время создается общий объект, а не исполняемый файл. По-видимому, хотя, л.д. удалось выяснить, что это необходимо, чтобы связать общий объект с boost_system:
$ ldd test | grep boost_system
libboost_system.so.1.54.0 => /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000)
Так что мой вопрос заключается в следующем: почему разрешение символ отличается при создании разделяемого объекта против исполняемого файла? Как можно выяснить, что мой общий объект должен быть связан с boost_system без моего указания --copy-dt-needed-entries
?
Вы пытались использовать '-shared -z defs'? –
@CharlesBailey Добавление '-z defs' в общую сборку приводит к ее разрыву (' test.cc :(.текст + 0x85): неопределенная ссылка на «boost :: system :: generic_category()»). Глядя на '-z defs', я также указал на' - [no-] allow-shlib-undefined', и это может на самом деле объяснить, что происходит ... спасибо за указатель! – user2862505