静态库链接问题"未定义的符号"对于已定义的符号

时间:2017-02-12 06:00:44

标签: c++ c gcc linker static-libraries

我正在使用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 个答案:

答案 0 :(得分: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