动态链接与rpath不工作在Ubuntu 17.10下 [英] Dynamic linking with rpath not working under Ubuntu 17.10

查看:267
本文介绍了动态链接与rpath不工作在Ubuntu 17.10下的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我构建一个R包,它使用Rcpp和链接到第三方共享对象( libbarraopt.so )(也链接到其他共享对象,例如 liboptsrvr.so 在它自己的目录中)。为了确保它能够找到它所链接的共享对象,我在〜/ .Renviron 中放置了以下变量:

  BARRA_OPS_HOME = $ {HOME} /bin/BarraOptimizer8.5 

在包中,我创建了以下 src / Makevars

  BARRA_LIB = $(BARRA_OPS_HOME)/ lib / intel64 
BARRA_INCLUDE = $(BARRA_OPS_HOME)/ include
PKG_CXXFLAGS = -I $(BARRA_INCLUDE)
PKG_CFLAGS = -I $(BARRA_INCLUDE)
PKG_LIBS = -L $(BARRA_LIB)-Wl,-R,$(BARRA_LIB)-lbarraopt

在Ubuntu 16.04下,我可以成功构建,加载和使用该软件包,而不会出现任何问题。但是,当操作系统升级到17.10时,我测试了完全相同的软件包时,可以构建软件包,但无法加载,说:

  g ++ -std = gnu ++ 11 -I / usr / share / R / include -DNDEBUG -I/home/renkun/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include - I / home / renkun / bin / BarraOptimizer8.5 / include -fpic -g -O2 -fstack-protector-strong -Wformat -Werror = format-security -Wdate-time -D_FORTIFY_SOURCE = 2 -g -c RcppExports.cpp -o RcppExports.o 
** libs
g ++ -std = gnu ++ 11 -I / usr / share / R / include -DNDEBUG -I/ home / renkun / R / x86_64-pc-linux- gnu-library / 3.4 / Rcpp / include-I / home / renkun / bin / BarraOptimizer8.5 / include -fpic -g -O2 -fstack-protector-strong -Wformat -Werror = format-security -Wdate-time -D_FORTIFY_SOURCE = 2 -g -c barraopt.cpp -o barraopt.o
g ++ -std = gnu ++ 11 -shared -L / usr / lib / R / lib -Wl,-Bsymbolic-functions -Wl,-z ,relro -o barraopt.so RcppExports.o barraopt.o -L / home / renkun / bin / BarraOptimizer8.5 / lib / intel64 -Wl,-R,/ home / renkun / bin / BarraOptimizer8.5 / lib / intel64 -lbarraopt -L / usr / lib / R / lib -lR
安装到/ tmp / Rtmpvbb6Io / devtools_install_42a342a07f84 / barraopt / libs
* DONE(barraopt)
dyn.load (dllfile):
无法加载共享对象'/home/renkun/Workspaces/barraopt/src/barraopt.so':
liboptsrvr.so:无法打开共享对象文件:无此文件或目录
电话:suppressPackageStartupMessages ...<匿名> - > load_all - > load_dll - > library.dynam2 - > dyn.load
执行暂停

退出状态1.

看起来 -Wl,-rpath 在这里没有效果。

在使用Ubuntu 16.04的机器下, ldd src / barraopt.so 显示所有动态链接都已解决。 ( BARRA_OPS_HOME = /home/ken/bin/BarraOptimizer8.5

  linux-vdso.so.1 => (0x00007ffc89a16000)
libbarraopt.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libbarraopt.so(0x00007f85dae49000)
libimf.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libimf.so(0x00007f85da97f000)
libR.so => /usr/lib/libR.so(0x00007f85da346000)
libstdc ++。so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6(0x00007f85d9fc4000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1(0x00007f85d9dae000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007f85d99e3000)
liboptsrvr.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/liboptsrvr.so(0x00007f85d7b10000)
libopsproto.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libopsproto.so(0x00007f85d77a1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6(0x00007f85d7497000)
libintlc.so.5 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libintlc.so.5(0x00007f85d7249000)
libblas.so.3 => /usr/lib/libblas.so.3(0x00007f85d6fe8000)
libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6(0x00007f85d6da1000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3(0x00007f85d6b31000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5(0x00007f85d690f000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0(0x00007f85d66fe000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1(0x00007f85d64e4000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1(0x00007f85d62dc000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2(0x00007f85d60d7000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1(0x00007f85d5eb5000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0(0x00007f85d5c98000)
/lib64/ld-linux-x86-64.so.2(0x000055fb75088000)
libifcore.so.5 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libifcore.so.5(0x00007f85d5961000)
libifport.so.5 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libifport.so.5(0x00007f85d5732000)
libsvml.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libsvml.so(0x00007f85d4e6d000)
libmosek64.so.7.0 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libmosek64.so.7.0(0x00007f85d3c63000)
libiomp5.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libiomp5.so(0x00007f85d396b000)
libprotobuf.so.6 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libprotobuf.so.6(0x00007f85d3668000)
libbridge_common.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libbridge_common.so(0x00007f85d3417000)
libsharc_xmlxproto.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libsharc_xmlxproto.so(0x00007f85d31a4000)
libboost_thread.so.1.49.0 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libboost_thread.so.1.49.0(0x00007f85d2f8a000)
libopenblas.so.0 => /usr/lib/libopenblas.so.0(0x00007f85d0ef5000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5(0x00007f85d0ccc000)
libxerces-c-3.1.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libxerces-c-3.1.so(0x00007f85d07c4000)
libgfortran.so.3 => /usr/lib/x86_64-linux-gnu/libgfortran.so.3(0x00007f85d0499000)
libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1(0x00007f85d027f000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0(0x00007f85d0040000)

然而,在Ubuntu 17.10下, ldd 显示共享对象 libbarraopt.so 链接不会被解析( BARRA_OPS_HOME = /home/renkun/bin/BarraOptimizer8.5 )< -Wl,-rpath / p>

  linux-vdso.so.1 => (0x00007ffe067f5000)
libbarraopt.so => /home/renkun/bin/BarraOptimizer8.5/lib/intel64/libbarraopt.so(0x00007f3dc5f0c000)
libR.so => /usr/lib/libR.so(0x00007f3dc58e4000)
libstdc ++。so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6(0x00007f3dc555e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6(0x00007f3dc5208000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1(0x00007f3dc4ff1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007f3dc4c11000)
liboptsrvr.so =>未找到
libopsproto.so =>未找到
libblas.so.3 => /usr/lib/x86_64-linux-gnu/libblas.so.3(0x00007f3dc49b6000)
libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6(0x00007f3dc4770000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3(0x00007f3dc44fe000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5(0x00007f3dc42d8000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0(0x00007f3dc40c8000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1(0x00007f3dc3eab000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1(0x00007f3dc3ca3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2(0x00007f3dc3a9f000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1(0x00007f3dc3870000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0(0x00007f3dc3651000)
/lib64/ld-linux-x86-64.so.2(0x00007f3dc6526000)
libopenblas.so.0 => /usr/lib/x86_64-linux-gnu/libopenblas.so.0(0x00007f3dc13ab000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5(0x00007f3dc1182000)
libgfortran.so.4 => /usr/lib/x86_64-linux-gnu/libgfortran.so.4(0x00007f3dc0da3000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0(0x00007f3dc0b63000)

它看起来像只有 libbarraopt.so 与正确的路径链接,但它链接的共享对象缺失。



我想知道我的构建配置在17.10发布的工具链下可能会出现什么问题。虽然使用全局配置(如 ldconfig )可以解决这个问题,但我并不是因为某些 .so 它依赖于冲突OS发布的版本。我宁愿使用本地配置的版本,而不会影响全局配置。

解决方案



可能发生的情况是您更新的链接器发出 DT_RUNPATH 动态标记,其中旧链接器发出 DT_RPATH 。 (也可能你的旧链接器是GNU-ld,而新的链接器是Gold。)


$ b $ < DT_RUNPATH 是比较正确的选择,它会影响二进制本身的搜索路径,但不会影响任何相关库的搜索路径。


$ b $ < DT_RPATH
code>具有全局效果,类似于将目录添加到 LD_LIBRARY_PATH 环境变量。



您可以验证这与: readelf -d a.out | grep'R. * PATH'



如果您看到 RPATH 和vs 。 RUNPATH 区别,实际上使用的是Gold,你可以用 -Wl强制旧行为, - disable-new-dtags GNU ld )最近还添加了 - disable-new-dtags ,所以它应该适用于任何链接器)。


I build an R package which uses Rcpp and links to a third-party shared object (libbarraopt.so) (which also links to other shared objects such as liboptsrvr.so in its own directory). To ensure that it is able to find those shared objects it links against, I put the following variables in ~/.Renviron:

BARRA_OPS_HOME=${HOME}/bin/BarraOptimizer8.5

In the package, I create the following src/Makevars:

BARRA_LIB=$(BARRA_OPS_HOME)/lib/intel64
BARRA_INCLUDE=$(BARRA_OPS_HOME)/include
PKG_CXXFLAGS=-I$(BARRA_INCLUDE)
PKG_CFLAGS=-I$(BARRA_INCLUDE)
PKG_LIBS=-L$(BARRA_LIB) -Wl,-R,$(BARRA_LIB) -lbarraopt

Under Ubuntu 16.04, I can build, load, and use the package successfully without any problem. However, when I test exactly the same package when OS is upgraded to 17.10, the package can be built but it cannot be loaded, saying:

g++ -std=gnu++11 -I/usr/share/R/include -DNDEBUG  -I"/home/renkun/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include"   -I/home/renkun/bin/BarraOptimizer8.5/include -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c RcppExports.cpp -o RcppExports.o
** libs
g++ -std=gnu++11 -I/usr/share/R/include -DNDEBUG  -I"/home/renkun/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include"   -I/home/renkun/bin/BarraOptimizer8.5/include -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c barraopt.cpp -o barraopt.o
g++ -std=gnu++11 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o barraopt.so RcppExports.o barraopt.o -L/home/renkun/bin/BarraOptimizer8.5/lib/intel64 -Wl,-R,/home/renkun/bin/BarraOptimizer8.5/lib/intel64 -lbarraopt -L/usr/lib/R/lib -lR
installing to /tmp/Rtmpvbb6Io/devtools_install_42a342a07f84/barraopt/libs
* DONE (barraopt)
Error in dyn.load(dllfile) : 
  unable to load shared object '/home/renkun/Workspaces/barraopt/src/barraopt.so':
  liboptsrvr.so: cannot open shared object file: No such file or directory
Calls: suppressPackageStartupMessages ... <Anonymous> -> load_all -> load_dll -> library.dynam2 -> dyn.load
Execution halted

Exited with status 1.

It seems that -Wl,-rpath is not effective here.

Under a machine with Ubuntu 16.04, ldd src/barraopt.so shows that all dynamic linking is corrected resolved. (BARRA_OPS_HOME = /home/ken/bin/BarraOptimizer8.5)

linux-vdso.so.1 =>  (0x00007ffc89a16000)
libbarraopt.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libbarraopt.so (0x00007f85dae49000)
libimf.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libimf.so (0x00007f85da97f000)
libR.so => /usr/lib/libR.so (0x00007f85da346000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f85d9fc4000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f85d9dae000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f85d99e3000)
liboptsrvr.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/liboptsrvr.so (0x00007f85d7b10000)
libopsproto.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libopsproto.so (0x00007f85d77a1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f85d7497000)
libintlc.so.5 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libintlc.so.5 (0x00007f85d7249000)
libblas.so.3 => /usr/lib/libblas.so.3 (0x00007f85d6fe8000)
libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007f85d6da1000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f85d6b31000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f85d690f000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f85d66fe000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f85d64e4000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f85d62dc000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f85d60d7000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f85d5eb5000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f85d5c98000)
/lib64/ld-linux-x86-64.so.2 (0x000055fb75088000)
libifcore.so.5 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libifcore.so.5 (0x00007f85d5961000)
libifport.so.5 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libifport.so.5 (0x00007f85d5732000)
libsvml.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libsvml.so (0x00007f85d4e6d000)
libmosek64.so.7.0 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libmosek64.so.7.0 (0x00007f85d3c63000)
libiomp5.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libiomp5.so (0x00007f85d396b000)
libprotobuf.so.6 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libprotobuf.so.6 (0x00007f85d3668000)
libbridge_common.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libbridge_common.so (0x00007f85d3417000)
libsharc_xmlxproto.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libsharc_xmlxproto.so (0x00007f85d31a4000)
libboost_thread.so.1.49.0 => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libboost_thread.so.1.49.0 (0x00007f85d2f8a000)
libopenblas.so.0 => /usr/lib/libopenblas.so.0 (0x00007f85d0ef5000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f85d0ccc000)
libxerces-c-3.1.so => /home/ken/bin/BarraOptimizer8.5/lib/intel64/libxerces-c-3.1.so (0x00007f85d07c4000)
libgfortran.so.3 => /usr/lib/x86_64-linux-gnu/libgfortran.so.3 (0x00007f85d0499000)
libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007f85d027f000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f85d0040000)

However, with the same source, under Ubuntu 17.10, ldd shows that the shared objects libbarraopt.so links against are not resolved even though -Wl,-rpath is secified: (BARRA_OPS_HOME = /home/renkun/bin/BarraOptimizer8.5)

linux-vdso.so.1 =>  (0x00007ffe067f5000)
libbarraopt.so => /home/renkun/bin/BarraOptimizer8.5/lib/intel64/libbarraopt.so (0x00007f3dc5f0c000)
libR.so => /usr/lib/libR.so (0x00007f3dc58e4000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3dc555e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3dc5208000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3dc4ff1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3dc4c11000)
liboptsrvr.so => not found
libopsproto.so => not found
libblas.so.3 => /usr/lib/x86_64-linux-gnu/libblas.so.3 (0x00007f3dc49b6000)
libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007f3dc4770000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3dc44fe000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f3dc42d8000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f3dc40c8000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f3dc3eab000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f3dc3ca3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3dc3a9f000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f3dc3870000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3dc3651000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3dc6526000)
libopenblas.so.0 => /usr/lib/x86_64-linux-gnu/libopenblas.so.0 (0x00007f3dc13ab000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f3dc1182000)
libgfortran.so.4 => /usr/lib/x86_64-linux-gnu/libgfortran.so.4 (0x00007f3dc0da3000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f3dc0b63000)

It looks like only libbarraopt.so is linked with the correct path but shared objects it links against are missing.

I'm wondering what might be wrong with my build configurations that breaks under the toolchain shipped by 17.10. Although using global config such as ldconfig would solve such problem, I prefer not because some .so it relies have conflict with the version the OS ships. I'd rather use a locally configured version without affecting the global config.

解决方案

It seems that -Wl,-rpath is not effective here.

What likely happened is that your updated linker emits DT_RUNPATH dynamic tag, where the old linker emitted DT_RPATH. (It's also possible that your old linker was GNU-ld, and the new one is Gold.)

The DT_RUNPATH is preferred as more correct, and affects search path of the binary itself, but not of any of the dependent libraries.

The DT_RPATH has global effect, similar to adding the directory to LD_LIBRARY_PATH environment variable.

You can verify this with: readelf -d a.out | grep 'R.*PATH'.

If you do see the RPATH vs. RUNPATH difference, and in fact are using Gold, you can force the "old" behavior with -Wl,--disable-new-dtags (GNU ld also had --disable-new-dtags added to it recently, so it should work for either linker).

这篇关于动态链接与rpath不工作在Ubuntu 17.10下的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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