Подключение статических библиотек в MinGW

Итак, некоторая есть статическая библиотека - в данном случае libantlr4-runtime.a. Я пытаюсь подключить её к своему проекту в CodeBlocks. И вот тут возникла нечаянность, с которой я никак не могу справиться. Сама библиотека выглядит вполне ординарно. Содержит внутри себя функции - например, такую

__ZN6antlr416ANTLRInputStreamC1ERSi

Эта функция вызывается в одном из файлов проекта, подключающего обсуждаемую библиотеку. Вызывается следующим образом:

ANTLRInputStream input(in);

то есть эта функция - конструктор объекта ANTLRInputStream. И вот при компиляции проекта валом валят такого рода ошибки:

C:\CodeBlocksProjects\ElectronicSheetFrontend\FormulaAST.cpp|440|undefined reference to `_imp___ZN6antlr416ANTLRInputStreamC1ERSi'

То есть компилятор в месте вызова упомянутой функции пытается вместо неё вызвать другую: _imp___ZN6antlr416ANTLRInputStreamC1ERSi.

То есть на самом деле как раз ту самую, нужную функцию, но только её имя почему-то отличается от правильного оригинала добавлением к нему префикса imp. И так происходит со всеми вызовами функций этой библиотеки (там их около сотни, здесь приведена только одна). Почему-то при создании библиотеки и при вызове функций меняются правила декорировки C++-имён и при вызове компилятор зачем-то добавляет к именам эту приставку imp_. Что же это такое и как с этим бороться?


Ответы (1 шт):

Автор решения: HolyBlackCat

Разобрался. Объясняю ход мыслей:

  • Ищем, где объявлен ANTLRInputStream. У меня это /mingw64/include/antlr4-runtime/ANTLRInputStream.h.

  • Конструкторы выглядят так:

    ANTLRInputStream(const std::string &input);
    ANTLRInputStream(const char *data, size_t length);
    ANTLRInputStream(std::istream &stream);
    

    Пока ничего необычного.

  • Сам класс объявлен так: class ANTLR4CPP_PUBLIC ANTLRInputStream. Это уже интереснее.

  • Ищем, что такое ANTLR4CPP_PUBLIC. Находим /mingw64/include/antlr4-runtime/antlr4-common.h и в нем вот это:

    #ifdef ANTLR4CPP_EXPORTS
      #define ANTLR4CPP_PUBLIC __declspec(dllexport)
    #else
      #ifdef ANTLR4CPP_STATIC
        #define ANTLR4CPP_PUBLIC
      #else
        #define ANTLR4CPP_PUBLIC __declspec(dllimport)
      #endif
    #endif
    
  • ANTLR4CPP_STATIC звучит многообещающе. Добавляем флаг -DANTLR4CPP_STATIC, чтобы задефайнить его. (В дополнение к -static.)

  • Все работает.

→ Ссылка