问题
I can't static lingking FreeImage 3.15.4 on MingW (either using .lib nor .a). I always receive error "undefined reference to" all FreeImage method. While I successfully dynamic linking the library.
Then I try build from the source, it's the same.
I also try using 3.15.3, both static and dynamic is success. But there's a bug in those version (opening some JPEG).
Need help with this.
My code only 1 file, purge.cpp
#define FREEIMAGE_LIB
#include "FreeImage.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
std::cerr << "FIError: " << message << std::endl;
}
int main(int argc, char** argv) {
#ifdef FREEIMAGE_LIB
FreeImage_Initialise();
#endif
FreeImage_SetOutputMessage(FreeImageErrorHandler);
std::string fnameIn (argv[1]);
std::string fnameOut (argv[2]);
std::vector<uint8_t> data;
std::ifstream ifs;
ifs.open(fnameIn.c_str(), std::ios::binary);
uint8_t c = ifs.get();
while (ifs.good()) {
data.push_back(c);
c = ifs.get();
}
ifs.close();
FIMEMORY *hmem = FreeImage_OpenMemory(&data[0], data.size());
FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
FIBITMAP *dib = FreeImage_LoadFromMemory(fif, hmem, 0);
int flag = JPEG_BASELINE | JPEG_QUALITYGOOD | JPEG_SUBSAMPLING_420 | JPEG_PROGRESSIVE | JPEG_OPTIMIZE;
bool b = FreeImage_Save(FIF_JPEG, dib, fnameOut.c_str(), flag);
std::cout << ((b)?"Save\n":"NoSave\n");
FreeImage_Unload(dib);
FreeImage_CloseMemory(hmem);
#ifdef FREEIMAGE_LIB
FreeImage_DeInitialise();
#endif
return 0;
}
Command:
g++ -o purge purge.cpp -L. -lfreeimage
Result:
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x286): undefined reference to `FreeImage_Initialise'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x292): undefined reference to `FreeImage_SetOutputMessage'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x486): undefined reference to `FreeImage_OpenMemory'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x49c): undefined reference to `FreeImage_GetFileTypeFromMemory'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x502): undefined reference to `FreeImage_LoadFromMemory'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x533): undefined reference to `FreeImage_GetWidth'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x541): undefined reference to `FreeImage_GetHeight'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x701): undefined reference to `FreeImage_Rescale'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x723): undefined reference to `FreeImage_Unload'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x72e): undefined reference to `FreeImage_CloseMemory'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x7a4): undefined reference to `FreeImage_Save'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x7d9): undefined reference to `FreeImage_Unload'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x7ea): undefined reference to `FreeImage_CloseMemory'
C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o:purge.cpp:(.text+0x7ef): undefined reference to `FreeImage_DeInitialise'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\ADIT~1.BIS\AppData\Local\Temp\cc1LYwkh.o: bad reloc address 0xf in section `.text$_ZNSt6vectorIhSaIhEEC1Ev[__ZNSt6vectorIhSaIhEEC1Ev]'
collect2.exe: error: ld returned 1 exit status
Then when I remove "#define FREEIMAGE_LIB", it's success. But with dynamic linking :(
Solved.
After reading README.minGW carefully. The mistake I made is: I create *.a with 'pexports' & 'dlltool'. While those *.a file is for dynamic link. The *.a file for static link should compile from the source with setting "FREEIMAGE_LIBRARY_TYPE=STATIC". Don't forget to edit "makefile", since the OS has been hard-coded to "gnu".
回答1:
Try to define FREEIMAGE_LIB
in your application too (before including of the header). Without that define your app will always spawn "undefined reference", because FreeImage.h still think that it's dynamic library and adds via macroses a DLL-Export annoations, so, prototypes in the header and in the built library are different.
If you still have troubles, you would also try to apply some changes into library itself:
Steps to do:
1. Modify FreeImage.h:
Replace this:
#ifdef __cplusplus
extern "C" {
#endif
with:
#if defined(__cplusplus) && !defined(__MINGW32__)
extern "C" {
#endif
then this:
#ifdef __cplusplus
}
#endif
with:
#if defined(__cplusplus) && !defined(__MINGW32__)
}
#endif
2. In those files:
Source/DeprecationManager/DeprecationMgr.cpp
Source/FreeImage/FreeImage.cpp
Source/FreeImage/Plugin.cpp
replace all #ifdef _WIN32
with #if defined(_WIN32) && !defined(__MINGW32__)
(or #if defined(_WIN32) && !defined(FREEIMAGE_LIB)
instead to don't break dynamic build).
Exception: don't replace #ifdef _WIN32
in the "Plugin.cpp" in the *U
functions: FreeImage_GetFIFFromFilenameU
, FreeImage_LoadU
and FreeImage_SaveU
.
3. Then try to completely rebuild library. It should be built fine
4. In your application you should define FREEIMAGE_LIB
too (I told below why).
If you want, you can take my working code which you would use:
https://github.com/WohlSoft/libFreeImage
I made it buildable via QMake for convenience, and I also made ability to build a lite version (which supports BMP, ICO, PNG and GIF formats only and which has small weigth). It was been included into MinGW-buildable project and it is successfully linking statically.
来源:https://stackoverflow.com/questions/20947685/fail-to-static-linking-freeimage-3-15-4-on-mingw