I found a library, libjson
, that I am trying to build as a shared library and use in a project. Building is simple enough; after fixing a Makefile bug,
# SHARED=1 make install
will compile and install a .so
in /usr/lib
. The problem is that my system (Arch Linux) already has a library named libjson
, which the Makefile thoughtlessly overwrites for me! Arch's library was installed as a dependency, so it can't be replaced. Presumably other distros would have a similar problem if they had a library named libjson
.
What can I do about this? I could rename the library (libjson-mine
or something), but dynamic linking is only a couple steps away from magic, so I have no idea if this will break something. How can I rename the library?
The other option is to drop the library's source code into my current project's source tree and have the builder make a static library instead. (Obviously this makes my code's repository a bit messier, hence the undesirability.) If I went this route, I'd need to make the linker prefer my libjson.a
instead of searching /usr/lib
for a "suitable" (read: wrong) library. How do I make the linker prefer my version?
Or, is there a third option that I'm not aware of?
Background concepts
Shared libraries are used at two points:
ld
)If you compile in gcc with -ljson
, the basename will be stored in the executable
On execution time, standard paths will be searched for that basename.
At link time, the linker must be able to find your library on it's search path. It is not easy to prepend to the search path:
You might be able to get away with /usr/local/lib
which is intended for user compiled libraries and should come before /usr/lib
.
But doing so will break anything that uses the other libjson
, so you likely don't want that.
If you compile in gcc with -l:/full/path/to/libjson.so
the full path will be stored in the executable.
On execution, no path searching is needed since we have the full path already.
You can check which is stored in the executable with:
readelf -d a.out | grep 'Shared library'
Possible solutions
I don't see any good solution that does not require editing the Makefile
of the project, so the details are project specific. But in general terms, you can either:
Edit the Makefile or similar for the library, and rename the basename to libjson_mine.so
.
Compile programs that need that library with: -ljson_mine
. This will work since we know that /usr/lib
is in the .so
search path.
This is the best option and has to be done sooner or later, or it will be the source of endless confusion... send a pull request!
In the same pull request, also change the default installation directory to /usr/local/lib
instead of /usr/lib
. That is where sane user compiled libraries must go by default, exactly to avoid overwriting distribution supplied ones.
If the owner does not want to rename the library, find an option in the Makefile to change the basename of the generated library.
If such option does not exist, pull request. If the owner does not want to accept that, fork the project ;-)
Then you and your distribution can use that option when compiling.
Find an option in the Makefile that changes the directory in which the library + headers are installed, then use something completely custom (~/usr/lib
, ~usr/include
), and add that to your dynamic loader search path How to specify preference of library path? + include search path. See DESTDIR and PREFIX of make for GNU methods.
Then at compile / execution time, change the include / dynamic loader search paths.
Not ideal, but might work for a one-off.