cgccdllmingw

How do I fix undefined reference to _imp__*?


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

Solution

  • The way to fix my minimal example is to add --libs after --cflags for pkg-config; 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.