tutorial todos solía sistemas significa scripts que operativos los español ejecutar como comando cli caracter brazo linux gcc linker autotools

todos - que significa en linux



Los símbolos de la biblioteca de conveniencia no se exportan en ejecutable (2)

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

El símbolo func() no se exporta dinámicamente en myprogram . Si corro

nm myprogram | grep func

No consigo nada. Sin embargo, no falta en libconvenience.a :

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

Estoy usando automake, pero si hago el último paso de enlace a mano en la línea de comandos, tampoco funciona:

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

Sin embargo, si vinculo el programa de esta manera, omitiendo el uso de una biblioteca de conveniencia y vinculando los archivos de objeto que se hubieran libconvenience.a directamente en libconvenience.a , func() aparece en los símbolos de myprogram como debería:

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

Si agrego una llamada ficticia a func() en algún lugar de myprogram , entonces func() también aparece en los símbolos de myprogram . Pero pensé 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 gcc 4.5.1 en Fedora 14. También estoy usando Libtool 2.2.10 para compilar plugin.so (pero no la biblioteca de conveniencia).

No me olvidé de poner -Wl,--export-dynamic en myprogram_LDFLAGS , ni olvidé poner la fuente que contiene func() en libconvenience_a_SOURCES (algunos de Google sugieren que estas son causas comunes de este problema).

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


Me las arreglé para resolverlo. Fue esta nota del excelente libro Autotools de John Calcote que me señaló la dirección correcta:

Los enlazadores agregan al producto binario todos los archivos de objetos especificados explícitamente en la línea de comandos, pero solo extraen de los archivos los archivos de objetos a los que se hace referencia en el código que se está vinculando.

Para contrarrestar este comportamiento, uno puede usar el --whole-archive para libtool. Sin embargo, esto provoca que todos los símbolos de todas las bibliotecas del sistema también se arrastren, lo que causa muchos errores de definición de doble símbolo. Entonces, --whole-archive debe estar justo antes de libconvenience.a en la línea de comando del enlazador, y debe estar seguido de --no-whole-archive para que las otras 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


Si necesita que func esté en plugin.so, debe intentar 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.