tags:

views:

238

answers:

3

I've got a project working on that's using FreeImage and openCV, currently we're using the jpeg support from both of these (I am working towards fixing that, but for now it's got to stay). Anyhow, FreeImage compiles libjpeg 7.0 into its static libraries, and openCV's highgui library links it in as a shared library (on my system, Ubuntu 9, I've got libjpeg 6.2 installed).

They link into a final library that's used to link into various programs, java wrappers, etc. All of that works fine, no symbol conflicts or anything during compile/link time. However, when I go to open an image using the openCV cvLoadImage function, it dies when reading the header, most likely due to differences between headers in 6.2 and 7.0.

If I unlink FreeImage (and comment out the code that requires it), the openCV calls start working again, so clearly the static libjpeg symbols from FreeImage are conflicting with symbols that would be loaded from the libjpeg shared library. What I can't figure out is why my compiler isn't throwing an error during linking because of the two sets of libjpeg symbols. Additionally, I've tried replacing my system's jpeglib.h header with the 7.0 version temporarily to see if openCV compiled with that would then sync up with the symbols that freeimage brings to the table, to no avail it seems.

Lastly I put a printf in jpeg_read_header in the libjpeg that freeimage compiles, and rebuilt it to see if openCV is using the freeimage libjpeg definition. It didn't print out so I have to assume not.

So I guess my questions are

1) Why doesn't linking a static libjpeg and a shared libjpeg generate linking errors due to duplicate symbols?

2) Does anyone know why these two things are conflicting with one another?

Edit: Compiling openCV in debug mode and then in regular mode again seems to have knocked something loose and made it work again, no idea what's going on.

+1  A: 

it is like this

Static libraries are compiled in, dynamic libraries are loaded during runtime, but only those symbols which are missing (I think). you can compile shared libraries in, and then you probably get symbol collision.

so opencv uses symbols which are compiled in, since they already present, rather than those from dynamic libraries. you end up using static symbols, possibly with different signatures, from prospective of opencv.

aaa
My assumption is that it's using one or the other library, but perhaps it's using a little of both somehow? Changing the header that openCV compiles with didn't fix the problem after all..
gct
+1  A: 

Generally speaking the linker is fine about being passed multiple libraries that all resolve the same symbol(s). It just uses the first one it finds. The order of the libraries on your linker command line will determine which one "wins".

This, by the way, is NOT true of object files. Every linker I've ever used assumes that you want to use all of the objects that you specify, and will complain if more than one has the same symbol.

John Knoeller
So most likely, it would be one or the other version of libjpeg that would "win" right? So either it'd pick the openCV version, in which case things would work, or switching the header openCV uses during compilation to the freeimage one should fix it... but it doesn't =(
gct
If the one the linker picked was different than the header you used, then I would expect it to _not_ work. You would need to switch headers _and also_ reorder the libs on the link line, and even that is courting failure. better to leave the lib you don't want to use off the link line entirely
John Knoeller
+1  A: 

You need to modify the linking options to export only the symbols that you want, then all the symbols in conflict will be hidden internally in the static linking, then no conflicts. By default all the symbols are exported, that's the problem. See this link: http://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html

zoomer.hammerball