11

Вопрос по mingw, dll, gcc, c – Как исправить неопределенную ссылку на _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' Я подозреваю, что это либо из-за того, что я пытаюсь связать againt {статическая, динамическая} библиотека, когда я должен связываться с другой, или потому что перед чертенком есть только одно подчеркивание и должно быть два; я получил

$ 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) предполагает, что чертёж

_declspec(dll{import,export})

хотя Enchant, кажется, использует

__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
  • enchant.h файл оборачивает все в#ifdef __cplusplus extern "C" { #endif  так что я не думаю, что это проблема. С тех пор я также добавил минимальный пример, в котором я почти уверен, что вызываю компиляцию Си.

    от Jason Gross
  • Как примечание для подписчиков, когда я получил это, это было потому, что & quot; библиотека зависимостей & quot; был определен с __declspec (dllimport), даже если это была статическая компиляция. Так что сняв это исправил, посмотриbetterlogic.com/roger/2012/09/libflite-cross-compile-woe

    от rogerdpack
  • Это глупое предложение, но вы уверены, что вызываете компиляцию C (не C ++)? Возможно, вы испытываете нелепое смешное имя?

    от std''OrgnlDave
  • 7

    Чтобы исправить мой минимальный пример, нужно добавить

    --libs после--cflags; gcc не может найти библиотеку для ссылки.

    Мне удалось решить проблему, с которой я работал, с помощью более сложного кода, который я изначально пытался скомпилировать (gummi (http://dev.midnightcoding.org/projects/gummi)), передавLDFLAGS="$(pkg-config --cflags --libs gtkspell-2.0 enchant)" CFLAGS="$(pkg-config --cflags --libs gtkspell-2.0 enchant)" настроить скрипт; похоже, проблема заключалась в том, что аргументы gcc были переданы в неправильном порядке, и он не мог найти enchant, когда пытался связать gtkspell.