5
我使用的是具有gcc 2.95.3的舊系統,我必須鏈接兩個對象,儘管它們之間沒有任何關係,但它們每個都有類似命名的方法。我不能重命名其中的任何一個,但我希望有一種方法可以構建它們,以免連接器發生抱怨。它所抱怨的方法都是由對象內部的類在內部調用的。我能做什麼?如何解決與gcc鏈接的「多個已定義符號」
我使用的是具有gcc 2.95.3的舊系統,我必須鏈接兩個對象,儘管它們之間沒有任何關係,但它們每個都有類似命名的方法。我不能重命名其中的任何一個,但我希望有一種方法可以構建它們,以免連接器發生抱怨。它所抱怨的方法都是由對象內部的類在內部調用的。我能做什麼?如何解決與gcc鏈接的「多個已定義符號」
如果你有一個完整的GNU工具鏈,你應該能夠解決使用objcopy
,這樣你的問題(如果我理解正確的話您的問題):
這裏有兩個非常相似的對象,「富「和‘酒吧’,這兩個出口一個名爲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
$
如何在指定本地對象之前指定對象?在代碼理想情況下,也可能作爲對象編譯的一部分? – CptanPanic 2010-07-19 14:55:09
如果碰撞函數僅用於單個文件中,則根本不需要導出它,因此使其成爲「靜態」應該可以工作。這將與我上面的小例子一起工作。 (我認爲你不能改變原始源代碼,而需要使用對象來處理,而當你說你不能重命名的時候)。如果你需要在早期的鏈接階段爲對象之間的引用導出這些符號(例如,鏈接部分對象或庫),那麼事情就會變得更加困難,並且將其排序取決於構建過程的更精細的細節。 – 2010-07-19 20:02:32