静态库链接问题定义符号的“未定义符号”
我正在使用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
转移注释到一个答案。
根据提问内容,我问:
你检查这
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)
,其中xyz
是stacks
类型的变量,则有可能会调用__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
库是用C还是C++编写的?如果它是C++,名称将会被破坏。 – Barmar
@Barmar:C不支持_methods_,奥卡姆的剃刀告诉我这是C++ ;-) – Olaf
这是C.我只是使用N_method作为占位符。 – Red