我正在使用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
答案 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)
,其中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