2017-02-12 250 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