2008-11-08 19 views
19

Parece que hay 3 formas de contar GCC a eslabón débil en un símbolo:¿Cómo hacer que los enlaces débiles funcionen con GCC?

  • __attribute__((weak_import))
  • __attribute__((weak))
  • #pragma weak symbol_name

Ninguno de estos trabajos para mí:

#pragma weak asdf 
extern void asdf(void) __attribute__((weak_import, weak)); 
... 
{ 
    if(asdf != NULL) asdf(); 
} 

Siempre me sale un error de enlace como este:

Undefined symbols: 
    "_asdf", referenced from: 
     _asdf$non_lazy_ptr in ccFA05kN.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status

Estoy usando GCC 4.0.1 en OS X 10.5.5. ¿Qué estoy haciendo mal?

+0

'int __attribute __ ((weak)) main() {...}' funciona bien para mí con gcc/Mac OS X, pero no se puede compilar con gcc/MinGW. :( – mcandre

+0

este puede ser el problema: http://stackoverflow.com/questions/13089166/how-to-make-gcc-link-strong-symbol-in-static-library-to-overwittren-sweak-symbol –

Respuesta

0

Desde el manual doc gcc:

débil

The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.

lo que significa que un objeto está legitimado para sobrescribir un símbolo débil (que se define en otro objeto/biblioteca) sin obtener errores en tiempo de enlace . Lo que no está claro es si está vinculando la biblioteca con el débil símbolo o no. Parece que ambos no han definido el símbolo y que la biblioteca no está correctamente vinculada.

+0

Hay parece ser dos usos de la vinculación débil: http://gcc.gnu.org/ml/gcc/1999-02n/msg01219.html Estoy intentando vincular con una versión anterior de una biblioteca. La versión actual define las funciones el anterior no. Quiero poder usar las nuevas funciones si están disponibles en tiempo de ejecución. –

+1

Esa cita no se aplica aquí: "El diseño de enlace débil de Mac OS X [viene del clásico Administrador de Fragmentos de Código de Mac OS ]. Si está familiarizado con [ELF], puede usar un significado diferente para los términos * weak symbol * o * weak linking, * donde un símbolo débil puede ser anulado por un símbolo no debil. La característica equivalente de Mac OS X es la * definición débil * -ver ["Ámbito y tratamiento de las definiciones de símbolos"] (http://developer.apple.com/libra ry/mac/# documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html # // apple_ref/doc/uid/TP40001829-98432-TPXREF120) para más información. " –

4

Debe establecer la variable MACOSX_DEPLOYMENT_TARGET a 10.2 o posterior. Ver Apple's documentation y su technote en enlace débil.

+0

Lo he visto, y es establecer de esa manera. Ese no es el error que estoy recibiendo. –

6

Agregue -Wl,-flat_namespace,-undefined,dynamic_lookup a la línea del compilador gcc que utiliza para hacer el enlace final.

+1

Cuando uso gcc/MinGW, dice 'cc1.exe: error: opción de línea de comando no reconocida" -flat_namespace, -undefined, dynamic_lookup "'. – mcandre

28

Acabo de analizar esto y pensé que otros podrían estar interesados ​​en mis hallazgos.

La vinculación débil con weak_import realmente solo funciona bien con bibliotecas dinámicas. Puede hacer que funcione con enlaces estáticos (al especificar "dynamic_lookup no definido" como se sugirió anteriormente), pero esta no es una idea tan buena. Significa que no se detectarán símbolos indefinidos hasta el tiempo de ejecución. Esto es algo que evitaría en el código de producción, personalmente.

Aquí está una sesión de Terminal de Mac OS X que muestra cómo hacer que funcione:

Aquí está fc

int f(int n) 
{ 
    return n * 7; 
} 

Aquí es whatnof.c

#include <stdio.h> 
#include <stdlib.h> 

extern int f (int) __attribute__((weak_import)); 

int main() { 
    if(f == NULL) 
     printf("what, no f?\n"); 
    else 
     printf("f(8) is %d\n", f(8)); 
    exit(0); 
} 

hacer una biblioteca dinámica desde fc:

$ cc -dynamiclib -o f.dylib f.c 

Compilar y vincular con la lib dinámica, enumerar las librerías dinámicas.

$ cc -o whatnof whatnof.c f.dylib 
$ otool -L whatnof 
whatnof: 
     f.dylib (compatibility version 0.0.0, current version 0.0.0) 
     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0) 

Run whatnof para ver lo que sucede:

$ whatnof 
f(8) is 56 

Ahora reemplace f.dylib con una biblioteca vacía (no símbolos):

$ mv f.dylib f.dylib.real 
$ touch null.c 
$ cc -dynamiclib -o f.dylib null.c 

Run misma whatnof para ver lo que sucede:

$ whatnof 
what, no f? 

La idea básica (o "caso de uso") para weak_import es que le permite enlazar contra un conjunto de bibliotecas dinámicas (compartidas), pero luego ejecute el mismo código en versiones anteriores de las mismas bibliotecas. Puede verificar las funciones contra NULL para ver si son compatibles con la biblioteca dinámica particular con la que se está ejecutando actualmente el código. Esto parece ser parte del modelo de desarrollo básico soportado por Xcode. Espero que este ejemplo sea útil; me ayudó a tranquilizarme sobre esta parte del diseño de Xcode.

Cuestiones relacionadas