如何重命名共享库以避免同名冲突?

问题描述 投票:0回答:2

我找到了一个库,

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

# SHARED=1 make install

将在

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

对此我能做什么? 我可以重命名该库(

libjson-mine
之类的),但动态链接离魔法只有几步之遥,所以我不知道这是否会破坏某些东西。 如何重命名库?

另一个选择是将库的源代码放入我当前项目的源代码树中,并让构建器创建一个静态库。 (显然,这使我的代码存储库有点混乱,因此是不可取的。)如果我走这条路,我需要让链接器更喜欢我的

libjson.a
,而不是搜索
/usr/lib
寻找“合适的”(阅读:错误) 图书馆。 如何让链接器更喜欢我的版本?

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

linux linker shared-libraries dynamic-linking file-rename
2个回答
3
投票

背景概念

共享库有两点使用:

  • 由链接器编译(
    ld
    )
  • 由动态加载器执行
  1. 如果您使用

    -ljson
    在 gcc 中编译,基本名称将存储在可执行文件中

    执行时,将搜索标准路径以查找该基本名称。

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

    您也许可以使用

    /usr/local/lib
    ,它适用于用户编译的库,并且应该出现在
    /usr/lib
    之前。

    但是这样做会破坏任何使用另一个

    libjson
    的东西,所以你可能不希望这样。

  2. 如果您使用

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

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

您可以使用以下命令检查可执行文件中存储的内容:

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 中找到一个选项来更改生成的库的基本名称。

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.
  1. 在 Makefile 中找到一个选项来更改库 + 标头的安装目录,然后使用完全自定义的内容(

    ~/usr/lib
    ~usr/include
    ),并将其添加到动态加载程序搜索路径如何指定首选项库路径? + 包含搜索路径。请参阅 makeDESTDIR 和 PREFIX 了解 GNU 方法。

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

    不理想,但可能一次性有效。


1
投票

有几种可能有效的方法:

  • 也许你可以重命名“其他”json库,并将其安装到
    /usr/local/lib
  • 也许你可以学习在 Arch Linux 上构建一个(pacman?)包。我从来没有这样做过,但这应该不会太难。至少,对于基于 RPM 的系统来说并不太难。
  • 也许您可以从其他项目构建静态库并将其包含在您自己的项目中。这样你就不会弄乱已安装的库,而且你的代码树还是干净的。
© www.soinside.com 2019 - 2024. All rights reserved.