Fail to static linking FreeImage 3.15.4 on MingW

丶灬走出姿态 提交于 2019-12-12 00:29:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!