Linux 为什么我不能用LD_LIBRARY_path覆盖动态库的搜索路径?
编辑:我解决了这个问题,解决方案如下 我正在一个共享计算集群中构建一个专门用于科学计算的代码,因此我只能控制主文件夹中的文件。虽然我使用fftw作为示例,但我想了解具体原因,即我尝试设置LD_LIBRARY_路径失败的原因 我在我的主文件夹中构建fftw和fftw\u mpi库,如下所示Linux 为什么我不能用LD_LIBRARY_path覆盖动态库的搜索路径?,linux,ld,dynamic-linking,fftw,Linux,Ld,Dynamic Linking,Fftw,编辑:我解决了这个问题,解决方案如下 我正在一个共享计算集群中构建一个专门用于科学计算的代码,因此我只能控制主文件夹中的文件。虽然我使用fftw作为示例,但我想了解具体原因,即我尝试设置LD_LIBRARY_路径失败的原因 我在我的主文件夹中构建fftw和fftw\u mpi库,如下所示 ./configure --prefix=$HOME/install/fftw --enable-mpi --enable-shared make install 它构建得很好,但在install/fftw/
./configure --prefix=$HOME/install/fftw --enable-mpi --enable-shared
make install
它构建得很好,但在install/fftw/lib中,我发现新构建的libfftw3_mpi.so链接到错误版本的fftw库
$ ldd libfftw3_mpi.so |grep fftw
libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f7df0979000)
如果我现在尝试将LD_LIBRARY_路径正确设置为指向此目录,它仍然首选错误的库:
$ export LD_LIBRARY_PATH=$HOME/install/fftw/lib
$ ldd libfftw3_mpi.so |grep fftw
libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f32b4794000)
只有明确使用LD_PRELOAD,我才能重写此行为。我认为LD_预加载不是一个合适的解决方案
$ export LD_PRELOAD=$HOME/install/fftw/lib/libfftw3.so.3
$ ldd libfftw3_mpi.so |grep fftw
$HOME/install/fftw/lib/libfftw3.so.3 (0x00007f5ca3d14000)
这是我所期望的,在Ubuntu桌面上完成的一个小测试,我首先将fftw安装到/usr/lib,然后用LD_LIBRARY_path覆盖这个搜索路径
$ export LD_LIBRARY_PATH=
$ ldd q0test_mpi |grep fftw3
libfftw3.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3.so.3
$ export LD_LIBRARY_PATH=$HOME/install/fftw-3.3.4/lib
$ ldd q0test_mpi |grep fftw3
libfftw3.so.3 => $HOME/install/fftw-3.3.4/lib/libfftw3.so.3
简言之:为什么libfft3\u mpi库仍然找到错误的动态fftw3库?该搜索路径的硬编码方式在哪里,使其优先于LD_LIBARY_路径?为什么另一台计算机不是这样
我使用的是英特尔编译器13.1.2、mkl 11.0.4.183和openmpi 1.6.2(如果需要)
编辑:谢谢所有的答案。在这些帮助下,我们能够将问题隔离到RPATH,从那里,集群支持能够解决问题。我接受了第一个答案,但两个答案都很好
之所以很难弄清楚,是因为我们不知道编译器实际上是包装脚本,向编译器命令行添加了一些东西。以下是支持部门回复的一部分:
编译通过我们的编译器包装器进行。我们做的是自行车运动
默认情况下,这有助于大多数用户正确运行其作业
不加载LD-LIBRARY_路径等,但我们排除某些
来自默认RPATH的库路径,其中包括/lib、/lib64/proj
/home等。之前的/usr/lib64没有被错误地排除在外
(大部分)。现在我们在排除列表中添加了该路径
从
在解析共享对象依赖项时,动态链接器首先
检查每个依赖项字符串是否包含斜杠(此
如果创建了包含斜杠的共享对象路径名,则可能发生此情况
在链接时间指定)。如果找到斜杠,则依赖项
字符串被解释为(相对或绝对)路径名,而
使用该路径名加载共享对象
如果共享对象依赖项不包含斜杠,则为
按以下顺序搜索:
o(仅限ELF)使用DT_RPATH动态目录中指定的目录
二进制文件的section属性(如果存在)和DT_运行路径
属性不存在。不推荐使用DT_RPATH
o使用环境变量LD_LIBRARY_PATH。除非
可执行文件是一个set user ID/set group ID二进制文件,在这种情况下
被忽略了
o(仅限ELF)使用DT_运行路径中指定的目录
二进制文件的动态节属性(如果存在)
o来自缓存文件/etc/ld.so.cache,其中包含已编译的
以前在“增强”列表中找到的候选共享对象列表
图书馆路径。但是,如果二进制文件与-z链接
nodeflib链接器选项,默认路径中的共享对象为
跳过。硬件功能中安装的共享对象
目录(见下文)优先于其他共享对象
o在默认路径/lib中,然后是/usr/lib。(在大约64位上)
体系结构中,64位共享对象的默认路径为
/如果二进制文件与
-z nodeflib链接器选项,跳过此步骤
- 使用readelf
可以在动态部分检查您的库是否包含这样的属性readelf-dlibfftw3\u mpi.so
- 使用导出LD_DEBUG=libs可以调试用于查找libs的搜索路径
- 使用
可以更改rpathchrpath-r
- 我认为有两个可能的原因
首先,
libfftw3\u mpi.so
可以作为RPATH
链接到/usr/lib64/
。在这种情况下,提供LD_LIBRARY_PATH
将无效。要检查是否是您的情况,请运行readelf-d libfftw3_mpi.so | grep RPATH
,并查看它是否有/usr/lib64/
作为库路径。如果是,请使用chrpath
实用程序更改或删除它
或者,您可能正在运行一个根本不支持
LD\u LIBRARY\u PATH
(如HP-UX)的系统。实际上,对于readelf,似乎/usr/lib64确实位于名为RPATH的/home/USER/install/fftw/lib in变量之前。现在的问题仍然是,/usr/lib64是如何在/fftw/lib之前到达那里的$readelf-d libfftw3_mpi.so|grep RPATH 0x000000000000000f(RPATH)库RPATH:[/software/intel/composer_xe_2013.4.183/compiler/lib/intel64:/usr/lib/gcc/x86_64-redhat-linux/4.4:/usr/lib64:/home/USER/install/fftw/lib]
在编译时添加RPATH。我不知道fftw库,但可能有一个--disable rpath
configure标志。要更改rpath,可以使用chrpath-r
更改库中的rpath