为什么我不能使用LD_LIBRARY_PATH覆盖动态库的搜索路径? [英] Why I cannot override search path of dynamic libraries with LD_LIBRARY_PATH?

查看:949
本文介绍了为什么我不能使用LD_LIBRARY_PATH覆盖动态库的搜索路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我解决了这个问题,解决方法如下.

I resolved this issue, the solution is below.

我正在专用于科学计算的共享计算集群中构建代码,因此我只能控制主文件夹中的文件.尽管我以fftw为例,但我想了解具体原因,为什么我尝试设置LD_LIBRARY_PATH无效.

I am building a code in a shared computing cluster dedicated for scientific computing, thus I can only control files in my home folder. Although I am using fftw as an example, I would like to understand the specific reason, why my attempt to setup LD_LIBRARY_PATH does not work.

我在这样的主文件夹中建立fftw和fftw_mpi库

I build the fftw and fftw_mpi libraries in my home folder like this

./configure --prefix=$HOME/install/fftw --enable-mpi --enable-shared
make install

它构建良好,但是在install/fftw/lib中,我发现新构建的libfftw3_mpi.so链接到错误版本的fftw库.

It builds fine, but in install/fftw/lib, I find that the freshly built libfftw3_mpi.so links to wrong version of fftw library.

$ ldd libfftw3_mpi.so |grep fftw
  libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f7df0979000)

如果我现在尝试正确设置LD_LIBRARY_PATH指向此目录,它仍然会选择错误的库:

If I now try to set the LD_LIBRARY_PATH correctly pointing to this directory, it still prefers the wrong 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_PRELOAD是合适的解决方案.

Only if I explicitly use LD_PRELOAD, I can override this behavior. I don't think LD_PRELOAD is a proper solution though.

$ 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中将fftw安装到/usr/lib,然后使用LD_LIBRARY_PATH覆盖此搜索路径.

Here is what I would have expecting, a small test done in Ubuntu desktop, where I installed fftw to /usr/lib first, and then override this search path with 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_mpi库仍然找到错误的动态fftw3库?该搜索路径在哪里以比LD_LIBARY_PATH优先的方式硬编码?为什么在另一台计算机上不是这种情况?

In short: Why is libfft3_mpi library still finding the wrong dynamic fftw3 library? Where is this searchpath hard coded in a such way that it is prioritized over LD_LIBARY_PATH? Why is this is not the case in another computer?

如果这很重要,我正在使用英特尔编译器13.1.2,mkl 11.0.4.183和openmpi 1.6.2.

I am using intel compilers 13.1.2, mkl 11.0.4.183 and openmpi 1.6.2 if this matters.

感谢您提供所有答案.在这些帮助下,我们能够将问题隔离到RPATH,并且从那里开始,集群支持才能够找出问题所在.我接受了第一个答案,但是两个答案都很好.

Thanks for all the answers. With help of those, we were able to isolate the problem to RPATH, and from there, the cluster support was able to figure out the problem. I accepted the first answer, but both answers were good.

之所以很难弄清这个原因,是因为我们不知道编译器实际上是包装器脚本,从而在编译器命令行中添加了一些内容.以下是支持人员回复的一部分:

The reason, why this was so hard to figure out, is that we did not know that the compilers were actually wrapper scripts, adding things to compiler command line. Here a part of a reply from the support:

[The]编译通过我们的编译器包装器进行.我们做RPATHing 默认情况下,因为它可以帮助大多数用户正确运行其作业 而不加载LD-LIBRARY_PATH等.但是,我们排除了某些 默认RPATH中的库路径,其中包括/lib,/lib64/proj /home等.之前/usr/lib64未被错误排除 (大多).现在,我们将该路径添加到了排除列表中.

[The] compilation goes through our compiler wrapper. We do RPATH-ing by default as it helps most users in correctly running their jobs without loading LD-LIBRARY_PATH etc. However we exclude certain library paths from default RPATH which includes /lib, /lib64 /proj /home etc. Earlier the /usr/lib64 was not excluded by mistake (mostly). Now we have added that path in the exclusion list.

推荐答案

来自 http: //man7.org/linux/man-pages/man8/ld.so.8.html

解决共享库依赖关系时,动态链接器首先 检查每个依赖项字符串以查看其是否包含斜杠(此 如果包含斜杠的共享对象路径名是 在链接时指定).如果找到斜线,则依赖项 字符串被解释为(相对或绝对)路径名,并且 使用该路径名加载共享库.

When resolving shared object dependencies, the dynamic linker first inspects each dependency string to see if it contains a slash (this can occur if a shared object pathname containing slashes was specified at link time). If a slash is found, then the dependency string is interpreted as a (relative or absolute) pathname, and the shared object is loaded using that pathname.

如果共享库依赖项不包含斜杠,则为 按以下顺序搜索:

If a shared object dependency does not contain a slash, then it is searched for in the following order:

o(仅ELF)使用DT_RPATH动态中指定的目录 二进制的section属性(如果存在)和DT_RUNPATH 属性不存在.不建议使用DT_RPATH.

o (ELF only) Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is deprecated.

o使用环境变量LD_LIBRARY_PATH.除非 可执行文件是设置用户ID/设置组ID二进制文件,在这种情况下,它是 被忽略.

o Using the environment variable LD_LIBRARY_PATH. Except if the executable is a set-user-ID/set-group-ID binary, in which case it is ignored.

o(仅ELF)使用DT_RUNPATH中指定的目录 二进制文件的动态部分属性(如果存在).

o (ELF only) Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present.

o来自缓存文件/etc/ld.so.cache,其中包含已编译的 先前在增强版中找到的候选共享对象的列表 库路径.但是,如果二进制文件与-z链接 nodeflib链接器选项,默认路径中的共享库为 跳过了.硬件功能中安装的共享对象 目录(请参见下文)要比其他共享库优先.

o From the cache file /etc/ld.so.cache, which contains a compiled list of candidate shared objects previously found in the augmented library path. If, however, the binary was linked with the -z nodeflib linker option, shared objects in the default paths are skipped. Shared objects installed in hardware capability directories (see below) are preferred to other shared objects.

o在默认路径/lib中,然后在/usr/lib中. (在某些64位 在体系结构中,64位共享对象的默认路径是 /lib64,然后是/usr/lib64.)如果二进制文件与 -z nodeflib链接器选项,将跳过此步骤.

o In the default path /lib, and then /usr/lib. (On some 64-bit archiectures, the default paths for 64-bit shared objects are /lib64, and then /usr/lib64.) If the binary was linked with the -z nodeflib linker option, this step is skipped.

  • 使用readelf readelf -d libfftw3_mpi.so,您可以检查您的lib是否在动态部分中包含此类属性.

    • with readelf readelf -d libfftw3_mpi.so you can check if your lib contains such a attribute in the dynamic section.

      使用export LD_DEBUG=libs,您可以调试用于查找库的搜索路径

      with export LD_DEBUG=libs you can debug the search path used to find your libs

      使用chrpath -r<new_path> <executable>可以更改rpath

      with chrpath -r<new_path> <executable> the rpath can be changed

      这篇关于为什么我不能使用LD_LIBRARY_PATH覆盖动态库的搜索路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆