[英]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)
,其中xyz
是stacks
类型的变量,那么它就有可能调用__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.