如何重命名共享库以避免同名冲突? [英] How to rename a shared library to avoid same-name conflict?

查看:71
本文介绍了如何重命名共享库以避免同名冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了一个库 libjson 构建为共享库并在项目中使用.建筑很简单;修复Makefile错误后,

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

将在/usr/lib 中编译并安装一个 .so .问题是我的系统(Arch Linux)已经有一个名为 libjson 的库,Makefile为我覆盖了这个库!Arch的库是作为依赖项安装的,因此无法替换.如果其他发行版具有一个名为 libjson 的库,则大概也会遇到类似的问题.

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.

对此我该怎么办?我可以重命名该库( libjson-mine 之类的东西),但是动态链接离魔术只有几步之遥,所以我不知道这是否会破坏某些东西.如何重命名库?

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?

另一个选择是将库的源代码放入我当前项目的源树中,然后让构建器创建一个静态库.(显然,这会使我的代码存储库更加混乱,因此是不合需要的.)如果我走了这条路线,则需要使链接程序更喜欢我的 libjson.a 而不是搜索/usr/lib 表示合适的"(错误的)库.如何使链接器首选我的版本?

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?

推荐答案

背景概念

共享库在两个地方使用:

Shared libraries are used at two points:

  • 由链接器( ld )进行编译
  • 由动态加载程序执行
  1. 如果使用 -llibjson 在gcc中进行编译,则基本名称将存储在可执行文件中

  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:

您也许可以摆脱/usr/local/lib ,它是为用户编译的库而设计的,应该位于/usr/lib 之前.

You might be able to get away with /usr/local/lib which is intended for user compiled libraries and should come before /usr/lib.

但是这样做会破坏使用其他 libjson 的任何内容,因此您可能不希望这样做.

But doing so will break anything that uses the other libjson, so you likely don't want that.

如果使用 -l:/full/path/to/libjson.so 在gcc中进行编译,则完整路径将存储在可执行文件中.

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'

可能的解决方案

我看不到任何不需要编辑项目的 Makefile 的好的解决方案,因此详细信息是特定于项目的.但总的来说,您可以:

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. 编辑该库的Makefile或类似文件,并将基本名称重命名为 libjson_mine.so .

使用以下代码编译需要该库的程序:-ljson_mine .这将起作用,因为我们知道/usr/lib .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!

在相同的拉取请求中,还将默认安装目录更改为/usr/local/lib 而不是/usr/lib .这是默认情况下必须由明智的用户编译的库所使用的位置,正是为了避免覆盖分发的库.

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.

如果所有者不想重命名该库,请在Makefile中找到一个选项来更改生成的库的基本名称.

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.

在Makefile中找到一个选项,该选项会更改安装了库+标头的目录,然后使用完全自定义的内容(〜/usr/lib 〜usr/包含),并将其添加到动态加载程序搜索路径如何指定库路径的首选项? +包含搜索路径.有关GNU方法,请参见 DESTDIR和make的前缀.

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.

这篇关于如何重命名共享库以避免同名冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆