我将使用一个简化的例子来解释我的情况。
我有两个libme.so 文件,它们具有不同的实现,并且我已经验证它们可以同时在一个设计中工作。一个位于 ./root/v1/ 另一个位于 ./root/v2/
我的“主”.so 文件与这两个 libme.so 文件链接,位于 ./root/libtest.so
现在我需要使这些东西可重定位。也就是说,如果我将整个“根”目录复制到另一个位置甚至另一台机器(假设二进制兼容),事情应该仍然可以正常工作。
我的问题是,要完成这项工作,我应该使用什么 gcc 命令行来构建 libtest.so?
我试过以下两种:
(1)(假设我在“根”目录中)
>gcc -shared -o libtest.so ./v1/libme.so ./v2/libme.so
这将使 libtest.so 具有绝对路径的这两个链接依赖项。这可以通过 ldd 进行验证:
>ldd libtest.so
/home/design/root/v1/libme.so
/home/design/root/v2/libme.so
显然路径是固定的。因此,一旦我重新定位“根”目录,它就无法在运行时找到 libme.so。注意设置 LD_LIBRARY_PATH 在这种情况下不起作用,因为来自 ldd 的路径是绝对路径。运行时加载程序不会搜索 LD_LIBRARY_PATH 来查找 libme.so。
(2)
>gcc -shared -o libtest.so -lme -L./v1 -L./v2
这只有在我们有一个版本的 libme.so 时才有效。在这种情况下,./v2 中的版本将不会被链接。-rpath 也存在同样的问题。
鉴于此,我还有什么其他选择?
注意有一些限制: (1) 不能将 libme.so 重命名为其他名称,例如 libme_v1.so (2) libtest.so 必须在两个版本的 libme.so 中链接