Изменить: Нашел решение, но пока не могу принять мой собственный ответ.
У меня проблемы со статическим связыванием библиотеки с моей программой. Я выполняю кросс-компиляцию из Linux в Windows, используя набор инструментов MinGW и Code :: Blocks как систему IDE / Build. Я также сам скомпилировал библиотеку с тем же набором инструментов, что и программа.
Я совершенно новичок в кросс-компиляции и компиляции для Windows.
Edit: я только что попробовал ту же процедуру на виртуальной установке Windows XP (с MinGW в комплекте Code :: Block) и получил ту же проблему, поэтому я думаю, что это не из-за кросс-компилятора.
Проблема
Я приведу все подробности ниже, но, по сути, проблема в том, что компоновщик жалуется на отсутствие символов _imp__some_symbol
. Символы присутствуют в статической библиотеке, но не как _imp__some_symbol
, а просто как _some_symbol
. Я подтвердил это, получив вывод nm libSomeLibrary.a
Подробнее
Сама библиотека - BearLibTerminal (источники можно найти по адресу https://bitbucket.org/cfyzium/bearlibterminal/downloads/).. Как уже говорилось ранее, я сам скомпилировал ее из исходного кода с помощью того же набора инструментов, что и моя основная программа.
Моя основная программа состоит из кода, это пример "Hello world", данный BearLibTerminal здесь http://foo.wyrd.name/en:bearlibterminal#simple_examplec_c:
#include "BearLibTerminal.h"
int main()
{
terminal_open();
// Printing text
terminal_print(1, 1, "Hello, world!");
terminal_refresh();
// Wait until user close the window
while (terminal_read() != TK_CLOSE);
terminal_close();
}
Мой полный журнал сборки Code :: Blocks можно найти по адресу https://pste.eu/p/VMJp.html. Он содержит журнал сборки для BearLibTerminal и его зависимостей, а также мою программу.
Соответствующие биты (я думаю) это:
i686-w64-mingw32-g++ -Wall -fexceptions -O2 -DWINVER=0x0400 -D__WIN95__ -D__GNUWIN32__ -DSTRICT -DHAVE_W32API_H -D__WXMSW__ -D__WINDOWS__ -IBearLibTerminal -I/usr/i686-w64-mingw32/sys-root/mingw/include -I/home/laleksic/Desktop/Roguelike -I/home/laleksic/Desktop/Roguelike/ -c /home/laleksic/Desktop/Roguelike/main.cpp -o /home/laleksic/Desktop/Roguelike/.objs/main.o
i686-w64-mingw32-g++ -L/usr/i686-w64-mingw32/sys-root/mingw/lib -o build/Roguelike /home/laleksic/Desktop/Roguelike/.objs/main.o -s -lstdc++ -lgcc -lodbc32 -lwsock32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lctl3d32 -lodbc32 -ladvapi32 -lodbc32 -lwsock32 -lopengl32 -lglu32 -lole32 -loleaut32 -luuid BearLibTerminal/Dependencies/PicoPNG/libPicoPNG.a BearLibTerminal/Dependencies/FreeType/libFreeType.a BearLibTerminal/libBearLibTerminal.a
/home/laleksic/Desktop/Roguelike/.objs/main.o:main.cpp:(.text.startup+0x11): undefined reference to "_imp__terminal_open'
/home/laleksic/Desktop/Roguelike/.objs/main.o:main.cpp:(.text.startup+0x56): undefined reference to "_imp__terminal_print_ext8'
/home/laleksic/Desktop/Roguelike/.objs/main.o:main.cpp:(.text.startup+0x5c): undefined reference to "_imp__terminal_refresh'
/home/laleksic/Desktop/Roguelike/.objs/main.o:main.cpp:(.text.startup+0x62): undefined reference to "_imp__terminal_read'
/home/laleksic/Desktop/Roguelike/.objs/main.o:main.cpp:(.text.startup+0x7b): undefined reference to "_imp__terminal_close'
collect2: error: ld returned 1 exit status
В конце линии связи вы видите, что она должна статически связывать зависимости BearLibTerminal (libPicoPNG.a
и libFreeType.a
) и сам BearLibTerminal (libBearLibTerminal.a
).
Теперь проверка символов libBearLibTerminal.a
с помощью nm libBearLibTerminal.a | grep -E ' _imp__terminal_(open|print_ext8|refresh|read|close)'
дает пустой вывод.
Однако nm libBearLibTerminal.a | grep -E 'terminal_(open|print_ext8|refresh|read|close)'
дает:
00000000 t __GLOBAL__sub_I_terminal_open
00000690 T _terminal_close
000032b0 T _terminal_open
000015b0 T _terminal_print_ext8
000024c0 T _terminal_read
00003240 T _terminal_read_str16
000031f0 T _terminal_read_str32
000031a0 T _terminal_read_str8
00000cd0 T _terminal_refresh
U _terminal_close
U _terminal_open
U _terminal_print_ext8
U _terminal_read
U _terminal_read_str8
U _terminal_refresh
00000220 T __Z16luaterminal_openP9lua_State
000010f0 T __Z16luaterminal_readP9lua_State
00000250 T __Z17luaterminal_closeP9lua_State
000002b0 T __Z19luaterminal_refreshP9lua_State
00001410 T __Z20luaterminal_read_strP9lua_State
Итак, символы есть, просто с другим префиксом.
В чем причина этого и как можно это исправить?
Toolchain * +1051 *
Я компилирую в системе Fedora 28 с помощью набора инструментов MinGW и Code :: Blocks как системы IDE / Build (все они установлены из официальных репозиториев Fedora). Если уместно, вот некоторая информация о версии для этих инструментов.
Выход i686-w64-mingw32-g++ -v
:
Using built-in specs.
COLLECT_GCC=i686-w64-mingw32-g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-w64-mingw32/7.3.0/lto-wrapper
Target: i686-w64-mingw32
Configured with: ../configure --prefix=/usr --bindir=/usr/bin --includedir=/usr/include --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --with-gnu-as --with-gnu-ld --verbose --without-newlib --disable-multilib --disable-plugin --with-system-zlib --disable-nls --without-included-gettext --disable-win32-registry --enable-languages=c,c++,objc,obj-c++,fortran --with-bugurl=http://bugzilla.redhat.com/bugzilla --with-cloog --enable-threads=posix --enable-libgomp --target=i686-w64-mingw32 --with-sysroot=/usr/i686-w64-mingw32/sys-root --with-gxx-include-dir=/usr/i686-w64-mingw32/sys-root/mingw/include/c++
Thread model: posix
gcc version 7.3.0 20180125 (Fedora MinGW 7.3.0-1.fc28) (GCC)
Редактировать: Дополнительно, я настроил Code :: Blocks для работы с кросс-компилятором, используя слегка измененные инструкции отсюда http://wiki.codeblocks.org/index.php/Code::Blocks_and_Cross_Compilers