2013-11-02 92 views
3

我找到了一个库,libjson,我试图建立一个共享库并在一个项目中使用。建筑很简单,固定的Makefile错误后,如何重命名共享库以避免同名冲突?

# SHARED=1 make install 

将编译和/usr/lib安装.so。问题是我的系统(Arch Linux)已经有一个名为libjson的库,Makefile为我覆盖了这个库! Arch的库被安装为依赖项,所以它不能被替换。如果他们有一个名为libjson的库,那么其他发行版可能会有类似的问题。

我该怎么办?我可以重新命名图书馆(libjson-mine或其他),但动态链接离魔法只有几步之遥,所以我不知道这是否会破坏某些东西。 如何重命名图书馆?

另一种选择是将库的源代码放到我的当前项目的源代码树,并有建设者使静态库,而不是。 (很显然,这会让我的代码存储库变得更加混乱,因此不太合适)。如果我走这条路线,我需要让链接器更喜欢我的libjson.a,而不是搜索/usr/lib以获得“合适”(读取:错误)库。 如何让链接器更喜欢我的版本?

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

+1

一个更好的想法是用通常的'/ usr/local /'前缀来配置和安装你的软件包,这样你的'libjson'会进入'/ usr/local/LIB/libjson.so';另外,了解有关'LD_LIBRARY_PATH'环境变量和'/ etc/ld.so.conf'和'ldconfig'命令的更多信息。 –

回答

3

背景概念

共享库在两个点用于:

  • 汇编由接头(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

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

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

1

有几种方法:

  • 默认安装的库听起来好像你可以将这些东西与它。想过那个?
  • 也许你确实可以重命名“其他”json库,并将其安装到/usr/local/lib
  • 也许你可以学习在Arch Linux上构建一个(pacman?)包。我不知道,但它不应该太难。至少,它不适用于基于RPM的系统,所以我也不在Arch上。
  • 你可以用你的方式在两者之间去:

    从其他项目中生成静态库,包括在自己的项目。这样你就不会搞乱已安装的库,而且你的代码树也是干净的。

+0

除了其他开发人员可能位于我的其他架构(x86_64)之外,我不介意以最后的方式进行操作,而且目标实际上是运行Yocto Linux的ARM板。 – thirtythreeforty