librerias instalar ejecutar compilar compilador como bibliotecas c++ shared-libraries dynamic-linking

ejecutar - instalar compilador c++ ubuntu



Obliga a GCC a notificar sobre referencias indefinidas en bibliotecas compartidas (4)

Tengo una biblioteca compartida que está vinculada a otra biblioteca compartida (de terceros). Mi biblioteca compartida se carga utilizando dlopen en mi aplicación. Todo esto funciona bien (suponiendo que los archivos están en el camino correcto, etc.).

Ahora, el problema es que ni siquiera necesito especificar un enlace contra la biblioteca compartida de terceros cuando enlace mi biblioteca. GCC lo acepta sin informar errores sobre referencias indefinidas. Entonces, la pregunta; ¿Cómo puedo obligar a GCC a notificarme sobre referencias indefinidas ?

Si cambio mi biblioteca para que sea (temporalmente) un ejecutable, obtengo referencias no definidas (cuando no estoy entregando la biblioteca al enlazador). (Funciona bien si lo especifico).

Es decir, se hace lo siguiente:

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

Donde la segunda línea NO da un error y la tercera línea se queja de una referencia no definida.

Código de muestra:

ah:

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(); }

bh:

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

b.cpp:

#include "b.h" void b::foobar() { }


Después de más investigaciones, me di cuenta de qué manera funcionan las cosas. Hay dos opciones de vinculador para manipular símbolos indefinidos de bibliotecas compartidas:

El primero es --no-undefined . Informa los símbolos no resueltos que no se resuelven inmediatamente, en la etapa de enlace. A menos que el símbolo se encuentre en una biblioteca compartida vinculada, ya sea manualmente (con -l switch) o automáticamente ( libgcc_s , C ++ runtime; libc , C runtime; ld-linux-**.so libgcc_s , dynamic linker utils) elegido, --no-undefined informa como un error. Esa es la clave que el interrogador necesitaba.

Hay otra clave, --no-allow-shlib-undefined (cuya descripción también sugiere --no-undefined ). Comprueba si se cumplen las definiciones en las bibliotecas compartidas a las que vincula su biblioteca compartida . Esta clave es de poca utilidad en el caso que se muestra en este tema, pero puede ser útil. Sin embargo, tiene sus propios obstáculos.

La página de manual proporciona algunos argumentos sobre por qué no es el valor predeterminado:

--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.

El hecho es que lo dicho anteriormente también es cierto, por ejemplo, para los sistemas Linux, donde algunas de las rutinas internas de la biblioteca compartida se implementan en ld-linux.so , el cargador dinámico (es biblioteca ejecutable y compartida). A menos que de alguna manera lo vincules, obtendrás algo como esto:

/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''

Estas son referencias indefinidas del cargador, ld-linux.so . Es específico de la plataforma (por ejemplo, en mi sistema, el cargador correcto es /lib64/ld-linux-x86-64.so ). Puede vincular el cargador con su biblioteca y verificar incluso las referencias engañosas que se muestran arriba:

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


No puede hacer que ld (que es lo que está ejecutando gcc) preste atención a una biblioteca que no está allí en el enlace. Puede desactivar RTLD_LAZY para obtener informes agresivos, y puede agregar una prueba de unidad que se ejecuta justo después del enlace para solucionar estos problemas.



-Wl, - la opción del enlazador no indefinido se puede usar al compilar una biblioteca compartida, los símbolos indefinidos se mostrarán como errores del enlazador.

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