【问题标题】:How to rename a shared library to avoid same-name conflict?如何重命名共享库以避免同名冲突?
【发布时间】:2013-11-13 10:12:11
【问题描述】:

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

# SHARED=1 make install

将在/usr/lib 中编译和安装.so。问题是我的系统(Arch Linux)已经有一个名为libjson 的库,Makefile 不假思索地为我覆盖了它! Arch 的库是作为依赖项安装的,因此无法替换。如果其他发行版有一个名为 libjson 的库,可能会遇到类似的问题。

对此我能做些什么?我可以重命名库(libjson-mine 或其他名称),但动态链接距离魔术只有几步之遥,所以我不知道这是否会破坏某些东西。 如何重命名库?

另一种选择是将库的源代码放入我当前项目的源代码树中,并让构建器创建一个静态库。 (显然这使我的代码存储库有点混乱,因此不受欢迎。)如果我走这条路,我需要让链接器更喜欢我的libjson.a,而不是在/usr/lib 中搜索“合适的”(阅读:错误) 图书馆。 如何让链接器更喜欢我的版本?

或者,有没有我不知道的第三种选择?

【问题讨论】:

  • 一个更好的主意是使用通常的/usr/local/前缀配置和安装您在软件包系统之外显式构建的软件,以便您的libjson进入/usr/local/lib/libjson.so;此外,了解有关LD_LIBRARY_PATH 环境变量和/etc/ld.so.conf 以及ldconfig 命令的更多信息。

标签: linux linker shared-libraries dynamic-linking file-rename


【解决方案1】:

背景概念

共享库用于两点:

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

    在执行时,将在标准路径中搜索该基本名称。

    在链接时,链接器必须能够在其搜索路径上找到您的库。将添加到搜索路径并不容易:

    你也许可以避开/usr/local/lib,它是为用户编译的库而设计的,应该在/usr/lib之前。

    但是这样做会破坏任何使用另一个 libjson 的东西,所以你可能不希望这样。

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

    在执行时,不需要路径搜索,因为我们已经有了完整的路径。

您可以检查哪些存储在可执行文件中:

readelf -d a.out | grep 'Shared library'

可能的解决方案

我没有看到不需要编辑项目的Makefile 的任何好的解决方案,所以细节是项目特定的。但总的来说,您可以:

  1. 编辑库的 Makefile 或类似文件,并将基本名称重命名为 libjson_mine.so

    编译需要该库的程序:-ljson_mine。这将起作用,因为我们知道 /usr/lib.so 搜索路径中。

    这是最好的选择,迟早要完成,否则会造成无穷无尽的混乱……发送拉取请求!

    在同一个拉取请求中,还将默认安装目录更改为/usr/local/lib,而不是/usr/lib。这就是默认情况下正常的用户编译库必须去的地方,正是为了避免覆盖分发提供的库。

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

    如果这样的选项不存在,拉取请求。如果所有者不想接受,请分叉项目;-)

    然后您和您的发行版可以在编译时使用该选项。

  3. 在 Makefile 中找到一个选项来更改库 + 头文件的安装目录,然后使用完全自定义的内容(~/usr/lib~usr/include),并将其添加到您的动态加载程序搜索路径 How to specify preference of library path? +包括搜索路径。有关 GNU 方法,请参阅 DESTDIR and PREFIX of make

    然后在编译/执行时,更改包含/动态加载器搜索路径。

    不理想,但可能一次性使用。

【讨论】:

    【解决方案2】:

    有几种方法:

    • 默认安装的库听起来好像你也可以使用它。想过吗?

    • 也许你确实可以重命名“其他”json库,并将其安装到/usr/local/lib

    • 也许你可以学习在 Arch Linux 上构建一个(pacman?)包。我不知道,但应该不会太难。至少,它不适用于基于 RPM 的系统,所以我认为它也不适用于 Arch。

    • 您可以选择一种介于两者之间的方式:

      从其他项目构建一个静态库并将其包含在您自己的项目中。这样您就不会弄乱已安装的库,而且您的代码树也很干净。

    【讨论】:

    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 2013-03-17
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    相关资源
    最近更新 更多