2010-07-14 22 views
5

Estoy usando un sistema anterior que tiene gcc 2.95.3, tengo que vincular dos objetos que, aunque no tienen nada que ver entre sí, tienen cada uno métodos de nombre similar. No puedo cambiar el nombre de ninguno de ellos, pero espero que haya una forma de compilarlos para que el enlazador no se queje. Los métodos de los que se queja son llamados internamente por clases dentro del objeto. ¿Que puedo hacer?Cómo evitar "múltiples símbolos definidos" al vincular con gcc

Respuesta

9

Si tiene una cadena de herramientas GNU completo, usted debe ser capaz de evitar el problema con objcopy, como esto (si he entendido su problema correctamente):

Éstos son dos objetos muy similares, "foo "y 'barra', ambos de los cuales exportar un símbolo denominado clash - que se usa internamente, pero en realidad no necesitan ser exportados en absoluto:

$ cat foo.c 
#include <stdio.h> 
void clash(char *s) { printf("foo: %s\n", s); } 
void foo(char *s) { clash(s); } 
$ 

y

$ cat bar.c 
#include <stdio.h> 
void clash(char *s) { printf("bar: %s\n", s); } 
void bar(char *s) { clash(s); } 
$ 

Y aquí está el código principal, que quiere usar tanto:

$ cat main.c 
extern void foo(char *s); 
extern void bar(char *s); 

int main(void) 
{ 
    foo("Hello"); 
    bar("world"); 
    return 0; 
} 
$ 

enlazándolos no funciona:

$ gcc -Wall -c foo.c 
$ gcc -Wall -c bar.c 
$ gcc -Wall -c main.c 
$ gcc -o test main.o foo.o bar.o 
bar.o: In function `clash': 
bar.c:(.text+0x0): multiple definition of `clash' 
foo.o:foo.c:(.text+0x0): first defined here 
collect2: ld returned 1 exit status 
$ 

lo tanto, utilizar objcopy para cambiar la visibilidad de clash en uno (o tanto, si se quiere) de los objetos:

$ objcopy --localize-symbol=clash bar.o bar2.o 
$ 

ya se puede vincular con éxito con el objeto modificado - y el programa se comporta como! debería:

$ gcc -o test main.o foo.o bar2.o 
$ ./test 
foo: Hello 
bar: world 
$ 
+1

¿Cómo puedo especificar local antes de que llegue a la forma de objeto? En el código idealmente, pero también tal vez como parte de la compilación de objetos? – CptanPanic

+2

Si la función de conflicto solo se utiliza en un único archivo, no es necesario exportarla en absoluto, por lo que debería funcionar 'static '. Esto funcionaría con mi ejemplo trivial de arriba. (Supuse que no podía cambiar la fuente original, y necesitaba trabajar con los objetos, cuando dijo que no podía cambiar el nombre de las cosas). Si * necesita *, esos símbolos exportados para referencias entre objetos en una etapa de enlace anterior (e, g, que une un objeto parcial o una biblioteca), entonces las cosas serían más difíciles, y clasificarlas dependería de los detalles más finos del proceso de compilación. –

Cuestiones relacionadas