После дополнительных исследований я понял, как все это работает. Существует два параметра компоновщика для управления неопределенными символами общих библиотек:
Первый - --no-undefined
. Он сообщает о неразрешенных символах, которые не разрешаются немедленно, на этапе связывания. Если символ не найден в общей библиотеке, с которой он связан, либо вручную (с переключателем -l
), либо автоматически (libgcc_s
, среда выполнения C ++; libc
, среда выполнения C; ld-linux-**.so
, утилиты динамического компоновщика), --no-undefined
сообщает об этом как об ошибке. Это ключ, который нужен спрашивающему.
Есть еще один ключ, --no-allow-shlib-undefined
(описание которого также предлагает --no-undefined
). Он проверяет, удовлетворяются ли определения в общих библиотеках , с которыми вы связываете свою общую библиотеку с . Этот ключ мало полезен в случае, показанном в этом разделе, но он может быть полезен. Однако у него есть свои препятствия.
Справочная страница дает некоторое объяснение, почему она не используется по умолчанию:
--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 `_dl_argv@GLIBC_PRIVATE'
/lib64/libc.so.6: undefined reference to `_rtld_global_ro@GLIBC_PRIVATE'
/usr/lib64/gcc/x86_64-suse-linux/4.3/libstdc++.so: undefined reference to `__tls_get_addr@GLIBC_2.3'
/lib64/libc.so.6: undefined reference to `_rtld_global@GLIBC_PRIVATE'
/lib64/libc.so.6: undefined reference to `__libc_enable_secure@GLIBC_PRIVATE'
Это неопределенные ссылки из загрузчика, 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