【发布时间】:2012-04-07 23:28:14
【问题描述】:
我正在尝试编译一些依赖于 gtkspell 的东西,它
取决于附魔,在MinGW下。我收到类似的错误
gtkspell/gtkspell.c:757: undefined reference to '_imp__enchant_broker_init'
我怀疑这是因为我正在尝试链接
当我应该链接到 {static,dynamic} 库时
另一个,或者因为在 imp 和之前只有一个下划线
应该有两个;我明白了
$ objdump -t /d/opt/enchant-1.6.0/lib/libenchant.a | grep enchant_broker_init
[ 85](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00002ac0 _enchant_broker_init
和
$ objdump -t /d/opt/enchant-1.6.0/lib/libenchant.dll.a | grep enchant_broker_init
[ 6](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _enchant_broker_init
[ 7](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp__enchant_broker_init
互联网 (http://lists.freedesktop.org/archives/gstreamer-devel/2007-January/013975.html) 表明imp mangling来自
_declspec(dll{import,export})
虽然附魔似乎有用
__declspec(dll{import,export})
,并注释掉 enchant.h 中的相关行使 gtkspell.c
请求enchant_broker_init 而不是_imp__enchant_broker_init,但是
不会更改 libenchant 中显示的符号。有没有办法
让 gcc 不破坏名称,或者有没有人知道什么
可能会出错/如何解决?
这是一个在我的系统上重现问题的最小示例:
如果我有一个包含内容的文件 enchanttest1.c
#include <stdio.h>
#include <enchant.h>
int main()
{
#ifdef ENCHANT_MODULE_EXPORT
printf("\nEnchant found\n");
#else
printf("\nEnchant not found\n");
#endif
return 0;
}
还有一个带有内容的文件 enchanttest2.c
#include <stdio.h>
#include <enchant.h>
int main()
{
EnchantBroker *b = enchant_broker_init();
#ifdef ENCHANT_MODULE_EXPORT
printf("\nEnchant found\n");
#else
printf("\nEnchant not found\n");
#endif
return 0;
}
然后
gcc enchanttest1.c `pkg-config --cflags enchant` && ./a.exe
给出Enchant found 但是
gcc enchanttest2.c `pkg-config --cflags enchant` && ./a.exe
给予
C:\Users\JASONG~1\AppData\Local\Temp\ccyDLptc.o:testenchant.c:(.text+0xf): undefined reference to `_imp__enchant_broker_init'
collect2: ld returned 1 exit status
【问题讨论】:
-
这是一个愚蠢的建议,但您确定要调用 C(不是 C++)编译吗?您可能正在经历微妙的名字修饰荒谬?
-
enchant.h文件将所有内容都包含在#ifdef __cplusplus extern "C" { #endif中,所以我认为这不是问题所在。我还添加了一个最小的示例,我很确定我正在调用 C 编译。 -
作为关注者的说明,当我得到这个时,这是因为“依赖库”是用 __declspec(dllimport) 定义的,即使它是一个静态编译。所以删除它修复了它,请参阅betterlogic.com/roger/2012/09/libflite-cross-compile-woe