2017-06-03 80 views
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。

回答

0

有一個類似的問題:Object files not properly added to archive on mac具有this answer

Option 1: 

ar -rs my_archive.a foo.o bar.o other_object_files.o 
ranlib -c my_archive.a 

Option 2: 

libtool -c -static -o my_archive.a foo.o bar.o other_object_files.o 

這是-c標誌,使分別在ranliblibtool這兩個選項的差異:

-c

包含常用符號作爲關於表 的定義內容。這很少是從庫中鏈接 的預期行爲,因爲它強制鏈接庫成員 僅僅是因爲它在鏈接中使用未定義的 未初始化的全局鏈接。此選項僅包含 ,因爲這是ranlib的原始行爲。此選項 不是默認值。

+0

對我來說,這聽起來並不是無意的:如果沒有鏈接定義符號的庫成員 - 即使它在那裏未初始化 - ,那麼該符號仍然未定義並導致鏈接器錯誤。這背後的理由是什麼?爲什麼MacOS和Linux(GNU binutils)有所不同? – olebole

+0

我不能說什麼是理由,不幸的是,不知道爲什麼是不同的。我也對你的示例代碼感到驚訝,並且只是做了一個關於如何讓它工作的研究。 –

+0

我們的好奇心,爲什麼不用一個普通的'foo.h'和普通的'extern char foo [];'在裏面呢?這僅僅是爲了這個問題的範圍,還是你寫這樣的產品代碼? –