2010-03-01 10 views
37

Tengo una biblioteca compartida que está vinculada con 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.).Forzar GCC para notificar sobre referencias indefinidas en bibliotecas compartidas

Ahora, el problema es que ni siquiera necesito especificar un enlace contra la biblioteca compartida de terceros cuando vinculo 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 vinculador). (Funciona bien si la especifica.)

es decir, se realiza lo siguiente:

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

Cuando la segunda línea no da un error y la tercera línea se queja de una referencia indefinida.

Código de ejemplo:

a.h:

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:

b.cpp:

#include "b.h" 

void b::foobar() 
{ 
} 

Respuesta

33

-Wl, - no-undefined opción de vinculador se puede utilizar al crear bibliotecas compartidas, los símbolos indefinidos se mostrarán como errores de enlazador.

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

+0

No, no hay error en absoluto. –

+0

¿Podría proporcionar la salida del enlazador? –

+0

Hm, podría haber jurado que lo hice antes y no obtuve nada como salida. Hacer esto una vez más pareció hacer que esto funcionara bien (es decir, ¡recibo un error!) –

1

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

+0

Lo que * puede * hacer, y lo que el que pregunta fue después, es obtener 'ld' para decirle" No tengo idea de dónde cree que van a venir estos símbolos, pero no están en ninguno de los bibliotecas de las que me ha hablado ". –

13

Después de más investigación, Me di cuenta de qué manera funciona el material. Hay dos opciones de vinculador para manipular los símbolos no definidos de bibliotecas compartidas:

La primera 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, dynamic linker utils) escogido, --no-undefined lo 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 las definiciones en las bibliotecas compartidas que vincula su biblioteca compartida contra están satisfechas. 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 alguna razón de por qué no está 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 caso es que lo que se dice más arriba también es cierto, por ejemplo, para los sistemas Linux, donde algunas de las rutinas internas de la compartían la biblioteca está implementada en ld-linux.so, el cargador dinámico (es biblioteca ejecutable y compartida). A menos que de alguna manera lo enlace, se consigue algo como esto:

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

Estos son referencias indefinidas desde el 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). Es posible vincular el cargador con su biblioteca y aun las referencias difíciles mostrados anteriormente:

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

No, no hay ningún error, independientemente de si uso --no-allow-shlib-undefined o --no-undefined. –

+0

@Fredrik, supongo, olvidaste agregar '-Wl,' cosas. * * Muestra el error, aunque * no * el que usted quería. Pero eso es lo máximo que puedes tener. –

+0

Parece que --no undefined funciona como se esperaba, pero --no-allow-shlib-undefined no lo hace. (Trabajando como dices) –

Cuestiones relacionadas