2010-11-14 13 views
6

Tengo un programa, myprogram, que está vinculado con una biblioteca de conveniencia estática, llámelo libconvenience.a, que contiene una función, func(). La función func() no se llama en ningún lugar en myprogram; debe poder invocarse desde una biblioteca de complementos, plugin.so.Símbolos de la biblioteca de conveniencia no se exportan en el ejecutable

El símbolo func() no se está exportando dinámicamente en myprogram. Si ejecuto

nm myprogram | grep func 

No obtengo nada. Sin embargo, no está ausente de libconvenience.a:

nm libconvenience/libconvenience.a | grep func
00000000 T func

estoy usando automake, pero si lo hago el último paso vinculación con la mano en la línea de comandos en su lugar, no funciona bien:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries` 

sin embargo, si puedo enlazar el programa como este, pasando por alto el uso de una biblioteca de conveniencia y la vinculación de los archivos de objetos que han entrado en libconvenience.a directamente, func() muestra en myprogram 's símbolos como debería:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries` 

Si añado una llamada ficticia a func() en algún lugar de myprogram, entonces func() muestra también en myprogram' s símbolos. ¡Pero pensé que se suponía que --export-dynamic debía exportar todos los símbolos independientemente de si se usaban en el programa o no!

estoy usando automake 1.11.1 y 4.5.1 gcc en Fedora 14. También estoy usando Libtool 2.2.10 para construir plugin.so (pero no la biblioteca de conveniencia.)

que no se olvide de poner -Wl,--export-dynamic en myprogram_LDFLAGS, ni se me olvidó poner la fuente que contiene func() en libconvenience_a_SOURCES (algunas google sugiere que estos son causas comunes de este problema.)

Puede alguien ayudarme a entender lo que está pasando aquí?

Respuesta

3

Pude resolverlo. Fue esta nota del excelente libro Autotools de John Calcote que me señaló en la dirección correcta:

enlazadores añaden al producto binario todos los archivos objeto especificado explícitamente en la línea de comandos, pero sólo extraer de los archivos esos ficheros objeto que en realidad se hace referencia en el código que se vincula.

Para contrarrestar este comportamiento, se puede usar el indicador --whole-archive para libtool. Sin embargo, esto provoca que todos los símbolos de todas las bibliotecas del sistema también se extraigan, lo que causa muchos errores de definición de doble símbolo.Por lo tanto, --whole-archive debe estar justo antes de libconvenience.a en la línea de comando del enlazador, y debe estar seguido por --no-whole-archive para que las demás bibliotecas no sean tratadas de esa manera. Esto es un poco difícil, ya que automake y libtool realmente no garantizan mantener sus banderas en el mismo orden en la línea de comandos, pero esta línea en Makefile.am hizo el truco:

myprogram_LDFLAGS = -Wl,--export-dynamic \ 
    -Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive 
0

Si necesita func estar en plugin.so, intente localizarlo allí si es posible. Las bibliotecas de conveniencia deben ser solo eso, una conveniencia para vincular a un archivo ejecutable o lib como un paso intermedio.

+0

Es cierto, pero necesito explícitamente func _NO_ a estar en el complemento, porque func es parte de una API que necesitan varios complementos para llamar. Los complementos fueron escritos en otra parte y estoy tratando de evitar modificaciones locales a ellos. – ptomato

Cuestiones relacionadas