Ответ 1
-Wl, - no- undefined может использоваться при создании общей библиотеки, символы undefined будут отображаться как ошибки компоновщика.g++ -shared -Wl, -soname, libmylib.so.5 -Wl,-no- undefined -o libmylib.so.1.1 mylib.o -lthirdpartylib
У меня есть общая библиотека, которая связана с другой (сторонней) разделяемой библиотекой. Моя разделяемая библиотека затем загружается с использованием 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()
{
}
g++ -shared -Wl, -soname, libmylib.so.5 -Wl,-no- undefined -o libmylib.so.1.1 mylib.o -lthirdpartylib
После дальнейших исследований я понял, как работает материал. Существует два варианта компоновщика для управления символами 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
Также хорошо обсуждается это на вики Mandriva.
Вы не можете сделать ld (это то, что работает gcc), обратите внимание на библиотеку, которой нет в ссылке. Вы можете отключить RTLD_LAZY, чтобы получить агрессивную отчетность, и вы можете добавить unit test, который запускается сразу после ссылки только для устранения этих проблем.