Как обойти несколько определенных символов при связывании с gcc

Я использую более старую систему с gcc 2.95.3, мне нужно связать два объекта, которые, хотя они не имеют ничего общего друг с другом, имеют методы с одинаковыми именами. Я не могу переименовать ни один из них, но я надеюсь, что есть способ построить их так, чтобы компоновщик не жаловался. Каждый из методов, на которые он жалуется, вызывается классами внутри объекта. Что я могу сделать?


person CptanPanic    schedule 14.07.2010    source источник


Ответы (1)


Если у вас есть полный набор инструментов GNU, вы сможете обойти свою проблему, используя objcopy, например так (если я правильно понял вашу проблему):

Вот два очень похожих объекта, "foo" и "bar", оба из которых экспортируют символ с именем clash, который используется внутри, но его вообще не нужно экспортировать:

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

а также

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

А вот основной код, который хочет использовать оба:

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

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

Связывание их вместе не работает:

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

Итак, используйте objcopy, чтобы изменить видимость clash в одном (или обоих, если хотите!) объектах:

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

Теперь вы можете успешно связать измененный объект, и программа ведет себя так, как должна:

$ gcc -o test main.o foo.o bar2.o
$ ./test
foo: Hello
bar: world
$ 
person Matthew Slattery    schedule 14.07.2010
comment
Как я могу указать локальный, прежде чем он получит форму объекта? В идеале в коде, но может быть и как часть компиляции объекта? - person CptanPanic; 19.07.2010
comment
Если функция коллизий используется только в одном файле, ее вообще не нужно экспортировать, поэтому сделать ее static должно работать. Это будет работать с моим тривиальным примером выше. (Я предположил, что вы не можете изменить первоначальный источник и вместо этого должны работать с объектами, когда вы сказали, что не можете переименовывать вещи.) Если вам нужно нужны эти символы, экспортированные для ссылок между объектами на более ранней стадии связывания (например, при связывании частичного объекта или библиотеки) все будет сложнее, и разобраться в этом будет зависеть от более тонких деталей процесса сборки. - person Matthew Slattery; 20.07.2010