LINUX.ORG.RU

Как собрать FreeImage.DLL с помощью MinGW под Linux (HOWTO)


0

1

Вот как собирать под Линуксом FreeImage из исходников:

$ unzip ~/Downloads/FreeImage3151.zip
$ cd FreeImage/
$ make -f Makefile.mingw
make: dlltool: Команда не найдена
make: *** [FreeImage.exp] Ошибка 127
# используются стандартные пути к программам компиляции, поэтому заменяем имена gcc -> i586-mingw32msvc-gcc и т.п.
$ make -f Makefile.mingw clean
$ make -f Makefile.mingw
....
cp FreeImage.dll Dist/FreeImage.dll
cp FreeImage.lib Dist/FreeImage.lib
cp Source/FreeImage.h Dist/FreeImage.h
(собралось)
Корректируем FreeImage.dll:

$ wine pexports.exe FreeImage.dll > FreeImage.def
$ cat FreeImage.def | sed 's/^_//g' > FreeImage-new.def
$ i586-mingw32msvc-dlltool --input-def FreeImage.def --output-lib libfreeimage.a
(теперь libfreeimage.a можно собирать с любыми проектами для MinGW на платформе Win32)
Аналогично компилируем FreeImagePlus:

$ cd Wrapper/FreeImagePlus/src/
$ ls -1 *.cpp | xargs -n1 -I{} i586-mingw32msvc-g++ -c -o {}.obj {} -I.. -I ../../../Source
$ ls -1 *.obj | wc -l
7
$ i586-mingw32msvc-g++ -shared -o FreeImagePlus.dll *.obj -Wl,--out-implib,libfreeimageplus.a -L. -lfreeimage
....

fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x7b4): undefined reference to `_BitBlt@36'
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x81a): undefined reference to `_SelectObject@8'
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x826): undefined reference to `_DeleteObject@4'
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x834): undefined reference to `_DeleteDC@4'
....
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x120c): undefined reference to `__imp___ZN8fipImageC2E15FREE_IMAGE_TYPEjjj'
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x1216): undefined reference to `__imp___ZTV11fipWinImage'
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x12a8): undefined reference to `__imp___ZN8fipImageC2E15FREE_IMAGE_TYPEjjj'
fipWinImage.cpp.obj:fipWinImage.cpp:(.text+0x12b2): undefined reference to `__imp___ZTV11fipWinImage'

(libfreeimageplus.a собралось, а вот FreeImagePlus.dll слинковаться не смогло; в принципе, мне этого пока достаточно)


P.S. Под виндой, в среде Visual Studio 2010 Express (C++), не получается открыть и сконвертировать файлы проектов от 2003, 2005 и 2008-й студий - IDE ругается на формат xml-файла проекта. MinGW32 (Dev-Cpp и Code::Blocks) также не собирает по имеющемуся Makefile.mingw (под Windows).
Поэтому собрал под Linux'ом (со второго раза).

Кстати, если кто-то подскажет, как слинковать FreeImagePlus.dll — буду благодарен.

★★★★★

FAIL: собранные таким образом библиотеки - неработоспособны.
То есть, программы с ними линкуются. Получаются .exe.

Но при попытке запуска:

$ wine convert.exe lena.jpg out.png
wine: Call from 0x40142f to unimplemented function FreeImage.dll.FreeImage_Initialise@4, aborting
wine: Unimplemented function FreeImage.dll.FreeImage_Initialise@4 called at address 0x40142f (thread 0009), starting debugger...
Unhandled exception: unimplemented function FreeImage.dll.FreeImage_Initialise@4 called in 32-bit code (0x7bc45c70).
Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:7bc45c70 ESP:0061fd9c EBP:0061fe00 EFLAGS:00000206(   - 00      - -IP1)
 EAX:004111fe EBX:7bc89444 ECX:00000001 EDX:0061fec0
 ESI:0061fda8 EDI:00401130
....
Backtrace:
=>1 0x7bc45c70 in ntdll (+0x35c70) (0x0061fe00)
  2 0x0040142f in convert (+0x142f) (0x0061fea8)
  3 0x004010a7 in convert (+0x10a7) (0x0061fee8)
  4 0x00401143 in convert (+0x1143) (0x0061ff08)
  5 0x7b8783a8 in kernel32 (+0x583a8) (0x0061ffe8)
wine: Call from 0x40142f to unimplemented function FreeImage.dll.FreeImage_Initialise@4, aborting

pacify ★★★★★ ()
Ответ на: комментарий от pacify

Вот как выглядит попытка собрать FreeImage стандартным Makefile под Windows:

C:\w\FreeImage>make.exe -f Makefile.mingw
g++ -O3 -fexceptions -Wno-ctor-dtor-privacy -DNDEBUG -DFREEIMAGE_EXPORTS -DOPJ_STATIC -DLIBRAW_NODLL -DLIBRAW_LIBRARY_BUILD -DNO_LCMS -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibMNG -ISource/LibPNG -ISource/LibTIFF -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -c Source/FreeImage/BitmapAccess.cpp -o Source/FreeImage/BitmapAccess.o
process_begin: CreateProcess((null), g++ -O3 -fexceptions -Wno-ctor-dtor-privacy -DNDEBUG -DFREEIMAGE_EXPORTS -DOPJ_STATIC -DLIBRAW_NODLL -DLIBRAW_LIBRARY_BUILD -DNO_LCMS -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibMNG -ISource/LibPNG -ISource/LibTIFF -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -c Source/FreeImage/BitmapAccess.cpp -o Source/FreeImage/BitmapAccess.o, ...) failed.
make (e=2): Не удается найти указанный файл.^M
C:\w\FreeImage\make.exe: *** [Source/FreeImage/BitmapAccess.o] Error 2

C:\w\FreeImage>make.exe
C:/w/FreeImage/make.EXE -f Makefile.gnu 
make.EXE[1]: Entering directory `C:/w/FreeImage'
g++ -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibMNG -ISource/LibPNG -ISource/LibTIFF -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -c Source/FreeImage/BitmapAccess.cpp -o Source/FreeImage/BitmapAccess.o
make.EXE[1]: Leaving directory `C:/w/FreeImage'
process_begin: CreateProcess((null), uname, ...) failed.
process_begin: CreateProcess((null), uname, ...) failed.
process_begin: CreateProcess((null), uname, ...) failed.
process_begin: CreateProcess((null), uname, ...) failed.
process_begin: CreateProcess((null), sh -c "uname -m 2>/dev/null || echo not", ...) failed.
process_begin: CreateProcess((null), g++ -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibMNG -ISource/LibPNG -ISource/LibTIFF -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -c Source/FreeImage/BitmapAccess.cpp -o Source/FreeImage/BitmapAccess.o, ...) failed.
make (e=2): Не удается найти указанный файл.^M
make.EXE[1]: *** [Source/FreeImage/BitmapAccess.o] Error 2
process_begin: CreateProcess((null), uname, ...) failed.
C:\w\FreeImage\make.EXE: *** [default] Error 2
Видно, что не хватает утилиты uname.exe. Если немного пропатчить Makefile.mingw, то по команде make сборка запускается. Но заканчивается такими сообщениями:

# with patched Makefile.mingw:
....
C:\w\FreeImage>make -f Makefile.mingw
C:\Dev-Cpp\bin\gcc -O3 -fexceptions -DNDEBUG -DFREEIMAGE_LIB -DOPJ_STATIC -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibMNG -ISource/LibPNG -ISource/LibTIFF -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -c Source/LibOpenJPEG/bio.c -o Source/LibOpenJPEG/bio.o
In file included from Source/LibOpenJPEG/opj_includes.h:108,
                 from Source/LibOpenJPEG/bio.c:32:
Source/LibOpenJPEG/opj_malloc.h:75:25: mm_malloc.h: No such file or directory
C:\w\FreeImage\make.EXE: *** [Source/LibOpenJPEG/bio.o] Error 1
Перебираемся на Code::Blocks (версии 10.05, ревизия 6283), и пытаемся закончить сборку. Но среда выдает следующее:

"C:\Program Files\CodeBlocks\MinGW\bin\ar" rs FreeImage.a ./Source/FreeImage/BitmapAccess.o ./Source/FreeImage/ColorLookup.o ./Source/FreeImage/FreeImage.o ./Source/FreeImage/FreeImageC.o ./Source/FreeImage/FreeImageIO.o 
.... Source/LibRawLite/./src/libraw_c_api.o Source/LibRawLite/./src/libraw_cxx.o 
Слишком длинная входная строка.
C:\w\FreeImage\make.EXE: *** [FreeImage.a] Error 255
Спасибо модераторам, прочитавщим этот текст до конца. Не удаляйте, пожалуйста, сейчас закончу.

Dev-Cpp версии 4.9.9.2
Code::Blocks версии 10.05, ревизия 6283
FreeImage 3.15.1

Итак,

Собранные под Windows объектники .o - линкуем под Linux (так как командная строка Windows не воспринимает такие длинные строки, см. выше):

$ i586-mingw32msvc-ar rs libfreeimage.a `cat link.txt | sed "s/\n/ /g"
$ ls -l *.a
-rw-r--r-- 1 pacify pacify 5138596 Окт 13 14:47 libfreeimage.a

Собрать под Windows файл FreeImage.DLL (комментируем одну строчку в makefile.mingw) также не получается - командная строка DOS/Windows не может обрабатывать такие длинные строки. Собираем под Linux тем же методом:

$ i586-mingw32msvc-dlltool -e FreeImage.exp -l FreeImage.lib -D FreeImage.dll --add-stdcall-underscore `cat link.txt | sed "s/\n/ /g"`
$ ls -l FreeImage.*
-rw-r--r-- 1 pacify pacify    7476 Дек  6  2010 FreeImage.2003.sln
-rw-r--r-- 1 pacify pacify   13306 Мар 26  2011 FreeImage.2003.vcproj
-rw-r--r-- 1 pacify pacify   10464 Авг 11  2010 FreeImage.2005.sln
-rw-r--r-- 1 pacify pacify   19966 Мар 26  2011 FreeImage.2005.vcproj
-rw-r--r-- 1 pacify pacify   11168 Фев  2  2010 FreeImage.2008.sln
-rw-r--r-- 1 pacify pacify   20066 Июл 14 17:27 FreeImage.2008.vcproj
-rw-r--r-- 1 pacify pacify    1536 Окт 13 11:05 FreeImage.coff
-rwxr-xr-x 1 pacify pacify 4020736 Окт 13 11:05 FreeImage.dll
-rw-r--r-- 1 pacify pacify   29619 Окт 13 14:57 FreeImage.exp
-rw-r--r-- 1 pacify pacify  188554 Окт 13 14:57 FreeImage.lib
-rw-r--r-- 1 pacify pacify    2549 Фев 13  2011 FreeImage.rc
(файл link.txt содержит имена .o-файлов, которые надо слинковать)

dll+lib+a получили, почти без «хакинга» ... но они к программе в среде MinGW не подлинковываются.
Microsoft Visual C++ также пишет: «fatal error LNK 1107: недопустимый или поврежденный файл: не удается прочитать по 0x2B8»

Короче, как сделать FreeImage.DLL юзабельной? Вопрос остается открытым.
Я так понял - без разницы, в какой среде ее собирать - под Linux, или под Windows. Под Linux компиляция проходит без проблем, также - под Linux нативная freeimage.a/.so поставляется «из коробки». Но при попытке переноса проекта под Win32 — возникают вышеописанные проблемы. Я сомневаюсь, что на rsdn.ru/sql.ru ответят на этот вопрос. Поэтому спрашиваю здесь.

pacify ★★★★★ ()

Всё, проблему решил. Алгоритм сборки работающей FreeImage.dll в целом ясен из вышенаписанного. :)
Но последний шаг (исправление external symbols с помощью pexports,dlltool,sed) под CodeBlocks 10.05 не получается - видать, там dlltool кривой. Создается libfreeimage.a с нулевой длиной.
Надо использовать dlltool из Dev-Cpp 4.9.9.2, при этом создается ненулевой libfreeimage.a, который и используется при сборке программы, использующей FreeImage.DLL.
Последние необходимые команды (см. README.minGW):

>pexports.exe FreeImage.dll | sed.exe "s/^_//" > FreeImage_gcc.def
>dlltool.exe -U -d FreeImage_gcc.def -l libfreeimage.a
Сборка собственно программы идёт так:

"C:\Program Files\CodeBlocks\MinGW\bin\gcc.exe" -Wall -I. -c -o scale.obj scale.c
"C:\Program Files\CodeBlocks\MinGW\bin\gcc.exe" -o scale.exe scale.obj -L. -lfreeimage
Спасибо французам за корректную команду на сайте: http://www.clubic.com/forum/programmation/codeblocks-et-freeimage-id533058-pa...
Без попытки сделать также я бы не догадался, наверное, полезть за dlltool.exe в Dev-Cpp.
P.S. FreeImage.DLL можно брать стандартный, с сайта: http://freeimage.sourceforge.net/download.html
http://downloads.sourceforge.net/freeimage/FreeImage3151Win32.zip
Собственно, роль Линукс сводится к линковке библиотек (если захотите собирать все «с нуля»). После этого можно делать .a.

pacify ★★★★★ ()
Ответ на: комментарий от pacify

> C:\w\FreeImage>make.exe

Чё за make? Если от MSYS, то надо использовать другой - mingw32-make.exe

dll+lib+a получили, почти без «хакинга» ... но они к программе в среде MinGW не подлинковываются.

И текст ошибки нам расскажет знакомый телепат?

Microsoft Visual C++ также пишет: «fatal error LNK 1107

И правильно пишет, *.lib файлы компиляторо-специфичны.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

Чё за make? Если от MSYS, то надо использовать другой - mingw32-make.exe


Собственно, я его просто переименовал: mingw32-make.exe -> make.exe. Взял его из Dev-Cpp 4.9.9.2. Так быстрее в командной строке набирать (я работаю в FAR Manager).

dll+lib+a получили, почти без «хакинга» ... но они к программе в среде MinGW не подлинковываются.

И текст ошибки нам расскажет знакомый телепат?


Будь попроще. Было так:

$ i586-mingw32msvc-gcc -o _scale.exe scale.c FreeImage.dll -I. 
/tmp/ccIZc9Uq.o:scale.c:(.text+0x83): undefined reference to `__imp__FreeImage_Initialise@4'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x97): undefined reference to `__imp__FreeImage_Load@12'
/tmp/ccIZc9Uq.o:scale.c:(.text+0xaa): undefined reference to `__imp__FreeImage_GetWidth@4'
/tmp/ccIZc9Uq.o:scale.c:(.text+0xbd): undefined reference to `__imp__FreeImage_GetHeight@4'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x11d): undefined reference to `__imp__FreeImage_Rescale@16'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x136): undefined reference to `__imp__FreeImage_Rescale@16'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x14f): undefined reference to `__imp__FreeImage_Rescale@16'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x168): undefined reference to `__imp__FreeImage_Rescale@16'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x181): undefined reference to `__imp__FreeImage_Rescale@16'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x19a): more undefined references to `__imp__FreeImage_Rescale@16' follow
/tmp/ccIZc9Uq.o:scale.c:(.text+0x1ae): undefined reference to `__imp__FreeImage_Save@16'
/tmp/ccIZc9Uq.o:scale.c:(.text+0x1b5): undefined reference to `__imp__FreeImage_DeInitialise@0'
collect2: ld returned 1 exit status
То есть, ошибка (при компиляции DLL «с нуля» под Linux), вылетала на этапе сборки .exe.

Перед этим (см. первое моё сообщение), не справлялся с задачей линуксовый i586-mingw32msvc-dlltool - полученный под Linux файл FreeImage.DLL не мог быть подключен на этапе запуска .exe. Но .exe успешно собирался.

Собственно, после сборки DLL под Линукс, и «патча» (dlltool.exe, Dev-Cpp 4.9.9.2), и программа успешно слинковалась, и DLL успешно подгрузилась - всё работает. Вот только не помню я - где для этой DLL объектники собирал. Наверное, под тем же Debian.

pacify ★★★★★ ()
Ответ на: комментарий от LamerOk

>> Microsoft Visual C++ также пишет: «fatal error LNK 1107

И правильно пишет, *.lib файлы компиляторо-специфичны.


Хм-хм. То есть, для подключения DLL к приложению на Visual C++, надо использовать .LIB-файл? Я в этом не понимаю, так как „нативное программирование под Windows“ не изучал.

pacify ★★★★★ ()
Ответ на: комментарий от pacify

> Перед этим (см. первое моё сообщение), не справлялся с задачей линуксовый i586-mingw32msvc-dlltool

см. ошибку во втором сообщении топика

pacify ★★★★★ ()
Ответ на: комментарий от LamerOk

Теоретически. А практически, у меня пол проекта собрано студией, а половиной жоцеце, и подлинковано 1:1 :D

vasily_pupkin ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.