8

I am following this example. However, I want to compile a static binary for the given toy example code. Normally, I use -static during compilation but here it gives an error message.

The compile command which works fine:

g++ freeimagetest.cpp -o freeimagetest -lfreeimageplus

The compile command which does not works fine:

g++ freeimagetest.cpp -o freeimagetest -lfreeimageplus -static

The last few lines of the error message:

 In function `ZIPPreDecode':
(.text+0x6f8): undefined reference to `inflateReset'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libfreeimageplus.a(tif_zip.o): In function `ZIPSetupDecode':
(.text+0x783): undefined reference to `inflateInit_'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libfreeimageplus.a(tif_zip.o): In function `ZIPSetupDecode':
(.text+0x7b4): undefined reference to `deflateEnd'
collect2: ld returned 1 exit status

So how could this be done/fixed?

EDIT: I could not see how the attached link solves my problem. Apparently, it looks that, due to the error messages, however, there is some problem in the way I am trying to compile it statically. I could not find the right way to do so. I think the error message is missleading - It just ends with these lines (where these lines are less than one percent of the all message). Anyone who has done it can better answer. If you think your answer is more than just an educated guess, i would request you to please give it a try before answering. It will only take a couple minutes if you follow the attached link. Moreover, I have tagged C also because it is same for C language programs as well.

tod
  • 1,539
  • 4
  • 17
  • 43

5 Answers5

7

Usually when you statically link a library (instead of linking it dynamically), you need to also link all of its dependencies manually. You need to figure out what library (dependency) it lacks and link it too.

Quick googling shows that inflateReset is from a library called zlib. Thus you need to link it using -lz. There is a good chance you already have this library in your compiler search directories, but if you don't, then you need to compile it manually.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
6

Following are the steps to compile C/C++ application statically with FreeImage library on Ubuntu:

  1. Use this link to download the source distribution of FreeImage.
  2. Download and uncompress to get the FreeImage source directory.
  3. Inside this directory open README.linux file and read it. It has very useful information. I would recommend not to miss it.
  4. README.linux file also guides on how to compile (both static and dynamic) and install this library for C or C++. The following is about C++:

Build FreeImagePlus

FreeImagePlus is a C++ wrapper for FreeImage. To build FreeImage as a C++ library enter the FreeImage directory using command prompt and build the distribution using the following command:

make -f Makefile.fip

Compile Test App Statically

Once make is complete, the desired files are available inside the Dist directory.

- libfreeimageplus.a: this is the static library ready to use.

- FreeImagePlus.h: this is the header file available for include.

Just copy these two files into the directory where the example C++ file (let's say freeimagetest.cpp) is already placed.

Use the following command to compile C/C++ application statically with FreeImage library on Ubuntu:

g++ -static freeimagetest.cpp -L. -lfreeimageplus -o freeimagetest

If you want to know more about creating and using static libraries, an example can be followed here

These steps solved my problem.

Please feel free to improve this answer.

tod
  • 1,539
  • 4
  • 17
  • 43
4

Used Visual C++ 6 Source : Use FreeImage as Static Library

How to use FreeImage as a static library instead of as a DLL (Visual C++ 6) ?

1. Compile the FreeImage library in debug and release modes and close your projects. You won't need to use the FreeImage source code anymore.
Note: Do not compile the FreeImage DLL (project named FreeImage) but the project named FreeImageLib. This should produce a huge file named FreeImage.lib (in release mode) or FreeImaged.lib (in debug mode) in the Dist\ directory.



2. Copy FreeImage.lib/FreeImaged.lib into your lib\ directory or in a directory where the linker can find them (e.g. your project directory). You can use "Menu->Tools->Options->Directories->Library files" for this.



3. Create a new project and add your code in it.
Add a call to FreeImage_Initialise() at the beginning of you main function and a call to FreeImage_DeInitialise() at the end of this function.



4. Edit the compiler options (Menu -> Project -> Settings)

    1. tab C/C++ : Category "Preprocessor"
    * Add FREEIMAGE_LIB to the preprocessor definitions
    2. tab C/C++ : Category "Code Generation"
    * Use the Multithreaded run-time library (in release mode)
    * Use the Debug Multithreaded run-time library (in debug mode)

5. Edit linker options (Menu -> Project -> Settings)

    1. tab Link : Category Input
    * Add FreeImage.lib to the list of object/library modules (release mode)
    * Add FreeImaged.lib to the list of object/library modules (debug mode)
    2. tab Link : Category Input
    * Add LIBCMT to the Ignore library list (it helps to avoid a warning)

6. Compile and link your program.

using MakeFile.MingW

# Uncomment this variable to make a static library. This may
# also be specified as an environment variable and can hold
# any of STATIC and SHARED and must be in uppercase letters.
# Default: SHARED
#FREEIMAGE_LIBRARY_TYPE = STATIC
 FREEIMAGE_LIBRARY_TYPE = STATIC

You don't need any another libary refer ReadMe.Mingw Section 2


2. Building the FreeImage library with MinGW

You do not need to have any other third party library (like libjpeg, libpng, libtiff, libmng and zlib and others) installed on your system in order to compile and use the library. FreeImage uses its own versions of these libraries. This way, you can be sure that FreeImage will always use the latest and properly tested versions of of these third party libraries.

  1. Fail to static linking FreeImage 3.15.4 on MingW (SOLVED)
  2. https://github.com/KelSolaar/FreeImage/blob/master/README.minGW
Community
  • 1
  • 1
Angelica
  • 488
  • 5
  • 22
  • I am using Linux/Ubuntu. The attached example in my question is also for Linux users. There is a complete list of steps to compile it statically using MSVS in QA of FreeImage webpage. Moreover, there are several questions on SO which talk about a list of issues during static compilation using MSVS. – tod Dec 19 '16 at 10:50
1

The link which you posted in your own answer to this question has the following at the top:

Source distribution includes source for FreeImage, C++, C#, Delphi and VB6 wrappers, examples and the internally used libraries LibTIFF, LibJPEG, LibPNG, ZLib, OpenEXR, OpenJPEG, LibRaw, LibJXR and LibWebP.

The distribution you are using most likely does not compile all these libraries into the static version of the freeimage library.

The compilation errors suggest that you should try adding system's ZLib and maybe LibTIFF to the list of libraries against which you link. This way you can avoid having to build your own version of freeimage library and use the system's version. If ZLib and LibTIFF turn out not to be the ones missing, you can try adding system's versions of the other libraries in that list one by one to see which one will solve the missing link issue.

grovkin
  • 158
  • 1
  • 3
  • 9
  • 1
    It's probably worth mentioning that the order of linkage matters. – Dmitry Rubanovich Dec 25 '16 at 00:30
  • 1
    @Dmitry Rubanovich, yes, `-static` has to precede the libraries which are to be statically linked on the command line. You can, in fact, switch between static and dynamic linking on the same command line a few times and before each set of libraries which are to be statically linked, you would use a `-static` option. And the libraries themselves may need to be reordered (or sometimes even listed twice if there is a circular dependency). So if libXYZ depends on libABC, then adding -lXYZ -lABC would work, while -lABC -lXYZ may not. – grovkin Dec 25 '16 at 00:35
-1

It has a dependency on a zip library. Probably zlib.

These functions don't have dependencies and are a better way to go if you want to avoid dependency hell.

https://github.com/MalcolmMcLean/babyxrc

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18