Issue
I am working on a library in C, let us call it ninja. Ninja depends upon some under laying libraries (which we also provide) (e.g jutsu, goku, bla). These are all placed in a shared library folder, let us say /usr/lib/secret/. The clients whom are using this project wants to be able to havde ninja version 1 and 2 laying side by side, this it not so hard. The problem comes when ninja 1 dependes up on for instance jutsu 1 and ninja 2 depends upon jutsu 3. How the h... do we/I do so so that when installing ninja from our package repository. It knows the correct version of jutsu. Of course the rpm/deb package should depend upon the correct version of the jutsu package.
so what we want is when, we execute for instance zypper in ninja. and it installs and compiles on the system, it knows which jutsu library to take with out been given a version number.
So we in the make file don't have to do this:
gcc ninja.c -o ninja -L /usr/local/lib/secret/ -l jutsu_2
But just
gcc ninja.c -o ninja -L /usr/local/lib/secret/ -l jutsu
NOTE: I know it is random to use ninja and so on, but I am not allowed to publish the real library names
Solution
You want to use an SONAME. Describing all the steps necessary is probably too large a scope for a good StackOverflow answer, but I can give an overview and point to some documentation.
An SONAME is a special data field inside a shared library. It is typically used to indicate compatibility with other versions of the same library; if two different versions of a shared library have the same SONAME, the linkers will know that either one can fill the dependency on that library. If they have a different SONAME, they can't.
Example: I have libdns88
and libbind-dev
version 1:9.8.4.dfsg.P1-6+nmu2+deb7u1
installed on a Debian wheezy system. I build a binary called samurai
with -ldns
. The GNU linker finds "libdns.so
" in my library search path and dynamically links samurai
with it. It reads the SONAME field from libdns.so
(which is a symlink to libdns.so.88.1.1
). The SONAME there is "libdns.so.88
".
$ objdump -p /usr/lib/libdns.so | grep SONAME
SONAME libdns.so.88
The libdns developers (or maybe packagers) chose that SONAME to indicate that any version 88.* of libdns is expected to be binary compatible with any other version 88.*. They use that same SONAME for all versions with a compatible ABI. When the ABI had a change, they changed the SONAME to libdns.so.89
, and so on. (Most well-managed libraries don't change their ABI that often.)
So the library dependency written into the samurai
binary is just libdns.so.88
. When I run samurai
later, the dynamic linker/loader looks for a file called "libdns.so.88
" instead of just "libdns.so
".
Also by convention, the name of an rpm or deb package should change when the SONAME of the library contained changes. That's why there is a libdns88
package separate from the libdns100
package, and they can be installed side by side without interfering with each other. My samurai
package will have a dependency on "libdns88
" and I can expect that any package called libdns88
will have a compatible ABI to the one I built it against. Tools like dpkg-shlibdeps
make it simple to create the right shared library package dependencies when SONAMEs and versioned symbols are used.
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Answered By - the paul Answer Checked By - Mary Flores (WPSolving Volunteer)