libjson
,我正在尝试将其构建为共享库并在项目中使用。 建造很简单;修复 Makefile 错误后,
# SHARED=1 make install
将在
.so
中编译并安装一个/usr/lib
。 问题是我的系统(Arch Linux)已经有一个名为 libjson
的库,Makefile 不假思索地为我覆盖了它! Arch 的库是作为依赖项安装的,因此无法替换。 如果其他发行版有一个名为 libjson
的库,想必也会遇到类似的问题。
对此我能做什么? 我可以重命名该库(
libjson-mine
之类的),但动态链接离魔法只有几步之遥,所以我不知道这是否会破坏某些东西。 如何重命名库?
另一个选择是将库的源代码放入我当前项目的源代码树中,并让构建器创建一个静态库。 (显然,这使我的代码存储库有点混乱,因此是不可取的。)如果我走这条路,我需要让链接器更喜欢我的
libjson.a
,而不是搜索 /usr/lib
寻找“合适的”(阅读:错误) 图书馆。 如何让链接器更喜欢我的版本?
或者,还有我不知道的第三种选择吗?
背景概念
共享库有两点使用:
ld
)如果您使用
-ljson
在 gcc 中编译,基本名称将存储在可执行文件中
执行时,将搜索标准路径以查找该基本名称。
在链接时,链接器必须能够在其搜索路径上找到您的库。在搜索路径中添加并不容易:
您也许可以使用
/usr/local/lib
,它适用于用户编译的库,并且应该出现在 /usr/lib
之前。
但是这样做会破坏任何使用另一个
libjson
的东西,所以你可能不希望这样。
如果您使用
-l:/full/path/to/libjson.so
在 gcc 中编译,完整路径将存储在可执行文件中。
执行时,不需要搜索路径,因为我们已经有了完整路径。
您可以使用以下命令检查可执行文件中存储的内容:
readelf -d a.out | grep 'Shared library'
可能的解决方案
我没有看到任何不需要编辑项目的
Makefile
的好的解决方案,因此详细信息是特定于项目的。但一般而言,您可以:
编辑库的 Makefile 或类似文件,并将基本名称重命名为
libjson_mine.so
。
使用以下命令编译需要该库的程序:
-ljson_mine
。这将起作用,因为我们知道 /usr/lib
在 .so
搜索路径中。
这是最好的选择,迟早必须完成,否则它将成为无尽混乱的根源......发送拉取请求!
在同一个拉取请求中,还将默认安装目录更改为
/usr/local/lib
而不是 /usr/lib
。这是默认情况下理智的用户编译库必须去的地方,以避免覆盖发行版提供的库。
如果所有者不想重命名库,请在 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.
在 Makefile 中找到一个选项来更改库 + 标头的安装目录,然后使用完全自定义的内容(
~/usr/lib
、~usr/include
),并将其添加到动态加载程序搜索路径如何指定首选项库路径? + 包含搜索路径。请参阅 make 的 DESTDIR 和 PREFIX 了解 GNU 方法。
然后在编译/执行时,更改包含/动态加载器搜索路径。
不理想,但可能一次性有效。
有几种可能有效的方法:
/usr/local/lib
。