понедельник, 21 ноября 2011 г.

C++ библиотека-плагин для Unix. Часть 1-я. Visibility

Современные версии g++ (а я решил взять последнюю 4.6.2) обзавелись замечательным атрибутом visibility. Атрибут позволяет как и в windows dll скрывать символы (раньше, все символы в разделяемых библиотеках торчали наружу).
Подробнее об этом замечательном атрибуте можно почитать в первоисточнике GCC Wiki Visibility.

Беда в том, что внося новое, обязательно что нибудь старое сломается. Это как в бородатом анекдоте про программиста, его сына и солнце :) А задача у меня, как я уже писал в предыдущем посте, собрать такую старую добрую большую библиотеку, и чтобы не было ссылок на libgcc_s и libstdc++. Вот эта штука, visibility, мне, как оказалось все портила.

/usr/bin/ld: /usr/local/gcc/lib/i386-redhat-linux/4.6.2/libgcc_eh.a(unwind-dw2.o)(.text+0x2c3): unresolvable R_386_PLT32 relocation against symbol `_Unwind_Find_FDE@@GCC_3.0'
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: выполнение ld завершилось с кодом возврата 1
gmake[1]: *** [libsnmp_int_stlport.so.5.2.1] Ошибка 1
Т.е. как видим из ошибки, линкер не нашел _Unwind_Find_FDE в libgcc_eh.a. Но оно там есть, сам видел:
ar x libgcc_eh.a
nm unwind-dw2-fde-glibc.o | grep Find
   00001af0 T _Unwind_Find_FDE
Грешил я, что gcc при сборке libgcc_eh.a не добавляет -fPIC - но это зря, все он добавляет.
Оказалось, что он просто скрыл данный символ этой новой модной штукой visibility.
Проблему решил, изменив определение
extern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
на
extern __attribute__ ((visibility ("default"))) const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
в файле заголовка unwind-dw2-fde.h в исходниках gcc.
Пересобирать весь gcc не надо. Заходим в каталог сборки boot/i686-pc-linux-gnu/libgcc,
удаляем *.o и запускаем gmake libgcc_eh.a. Затем подменяем оригинальную libgcc_eh.a или используем прямое указание компилятору рантаймных библиотек. (об этом позже)
Кстати, в версии 4.3.2. та-же самая проблема .

Комментариев нет:

Отправить комментарий