Saltar al contenido principal

Visibilidad de simbolos GNU

Hoy aprendí sobre un detalle al compilar una biblioteca compartida. Quería ligar código contra una biblioteca que compilé con meson, pero seguía obteniendo errores al ligar, específicamente

undefined reference to `func_name' # referencia indefinida a `func_name'

Después de compilar la biblioteca manualmente e inspeccionar el objeto resultante con nm, la diferencia relevante fue a siguiente

# creado con meson
0000000000001263 t func_name

# compilada manuamente
0000000000001263 T func_name

La diferencia es sobre la T siendo minúscula/mayúscula, como sugiere la página de manual de NM(1):

“T”

“t” The symbol is in the text (code) section.

El símbolo se encuentra en la sección de texto (código). Sin embargo, no menciona la diferencia entre minúscula/mayúscula.

Resulta que la T mayúscula significa que es un símbolo global, mientras la t minúscula es local. Obviamente ignoré el siguiente enunciado de la página del manual

If lowercase, the symbol is usually local; if uppercase, the symbol is global (external).

Si es minúscula, el símbolo es usualmente local, mientras la mayúscula es un símbolo global (externo). Así que cambiando el valor de gnu_symbol_visibility de hidden (oculto, el cual es el valor por defecto cuando meson genera automáticamente el archivo meson.build) a default (por defecto) cambia cómo los símbolos son manejados dentro del archivo de biblioteca compartida generada.

Más detalles sobre la visibilidad de símbolos se pueden consultar en la wiki de GNU (en Inglés)

Y ahora, ¡a seguir jugando!