Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I fix undefined reference to _imp__*?

Tags:

c

gcc

mingw

dll

I'm trying to compile something that depends on gtkspell, which depends on enchant, under MinGW. I'm getting errors like gtkspell/gtkspell.c:757: undefined reference to '_imp__enchant_broker_init' I suspect this is either due to the fact that I'm trying to link againt a {static,dynamic} library when I should be linking against the other one, or because there's only one underscore before the imp and there should be two; I get

$ 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

and

$ 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

The internet (http://lists.freedesktop.org/archives/gstreamer-devel/2007-January/013975.html) suggests that the imp mangling comes from

_declspec(dll{import,export})

though enchant seems to use

__declspec(dll{import,export})

, and commenting out the relevant lines in enchant.h makes gtkspell.c request enchant_broker_init rather than _imp__enchant_broker_init, but doesn't change the symbols that show up in libenchant. Is there a way to make gcc not mangle the names, or does anyone have ideas about what might be going wrong/how to fix it?

Here's a minimal example that reproduces the problem on my system:

If I have a file enchanttest1.c with contents

#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;
}

and a file enchanttest2.c with contents

#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;
}

then

gcc enchanttest1.c `pkg-config --cflags enchant` && ./a.exe

gives Enchant found but

gcc enchanttest2.c `pkg-config --cflags enchant` && ./a.exe

gives

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
like image 771
Jason Gross Avatar asked Apr 07 '12 23:04

Jason Gross


1 Answers

The way to fix my minimal example is to add --libs after --cflags; gcc couldn't find the library to link against.

I was able to fix the problem that I was running in to with the more complicated code that I was originally trying to compile (gummi (https://gummi.app/)) by passing LDFLAGS="$(pkg-config --cflags --libs gtkspell-2.0 enchant)" CFLAGS="$(pkg-config --cflags --libs gtkspell-2.0 enchant)" to the configure script; the problem seems to have been that the arguments to gcc were passed in the wrong order, and it couldn't find enchant when it was trying to link gtkspell.

like image 102
Jason Gross Avatar answered Nov 16 '22 03:11

Jason Gross