How to rename a shared library to avoid same-name conflict?

微笑、不失礼 提交于 2020-12-03 11:51:05

问题


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?


回答1:


Background concepts

Shared libraries are used at two points:

  • compilation by the linker (ld)
  • execution by the dynamic loader
  1. If you compile in gcc with -llibjson, 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:

    • GCC how to add before the default linker search path by default? LIBRARY_PATH not working
    • How to stop gcc from passing -L with standard library paths to the linker

    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.

  2. 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:

  1. 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.

  2. 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.

  3. 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.




回答2:


There are several approaches:

  • The library installed by default sounds as if you could these things with it as well. Thought about that?

  • Maybe you can indeed rename the "other" json library, and install it to /usr/local/lib.

  • Maybe you can learn to build a (pacman?) package on Arch Linux. I doN't know about it, but it shouldn't be too hard. At least, it isn't for RPM based systems, so I thing it isn't on Arch as well.

  • You could go with a way in-between yours:

    Build a static library from the other project and include that in your own project. This way you won't mess with the installed library, and nevertheless you have your code tree clean.



来源:https://stackoverflow.com/questions/19739828/how-to-rename-a-shared-library-to-avoid-same-name-conflict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!