2010-07-14 15 views
5

Sto usando un vecchio sistema che ha gcc 2.95.3, devo collegare in due oggetti che sebbene non abbiano nulla a che fare l'uno con l'altro, ognuno di essi ha metodi con nomi simili. Non posso rinominare nessuno dei due, ma spero che ci sia un modo per costruirli in modo da non lamentarsi del linker. I metodi a cui si lamenta sono chiamati internamente da classi all'interno dell'oggetto. Cosa posso fare?Come aggirare "più simboli definiti" nel collegamento con gcc

risposta

9

Se si dispone di un completo toolchain GNU, si dovrebbe essere in grado di aggirare il problema utilizzando objcopy, come questo (se ho capito il problema in modo corretto):

Qui ci sono due oggetti molto simili, "foo "e 'bar', entrambi i quali esportare un simbolo chiamato clash - che viene utilizzato internamente, ma in realtà non deve essere esportato a tutti:

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

e

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

Ed ecco il codice principale, che vuole utilizzare sia:

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

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

collegandoli insieme non funziona:

$ 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 
$ 

Quindi, utilizzare objcopy per modificare la visibilità di clash in uno (o entrambi, se si vuole) degli oggetti:

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

Ora è possibile collegare con successo con l'oggetto modificato - e il programma si comporta come! dovrebbe:

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

Come posso specificare locale prima che arrivi al modulo oggetto? Nel codice idealmente, ma forse anche come parte della compilazione di oggetti? – CptanPanic

+2

Se la funzione di contrasto è utilizzata solo in un singolo file, non è necessario che sia esportata, quindi è necessario che 'static' funzioni. Ciò funzionerebbe con il mio esempio banale sopra. (Supponevo che tu non potessi cambiare la fonte originale e che invece avessi bisogno di lavorare con gli oggetti, quando hai detto che non potevi rinominare le cose.) Se * fai * bisogno di quei simboli esportati per i riferimenti tra oggetti in una fase di collegamento precedente (e, g, collegando un oggetto parziale o una libreria), le cose sarebbero più difficili e l'ordinamento dipenderà dai dettagli più fini del processo di compilazione. –

Problemi correlati