1

I am compiling a shared library using g++ on SUse Linux with cmake that depends on libicuuc.so and friends.

Suse has libicuuc.so, libicuuc.so.46 and libicuuc.so.46.1 in /usr/lib.

Now when I use ldd to list the dependencies of my library it tells me that it depends on libicuuc.so.46.

Since I want to distribute my library in binary form (it takes about 45 minutes to compile on a fast PC) this dependency is a problem. The target PCs have different versions of libicuuc.so.

What can I do so that my library depends on libicuuc.so and not libicuuc.so.46?

I tried to remove the so.46 versions in my /usr/lib folder before compiling but libicuuc.so depends on libicudata.so.46 so I keep that dependency on a 46 version what I try to avoid.

Georg
  • 119
  • 1
  • 10

1 Answers1

1

Read about external library versioning here.

What can I do so that my library depends on libicuuc.so and not libicuuc.so.46?

You can't do anything about that. The libicuuc.so that you have has SONAME set to libicuuc.so.46, and the linker dutifully records that dependency (as it should).

If developers release libicuuc.so.47, they would do so because the new library is not ABI-compatible with the old one (at least that's what they should do if they are not clueless).

If your library loaded libcuuc.so.47 (as you want it to), it would most likely crash due to the ABI incompatibility. Or worse: corrupt your end user's data. So achieving your desired result would get you into worse trouble than what you have now (not running is better than randomly crashing or corrupting data).

Update:

The libicuuc.so documentation explicitly states that "Binary compatibility is for versions that share the same major+minor number."

That means: you can't link a library compiled with version 4.6 (SONAME libicuuc.so.46) and expect it work with version 4.7.

You must either rebuild your library for each version of ICUUC, or distribute matching libicuuc.so.NN with your library (and hope that the user is not already using some other version of libicuuc).

Another possible alternative: statically link libicuuc.a into your library, and hide all of libicuuc.a symbols so they don't conflict with anything else. Note: this has licensing implications.

Community
  • 1
  • 1
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • I did assume that version 46 has a subset of the 47 ABI and the library that was linked with a 46 library could just pick the parts it needed from the 47 ABI. But I have no detailed knowledge about shared library ABIs and how the linker uses them. – Georg Nov 10 '14 at 13:48
  • @Georg You assumption is incorrect. Adding new parts to the ABI does *not* require incrementing external version; only *incompatible* change to *existing* ABI does. – Employed Russian Nov 10 '14 at 15:39
  • What do you recommend that I do? When I compile from source the library will work with any version of libicuuc. When I compile it, it will only work with the libicuuc version that is currently installed. If I make a binary rpm this will just work if the target PC has the same shared library version of libicuuc that I had on my PC where I compiled it. I thought libicuuc.so was intended to allow programs to ask to load just ".so" and this will then point to any version that happens to be installed. – Georg Nov 10 '14 at 21:28
  • I will give the static approach a try. I wanted to make a stripped down bare bones version of ICU anyway. Thank you for your detailed information! – Georg Nov 10 '14 at 22:14