我有一个问题,即g ++构建一个链接到静态库的应用程序,后者应该包含一些用外部asm文件编写的全局函数,用yasm编译。所以在图书馆,我有
#ifdef __cplusplus
extern "C" {
#endif
extern void __attribute__((cdecl)) interp1( char *pSrc );
extern void __attribute__((cdecl)) interp2( char *pSrc );
#ifdef __cplusplus
}
#endif
我在图书馆的其他地方引用。然后,在asm文件中有实现,如下所示:
section .data
; (some data)
section .text
; (some text)
global _interp1
_interp1:
; (code ...)
ret
global _interp2
_interp2:
; (code ...)
ret
编译和链接工作正常,我做
yasm -f elf32 -O2 -o interp.o interp.asm
然后
ar -rc libInterp.a objs1.o [...] objsN.o interp.o
ranlib libInterp.a
现在最后,为了将库链接到主应用程序,我做
g++ -O4 -ffast-math -DNDEBUG -fomit-frame-pointer -DARCH_X86 -fPIC -o ../bin/interp this.o that.o -lboost_thread -lpthread ./libInterp.a
我得到了错误
undefined reference to `interp1'
undefined reference to `interp2'
我在这里做错了什么?任何帮助表示赞赏。
答案 0 :(得分:2)
根据目标类型,gcc不会在前面的下划线前加上外部符号。您的方案中似乎就是这种情况。
简单修复可能是从程序集文件中的名称中删除下划线。
您可能需要考虑的几个替代方法可能是在汇编文件中为符号使用以下某个宏之一:
; sym()
; Return the proper symbol name for the target ABI.
;
; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols
; with C linkage be prefixed with an underscore.
;
%ifidn __OUTPUT_FORMAT__,elf32
%define sym(x) x
%elifidn __OUTPUT_FORMAT__,elf64
%define sym(x) x
%elifidn __OUTPUT_FORMAT__,x64
%define sym(x) x
%else
%define sym(x) _ %+ x
%endif
%macro public_c_symbol 1
GLOBAL %1,_%1
%1:
_%1:
%endmacro
public_c_symbol my_external_proc:
; ...
RET