1
我想創建一個靜態庫,並將其鏈接在MacOS X(幾個版本): 文件foo.c
:找不到符號時,靜態鏈接MacOSX上
char foo[111];
文件bar.c
:
#include <string.h>
extern char foo[];
int bar(char *src) {
strcpy(foo, src);
return strlen(foo);
}
創建庫:
$ cc -c foo.c bar.c
$ ar r libfoobar.a foo.o bar.o
ar: creating archive libfoobar.a
$ ranlib libfoobar.a
$ nm libfoobar.a
libfoobar.a(foo.o):
000000000000006f C _foo
libfoobar.a(bar.o):
U ___strcpy_chk
0000000000000000 T _bar
U _foo
U _strlen
創建一個小測試程序上午:
文件main.c
:
#include <stdio.h>
int bar(char *);
int main(void) {
printf("foobarbar = %i\n", bar("123"));
return 0;
}
編譯和鏈接:
$ cc -c main.c
$ cc -o m main.o -L. -lfoobar
Undefined symbols for architecture x86_64:
"_foo", referenced from:
_bar in libfoobar.a(bar.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
爲什麼沒有找到符號?它在foo.c
中定義?至少ranlib
是否應該在庫中創建一個允許隨機排序文件的索引?
相同的代碼在Linux(gcc)下運行良好,並且foo.c
中的符號不是char數組,而是int。
對我來說,這聽起來並不是無意的:如果沒有鏈接定義符號的庫成員 - 即使它在那裏未初始化 - ,那麼該符號仍然未定義並導致鏈接器錯誤。這背後的理由是什麼?爲什麼MacOS和Linux(GNU binutils)有所不同? – olebole
我不能說什麼是理由,不幸的是,不知道爲什麼是不同的。我也對你的示例代碼感到驚訝,並且只是做了一個關於如何讓它工作的研究。 –
我們的好奇心,爲什麼不用一個普通的'foo.h'和普通的'extern char foo [];'在裏面呢?這僅僅是爲了這個問題的範圍,還是你寫這樣的產品代碼? –