简体   繁体   English

已定义符号的静态库链接问题“未定义符号”

[英]Static Library Linking Issue "Undefined symbols" for symbols that are defined

I am using Apple LLVM version 8.0.0 (clang-800.0.42.1) to compile.我正在使用 Apple LLVM 版本 8.0.0 (clang-800.0.42.1) 进行编译。 It's about 1200 files, but I have used them before.大约有 1200 个文件,但我以前使用过它们。 I go and compile them all, no problems.我去编译它们,没有问题。 Then I make my static library ( ar rcs libblib.a *.o ), no problems.然后我制作我的静态库( ar rcs libblib.a *.o ),没问题。 So when I try to use my brand new library, I have my problem.因此,当我尝试使用全新的库时,我遇到了问题。

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

But, I know this is defined.但是,我知道这是定义的。 I check to see that the file is included ( ar -t libblib.a | grep N_METHOD.o ) and it is in there.我检查是否包含该文件( ar -t libblib.a | grep N_METHOD.o )并且它在那里。 Check the source file, and there is the method, exactly named as it is in the header file.检查源文件,有方法,与头文件中的名称完全相同。 What is the problem I am having here?我在这里遇到了什么问题? I am at a complete loss and I am hoping I am missing something simple.我完全不知所措,我希望我错过了一些简单的东西。

I did nm -g N_METHOD.o and got back:我做了nm -g N_METHOD.o并回来了:

0000000000000000 T __Z8N_methodP6stacks

Transferring comments into an answer.将评论转换为答案。

Based on the question content, I asked:根据问题内容,​​我问:

  • Have you checked that N_METHOD.o is a 64-bit object file (or a fat object file with both 32-bit and 64-bit code in it)?你有没有检查过N_METHOD.o是一个 64 位的目标文件(或者一个包含 32 位和 64 位代码的胖目标文件)? If it is a 32-bit object file, then it is no use for a 64-bit program.如果它是一个 32 位的目标文件,那么它对于 64 位的程序是没有用的。 However, that's a little unlikely;然而,这有点不太可能。 you have to go out of your way to create a 32-bit object file on Mac.您必须竭尽全力在 Mac 上创建 32 位目标文件。

  • Have you run nm -g N_METHOD.o to see whether _N_method is defined in the object file?您是否运行nm -g N_METHOD.o以查看_N_method是否在目标文件中定义?

I did nm -g N_METHOD.o and got back:我做了nm -g N_METHOD.o并回来了:

 0000000000000000 T __Z8N_methodP6stacks

Don't compile C code with a C++ compiler.不要使用 C++ 编译器编译 C 代码。 Or don't try to compile C++ code with a C compiler.或者不要尝试使用 C 编译器编译 C++ 代码。 The mangled name ( __Z8N_methodP6stacks ) is for C++.损坏的名称 ( __Z8N_methodP6stacks ) 用于 C++。 Maybe you simply need to link with g++ instead of gcc ?也许您只需要链接g++而不是gcc They are different languages — this is the property of 'type-safe linkage' that is characteristic of C++ and completely unknown to C.它们是不同的语言——这是“类型安全链接”的特性,它是 C++ 的特征,而 C 完全不知道。

First step — compile and link with:第一步 - 编译并链接:

g++ main.c -L. -lblib

Assuming that the source is in the C++ subset of C (or C subset of C++), then the chances are that should work.假设源代码在 C 的 C++ 子集(或 C++ 的 C 子集)中,那么应该可行。 At least, if the code contains N_Method(&xyz) where xyz is a variable of type stacks , then there's a chance it will call __Z8N_methodP6stacks .至少,如果代码包含N_Method(&xyz) ,其中xyzstacks类型的变量,那么它就有可能调用__Z8N_methodP6stacks

The following code:以下代码:

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

extern int relay(stacks *r);

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

compiles with a C++ compiler to produce the nm -g output:使用 C++ 编译器编译以生成nm -g输出:

0000000000000000 T __Z5relayP6stacks
                 U __Z8N_methodP6stacks

It also compiles with a C compiler to produce the nm -g output:它还使用 C 编译器进行编译以生成nm -g输出:

0000000000000038 s EH_frame1
                 U _N_method
0000000000000000 T _relay

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM