2017-02-12 74 views
-1

我正在使用Apple LLVM版本8.0.0(clang-800.0.42.1)進行編譯。它大約有1200個文件,但我之前使用過它們。我去編譯它們,沒有問題。然後我製作我的靜態庫(ar rcs libblib.a *.o),沒問題。所以當我嘗試使用我的全新庫時,我遇到了我的問題。靜態庫鏈接問題定義符號的「未定義符號」

gcc main.c -L. -lblib 
Undefined symbols for architecture x86_64: 
    "_N_method", referenced from: 
     _main in main-7fc584.o 
ld: symbol(s) not found for architecture x86_64 

但是,我知道這是定義。我檢查是否包含該文件(ar -t libblib.a | grep N_METHOD.o),它在那裏。檢查源文件,並且有方法,正如它在頭文件中一樣命名。我在這裏有什麼問題?我完全失去了,我希望我錯過了一些簡單的事情。

我做nm -g N_METHOD.o和回來:

0000000000000000 T __Z8N_methodP6stacks 
+1

庫是用C還是C++編寫的?如果它是C++,名稱將會被破壞。 – Barmar

+0

@Barmar:C不支持_methods_,奧卡姆的剃刀告訴我這是C++ ;-) – Olaf

+0

這是C.我只是使用N_method作爲佔位符。 – Red

回答

0

轉移註釋到一個答案。

根據提問內容,我問:

  • 你檢查這N_METHOD.o是一個64位的目標文件(或32位和64位代碼中的脂肪對象文件在裏面)?如果它是一個32位的目標文件,那麼它對64位程序沒有用處。但是,這是不太可能的;你不得不在Mac上創建一個32位的目標文件。

  • 你運行nm -g N_METHOD.o看是否在目標文件中定義了_N_method

我做nm -g N_METHOD.o和回來:

0000000000000000 T __Z8N_methodP6stacks 

不要編譯C代碼用C++編譯器。或者不要嘗試用C編譯器編譯C++代碼。損壞的名稱(__Z8N_methodP6stacks)適用於C++。也許你只需要鏈接g++而不是gcc?它們是不同的語言 - 這是「類型安全連鎖」的屬性,該屬性是特性的C++和完全未知到C.

第一步 - 編譯和鏈接以:假設源

g++ main.c -L. -lblib 

是在C(或C++的C子集)的C++子集中,那麼這個機會應該是可行的。至少,如果代碼包含N_Method(&xyz),其中xyzstacks類型的變量,則有可能會調用__Z8N_methodP6stacks

以下代碼:

typedef struct stacks stacks; 
extern int N_method(stacks*); 

extern int relay(stacks *r); 

int relay(stacks *r) { return N_method(r); } 

用C++編譯器編譯以產生nm -g輸出:

0000000000000000 T __Z5relayP6stacks 
       U __Z8N_methodP6stacks 

它還帶有C編譯器編譯以產生nm -g輸出:

0000000000000038 s EH_frame1 
       U _N_method 
0000000000000000 T _relay