2013-10-09 2 views
7

У меня есть тривиальное кусок кода 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?

+0

Вы пытались использовать '-shared -z defs'? –

+0

@CharlesBailey Добавление '-z defs' в общую сборку приводит к ее разрыву (' test.cc :(.текст + 0x85): неопределенная ссылка на «boost :: system :: generic_category()»). Глядя на '-z defs', я также указал на' - [no-] allow-shlib-undefined', и это может на самом деле объяснить, что происходит ... спасибо за указатель! – user2862505

ответ

5

Прямой ответ на мой вопрос в опции --[no-]allow-shlib-undefined для ld, я думаю. От человека странице:

поведение по умолчанию для сообщений об ошибках для всех неопределенных символов ссылки в разделяемых библиотеках, если компоновщик используется для создания исполняемого файла, но разрешить их, если компоновщик используется для создайте общую библиотеку.

Поэтому, когда я строю с -shared, символы в boost_system не определены, но поведение по умолчанию л.д. не заботиться. Это может быть сказано в уходе:

$ g++ -fPIC -shared -Wl,--no-allow-shlib-undefined -o test test.cc -lboost_timer 
/usr/bin/ld: /tmp/cc6j1de3.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 

Точно так же, мы можем сказать, это не заботило при создании исполняемого:

$ g++ -Wl,--allow-shlib-undefined -o test test.cc -lboost_timer 
/tmp/ccUHoCIU.o: In function `__static_initialization_and_destruction_0(int, int)': 
test.cc:(.text+0x7a): undefined reference to `boost::system::generic_category()' 
test.cc:(.text+0x86): undefined reference to `boost::system::generic_category()' 
test.cc:(.text+0x92): undefined reference to `boost::system::system_category()' 
collect2: error: ld returned 1 exit status 

Но создание двоичного файла не удается, не будучи в состоянии определить эти символы.

Thanks @CharlesBailey за то, что указал мне в правильном направлении!

0

В команде collect2 есть отличия, которые могут иметь значение. Различные команды сравниваются с http://imgur.com/eMr2tY2. Правая сторона создает общую библиотеку (-fPic -shared), слева - обычная компиляция.

+0

это, возможно, вопрос вне темы. Но ваш diff-образ выглядит интересным. не могли бы вы сообщить нам, где у вас этот инструмент для сравнения? – earthdan

Смежные вопросы