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
5
A
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
$
Come posso specificare locale prima che arrivi al modulo oggetto? Nel codice idealmente, ma forse anche come parte della compilazione di oggetti? – CptanPanic
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. –