Подтвердить что ты не робот

Заставить GCC уведомлять о ссылках undefined в разделяемых библиотеках

У меня есть общая библиотека, которая связана с другой (сторонней) разделяемой библиотекой. Моя разделяемая библиотека затем загружается с использованием dlopen в моем приложении. Все это прекрасно работает (если файлы находятся на правильном пути и т.д.).

Теперь проблема заключается в том, что мне даже не нужно указывать ссылку на стороннюю разделяемую библиотеку при связывании моей библиотеки. GCC принимает его без сообщений об ошибках undefined. Итак, вопрос; как я могу заставить GCC уведомить меня о undefined ссылках?

Если я изменю свою библиотеку на (временно) исполняемый файл, я получаю ссылки undefined (когда не поставляю библиотеку компоновщику). (Отлично работает, если я укажу его.)

I.e., выполняется следующее:

g++ -fPIC -shared -o libb.so b.o 
g++ -fPIC -shared -o liba.so a.o
g++ -o a.exe a.cpp 

Если вторая строка НЕ ​​выдаёт ошибку, а третья строка жалуется на ссылку undefined.

Пример кода:

хиджры:

class a
{
public:
    void foobar();
};

a.cpp:

#include "a.h"
#include "b.h"

void a::foobar()
{
    b myB;
    myB.foobar();
}

int main()
{
    a myA; myA.foobar();
}

b.h:

class b
{
public:
    void foobar();
};

b.cpp:

#include "b.h"

void b::foobar()
{
}
4b9b3361

Ответ 1

-Wl, - no- undefined может использоваться при создании общей библиотеки, символы undefined будут отображаться как ошибки компоновщика.

g++ -shared -Wl, -soname, libmylib.so.5 -Wl,-no- undefined -o libmylib.so.1.1 mylib.o -lthirdpartylib

Ответ 2

После дальнейших исследований я понял, как работает материал. Существует два варианта компоновщика для управления символами undefined разделяемых библиотек:

Первый - --no-undefined. В нем сообщаются неразрешенные символы, которые не разрешаются немедленно, на этапе связывания. Если этот символ не найден в общей библиотеке, связанной с ней, либо вручную (с помощью -l switch), либо автоматически (libgcc_s, С++ runtime; libc, C runtime; ld-linux-**.so, dynamic linker utils) выбрано, --no-undefined сообщает об ошибке. Это ключ, который нужен вопрошающему.

Существует еще один ключ --no-allow-shlib-undefined (описание которого также предлагает --no-undefined). Он проверяет, выполнены ли определения в общих библиотеках , которые вы связываете с общей библиотекой с. Этот ключ малоприменим в случае, показанном в этом разделе, но он может быть полезен. Однако у Него есть свои препятствия.

В manpage приводятся некоторые соображения о том, почему это не по умолчанию:

   --allow-shlib-undefined
   --no-allow-shlib-undefined
       Allows  (the  default)  or  disallows  undefined  symbols  in  shared
       libraries (It is meant, in shared libraries _linked_against_, not the
       one we're creating!--Pavel Shved). This switch is similar to --no-un-
       defined except  that it determines  the  behaviour when the undefined
       symbols are in a shared library rather than a regular object file. It
       does not  affect  how  undefined  symbols in regular object files are
       handled.

       The  reason  that  --allow-shlib-undefined is the default is that the
       shared library being specified at link time may not be  the  same  as
       the one that is available at load time, so the symbols might actually
       be resolvable at load time.  Plus there are some systems,  (eg  BeOS)
       where  undefined  symbols in shared libraries is normal.  (The kernel
       patches them at load time to select which function is most  appropri-
       ate for the current architecture.  This is used for example to dynam-
       ically select an appropriate memset function).  Apparently it is also
       normal for HPPA shared libraries to have undefined symbols.

Дело в том, что сказанное выше также верно, например, для систем Linux, где некоторые внутренние подпрограммы разделяемой библиотеки реализованы в ld-linux.so, динамическом загрузчике (как исполняемой, так и общей библиотеке), Если вы каким-то образом не свяжете его, вы получите что-то вроде этого:

/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE'
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE'
/usr/lib64/gcc/x86_64-suse-linux/4.3/libstdc++.so: undefined reference to `[email protected]_2.3'
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE'
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE'

Это undefined ссылки от загрузчика, ld-linux.so. Это зависит от платформы (например, в моей системе правильный загрузчик /lib64/ld-linux-x86-64.so). Вы можете связать загрузчик с вашей библиотекой и проверить даже сложные ссылки, показанные выше:

g++ -fPIC -shared -o liba.so a.o -Wl,--no-allow-shlib-undefined  /lib64/ld-linux-x86-64.so.2

Ответ 3

Также хорошо обсуждается это на вики Mandriva.

Ответ 4

Вы не можете сделать ld (это то, что работает gcc), обратите внимание на библиотеку, которой нет в ссылке. Вы можете отключить RTLD_LAZY, чтобы получить агрессивную отчетность, и вы можете добавить unit test, который запускается сразу после ссылки только для устранения этих проблем.