XML::LibXML
是一个Perl库。 LibXML.so
是图书馆的一部分。我想让XML::LibXML
使用定制的libxml2
。但提供LD_LIBRARY_PATH
没有任何区别:
$ ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f66af5e9000)
$ LD_LIBRARY_PATH=/home/yuri/_/libxml2/.libs ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f2d26ae3000)
$ ldd /usr/lib/python3.7/site-packages/libxml2mod.so | grep libxml2
libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f878cbc8000)
$ LD_LIBRARY_PATH=/home/yuri/_/libxml2/.libs ldd /usr/lib/python3.7/site-packages/libxml2mod.so | grep libxml2
libxml2.so.2 => /home/yuri/_/libxml2/.libs/libxml2.so.2 (0x00007f6f8f5d8000)
我究竟做错了什么?有办法处理吗?目标是使Perl脚本使用自定义构建的libxml2
(以调查某些问题)。
UPD
$ find /usr/lib -name libxml2.so.2
/usr/lib/libxml2.so.2
/usr/lib/vmware-installer/2.1.0/lib/lib/libxml2.so.2
/usr/lib/vmware-installer/2.1.0/lib/lib/libxml2.so.2/libxml2.so.2
/usr/lib/vmware-vmrc/5.5/lib/libxml2.so.2
/usr/lib/vmware-vmrc/5.5/lib/libxml2.so.2/libxml2.so.2
$ find /usr/local/lib -name libxml2.so.2
ExtUtils::MakeMaker
通过RPATH
部分中的.dynamic
条目硬编码二进制文件中共享库的路径。但是你可以预加载所需的库,
$ LD_PRELOAD=path/to/custom/libxml2/.libs/libxml2.so.2 ldd ./blib/arch/auto/XML/LibXML/LibXML.so
或使加载程序忽略RPATH
条目,
$ LD_LIBRARY_PATH=path/to/custom/libxml2/.libs /usr/lib/ld-linux-x86-64.so.2 --inhibit-rpath /abs/path/to/LibXML.so /abs/path/to/perl ./1.pl
或者将RPATH
条目转换为RUNPATH
,
$ chrpath --convert blib/arch/auto/XML/LibXML/LibXML.so
或删除RPATH
条目,
$ chrpath --delete blib/arch/auto/XML/LibXML/LibXML.so
或指定XMLPREFIX
变量,
$ perl Makefile.PL XMLPREFIX=path/to/custom/libxml2/build
ExtUtils::Liblist::ext()
列出了与-lxml2 -lz -llzma -licui18n -licuuc -licudata -lm -ldl
相关联的库,并将它们转换为four或five variables,它们将进入生成的Makefile
。其中之一是LD_RUN_PATH
。它包含找到库的所有路径。
如果图书馆是动态的,$is_dyna
是真的(不是ends与.a
)。如果Perl与$is_perl
不是built,则it是真的,而%ld_run_path_seen
在LD_RUN_PATH
中不重复值。
calculates LD_RUN_PATH
,用variable生成Makefile的一部分,以及将它传递给linker的部分。
LD_RUN_PATH
以及二进制文件中的RPATH
条目使加载程序在找到它们的目录(在编译时)搜索库(在运行时)。
-rpath = dir将目录添加到运行时库搜索路径。将ELF可执行文件与共享对象链接时使用此方法。所有-rpath参数都连接在一起并传递给运行时链接程序,后者使用它们在运行时查找共享对象。在定位链接中明确包含的共享对象所需的共享对象时,也会使用-rpath选项;请参阅-rpath-link选项的说明。如果在链接ELF可执行文件时未使用-rpath,则在定义环境变量“LD_RUN_PATH”的内容时将使用该内容。
https://jlk.fjfi.cvut.cz/arch/manpages/man/core/binutils/ld.1.en
如果共享对象依赖项不包含斜杠,则按以下顺序搜索它:
o使用二进制文件的DT_RPATH动态部分属性中指定的目录(如果存在)和DT_RUNPATH属性不存在。不推荐使用DT_RPATH。
o使用环境变量LD_LIBRARY_PATH,除非可执行文件以安全执行模式运行(参见下文),在这种情况下,此变量将被忽略。
https://jlk.fjfi.cvut.cz/arch/manpages/man/core/man-pages/ld.so.8.en
$ perl Makefile.PL
$ make
结果,
$ readelf --dynamic ./blib/arch/auto/XML/LibXML/LibXML.so | grep RPATH
0x000000000000000f (RPATH) Library rpath: [/usr/lib]
$ objdump -x ./blib/arch/auto/XML/LibXML/LibXML.so | egrep RPATH
RPATH /usr/lib
$ LD_LIBRARY_PATH=path/to/custom/libxml2/.libs ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f6cfabb2000)
--dynamic
- 显示.dynamic
部分的内容,-x
- 显示所有标题。
解决这个问题的一种方法是预加载所需的libxml2
实例,
$ LD_PRELOAD=path/to/custom/libxml2/.libs/libxml2.so.2 ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
path/to/custom/libxml2/build/lib/libxml2.so.2 (0x00007fe183aeb000)
另一种方法是告诉Makefile.PL
在所需位置(编译时)搜索libxml2
。
$ perl Makefile.PL XMLPREFIX=path/to/custom/libxml2/build
$ make
结果,
$ readelf --dynamic ./blib/arch/auto/XML/LibXML/LibXML.so | grep RPATH
0x000000000000000f (RPATH) Library rpath: [path/to/custom/libxml2/build/lib:/usr/lib]
$ objdump -x ./blib/arch/auto/XML/LibXML/LibXML.so | egrep RPATH
RPATH path/to/custom/libxml2/build/lib:/usr/lib
$ ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
libxml2.so.2 => path/to/custom/libxml2/build/lib/libxml2.so.2 (0x00007fe183aeb000)
如果您想调试XML::LibXML
,可以使用OPTIMIZE
变量运行make(添加-B
以使make重建所有内容,以防已经构建了库),
$ make OPTIMIZE='-g3 -O0'
还有-O2
,-g
没有LDDLFLAGS
,但不确定这是否重要。
或者,WriteMakeFile
采用OPTIMIZE
参数,所以你可以添加一行here,
'OPTIMIZE' => '-g3 -O0'
或者你可以添加变量here,并将其传递给Makefile.PL
,
$ perl Makefile.PL OPTIMIZE='-g3 -O0'
如果你在/usr/local/lib
中安装自定义版本的libxml,我认为XML :: LibXML模块应该加载自定义版本而不是/usr/lib
中的那个(假设你有sudoers或root权限来安装它)。
我不确定为什么Python似乎使用不同的库查找路径而不是Perl。也许libxml库的完整路径是在XML :: LibXML的LibXML.so中硬编码的?如果XML :: LibXML模块与-l / usr / lib / libxml2.so而不是-lxml2链接,那将是问题。