¿Cómo aplicar la opción-fvisibility a símbolos en bibliotecas estáticas?


Tengo un proyecto de biblioteca compartida que se construye a partir de 4 bibliotecas estáticas (.a) y un archivo object (.o). Estoy tratando de agregar la opción -fvisibility=hidden para restringir los símbolos en la salida solo a aquellos que marque en la fuente con un atributo___.

He añadido la opción -fvisibility=hidden a las opciones de compilación para el proyecto .so (que cubre el archivo .o) y para los proyectos .a.

Los símbolos en el archivo objeto se eliminan como se espera del .so final. Sin embargo, el los símbolos de los proyectos .a están todavía en el archivo final .so. Agregar la opción -fvisibility=hidden al comando .so link no tiene efecto.

¿Qué estoy haciendo mal?

Mi propósito aquí es eliminar de .so todos los símbolos excepto las funciones de interfaz de la biblioteca.

EDITAR: En realidad usé un mapa de versión para resolver esto por ahora. Sin embargo, requiere un mantenimiento continuo del script de la versión a medida que cambian los símbolos externos. Respuesta aceptada tiene una mejor idea.

Author: jww, 2010-02-08

3 answers

Básicamente, la visibilidad se maneja durante el enlace, y el enlazador no parece imponerla a los archivos estáticos. Una pregunta relacionada (aunque no un duplicado) fue hecha en SO aquí.

Lo que te aconsejo que hagas es reemplazar tu etapa de enlace: gcc -shared -o mylib.so foo.o libbar.a en un proceso de dos etapas donde recuperes los archivos objeto:

  • ar x libbar.a (posiblemente en un directorio adecuado y vacío)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
 29
Author: F'x,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:10

Simplemente pase -Wl,--exclude-libs,ALL a gcc

Esto le dirá al enlazador que transforme todos los símbolos en las bibliotecas estáticas en ocultos.

--exclude-libs también acepta una lista de archivos (es decir, nombres de bibliotecas estáticas) para una granularidad más fina en las bibliotecas de las que ocultar símbolos.

Nota: esto solo funcionará en sistemas que usen GNU binutils (por ejemplo, Linux) o con un enlazador que soporte --exclude-libs (por ejemplo, no funcionará con ld64 de OSX)

 53
Author: fons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-12 21:42:43

Esta es una respuesta al problema para OS X.

El Mac ld no soporta --exclude-libs, pero sí soporta -exported_symbol sym y aplica esto a archivos objeto en bibliotecas estáticas. Y cuando se filtra a una API pública, la lista blanca es lo suficientemente pequeña como para deletrearla.

Terminé con lo siguiente en mi Makefile para generar una bandera -Wl,-exported_symbol,_api_func_1 para cada símbolo exportado:

SYMBOLS   = api_func_1 api_func_2 api_func_3 api_func_4
SYMBOLS   += api_func_5 # add more as necessary
COMMA     = ,
LDFLAGS   += $(addprefix -Wl$(COMMA)-exported_symbol$(COMMA)_,$(SYMBOLS))

# ...

libmyapi.so: # ...
    $(CC) -shared -o $@ ... $(LDFLAGS)

Entonces puede if-gate entre esta versión de las banderas y la versión GNU ld después detectando qué enlazador tiene el sistema.

 4
Author: Riking,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 15:45:08