2 min to read
MongoDB驱动安装
类Unix系统动态链接时可执行与可链接格式文件中 DT_RPATH 字段的写入.

MongoDB驱动安装
unix
linux
gcc
ld
rpath
runpath
背景
开发一个在线电影订票网站时考虑利用MongoDB来进行后台数据持久化。但是在编译安装MongoDB驱动时遇到一些问题。
问题
- 在WSL中传递rpath参数,得到结果是RPATH。
> echo "int main() { return 0; }" > test.c && gcc test.c -o test -Wl,--rpath=. && readelf -d test | grep path 0x000000000000000f (RPATH) Library rpath: [.]
当前编译器信息为:
> gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
系统信息为:
> lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.4 LTS Release: 16.04 Codename: xenial > cat /proc/version Linux version 4.4.0-17127-Microsoft (Microsoft@Microsoft.com) (gcc version 5.4.0 (GCC) ) #1-Microsoft Sun Mar 18 00:47:00 PST 2018
- 在Debian中编译,得到结果是RUNPATH。
> echo "int main() { return 0; }" > test.c && gcc test.c -o test -Wl,--rpath=. && readelf -d test | grep path 0x000000000000001d (RUNPATH) Library runpath: [.]
当前编译器信息为:
> gcc --version gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
系统信息为:
> lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 9.4 (stretch) Release: 9.4 Codename: stretch > cat /proc/version Linux version 3.16.0-5-amd64 (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.51-3+deb8u1 (2018-01-08)
结果
在Ubuntu 17.10及18.04预览版得到结果也是RUNPATH。rpath与runpath的不同,很久前的QT博客中有提到: 字段决定链接动态库时搜索的顺序。
当时搜索了许多也没有找到答案:为何较新的系统上在可执行与可链接格式文件中指定写入DT_RPATH
字段对应(rpath),写入的却是DT_RUNPATH
字段(对应runpath),以及怎样才能在那些系统上写入DT_RPATH
字段。
查看三个系统上的相关文档,三者文档描述差不多。
> man ld
...
-rpath=dir
Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared
objects at runtime. The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option. If -rpath is not used when
linking an ELF executable, the contents of the environment variable "LD_RUN_PATH" will be used if it is defined.
The -rpath option may also be used on SunOS. By default, on SunOS, the linker will form a runtime search path out of all the -L options it is given. If a -rpath option is used, the runtime search path will be formed
exclusively using the -rpath options, ignoring the -L options. This can be useful when using gcc, which adds many -L options which may be on NFS mounted file systems.
For compatibility with other ELF linkers, if the -R option is followed by a directory name, rather than a file name, it is treated as the -rpath option.
...
后来终于找到了原因:Gentoo ld generates RUNPATH in library when -Wl,-rpath is used。
回答是(谷歌翻译得来):
DDT_RPATH标签被弃用,DT_RUNPATH是现代的实现,有两种不同的语义。Gentoo链接编辑器(两者ld和gold)默认情况下不会生成弃用的标签。你可以(但可能不应该)通过传递来禁用这些-Wl,–disable-new-dtags,但这并不是我所说的建议。
Comments