【发布时间】:2013-03-19 03:53:57
【问题描述】:
我将使用一个简化的例子来解释我的情况。
我有 两个 libme.so 文件,它们具有不同的实现,我已经验证它们可以同时在一个设计中工作。一个位于 ./root/v1/ 另一个位于 ./root/v2/
我的“主”.so 文件与这 2 个 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 中链接
【问题讨论】:
-
它是哪个操作系统?在 Linux 上使用相对路径链接是可以的(至少我正在使用的链接器)
-
这是 Linux,rhel 5/6。如果您在 (1) 中执行与我相同的 gcc 命令,您是否从 ldd 获得相同样式的输出?如果不能,你能告诉我你的 gcc 命令和 ldd 的输出吗?谢谢。
-
可能是链接器版本?我正在使用最新的 Ubuntu。当我链接到上面的目录时,ldd 给了我
../liba.so.1.0 (0x00007f39c0226000) -
我认为你是对的!我刚刚在我的 Ubuntu 12 上尝试过,我得到了和你一样的结果。我将在 RHEL 上仔细检查我的链接器。