【发布时间】:2011-12-16 05:45:43
【问题描述】:
我需要构建两个第三方共享库,因此它们的 .so 文件将被其他项目重用。但是,在构建这些库之一后,包含到另一个库的硬编码路径。此路径在其他机器上无效并导致链接器警告。如何防止完整路径嵌入到生成的 .so 文件中?
详情:
第一个库来源:~/dev/A
二库来源:~/dev/B
他们都有configure 脚本来生成make 文件。库 B 依赖于 A。所以,首先我建立A:
$ ~/dev/A/configure --prefix=~/dev/A-install
$ make && make install
然后我构建B:
$ ~/dev/B/configure --prefix=~/dev/B-install --with-A=~/dev/A-install
$ make && make install
然后我想将~/dev/A-install 和~/dev/B-install 的内容上传到我们的文件服务器,以便其他团队和构建机器可以使用这些二进制文件。但是当他们尝试使用B 时会收到链接器警告:
/usr/bin/ld: warning: libA.so.2, needed by /.../deps/B/lib/libB.so, not found (try using -rpath or -rpath-link)
当我运行 ldd libB.so 时,它给出:
...
libA.so.2 => /home/alex/dev/A-install/lib/libA.so.2
显然这条路径只存在于我的机器上,其他机器上找不到。
如何从libB.so 中删除完整的硬编码路径?
谢谢。
【问题讨论】:
-
如何链接?使用 libtool?在这种情况下,
patchelf可能会帮助您摆脱编码路径(RPATH)。 -
为什么不使用不依赖于您的环境的前缀,即
~?为什么不使用像/opt这样的前缀,它不依赖于像$HOME(~) 这样的环境变量?你可以试试LD_PRELOAD也许 -
理想情况下,您可以更改
configure脚本以防止出现此问题。如果您想编辑库,我听说过有关 elfsh (eresi-project.org) 的好消息。 -
@another.anon.coward,为了清楚起见,我在这里使用 ~ 前缀。实际上,它是某个目录的完整路径。但无论如何,这个目录对我的机器来说是唯一的,不一定存在于其他机器上。
-
configure脚本设计用于这种情况。是的,在您仔细阅读之前,从文档中并不完全清楚。
标签: c++ gcc linker shared-libraries