如何让Cygwin / perl加载特定的文件库(例如LD_LIBRARY_PATH / LD_RUN_PATH)?

时间:2012-09-23 17:14:48

标签: perl dll cygwin ld library-path

我看到的问题是,在Cygwin上运行的perl进程中加载​​了错误的库版本(1.7.15,截至2012年9月的当前版本)。

简单地说,perl启动,use XML::LibXML,它是libxml2的Perl接口,Daniel Veillard的XML库C库,然后Perl / C粘合剂加载C库。现在,安装了两个版本,/usr/lib中的较旧版本和/usr/local/lib中的较新版本 - 这是一个典型的场景。 Perl / C胶水库(XML::LibXML)是根据/usr/local/lib中较新的版本编译的。然而,负责加载库的Perl或Cygwin组件会选择较旧的组件。这会触发Perl / C粘合代码的警告,该代码正确地期望并要求编译它的版本。 (由于向后兼容性,它仍然主要起作用,但不完全符合预期。)

有一点需要注意,在Cygwin上它不是lib/libxml2.so.2,而是bin/cygxml2-2.dll

这是从屏幕上复制的动作:

MiLu@Dago: /tmp > export LD_LIBRARY_PATH=/usr/local/bin
MiLu@Dago: /tmp > export LD_RUN_PATH=/usr/local/bin
MiLu@Dago: /tmp > ls -l /usr/bin/cygxml2-2.dll
-rwxr-xr-x 1 MiLu root 1096206  1. Mrz 2012  /usr/bin/cygxml2-2.dll
MiLu@Dago: /tmp > ls -l /usr/local/bin/cygxml2-2.dll
-rwxr-xr-x 1 MiLu None 3997813 21. Mai 22:35 /usr/local/bin/cygxml2-2.dll
MiLu@Dago: /tmp > perl -MXML::LibXML -e1
Warning: program compiled against libxml 208 using older 207
Warning: XML::LibXML compiled against libxml2 20800,
                 but runtime libxml2 is older 20708

我不确定如何加载C库cygxml2-2.dll(标准名称libxml2)。

这是Perl / C胶水库的ldd输出:

$ ldd /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads-64int/auto/XML/LibXML/LibXML.dll
    ntdll.dll       => /cygdrive/c/Windows/SysWOW64/ntdll.dll (0x774a0000)
    kernel32.dll    => /cygdrive/c/Windows/syswow64/kernel32.dll (0x756c0000)
    KERNELBASE.dll  => /cygdrive/c/Windows/syswow64/KERNELBASE.dll (0x76750000)
    cygwin1.dll     => /usr/bin/cygwin1.dll (0x61000000)
    cygssp-0.dll    => /usr/bin/cygssp-0.dll (0x6af50000)
>>> cygxml2-2.dll   => /usr/local/bin/cygxml2-2.dll (0x63fc0000) <<<
    cygz.dll        => /usr/bin/cygz.dll (0x6a900000)
    cyggcc_s-1.dll  => /usr/bin/cyggcc_s-1.dll (0x6ca60000)
    cygiconv-2.dll  => /usr/bin/cygiconv-2.dll (0x6c390000)
    cygperl5_14.dll => /usr/bin/cygperl5_14.dll (0x6b8a0000)
    cygcrypt-0.dll  => /usr/bin/cygcrypt-0.dll (0x6d3d0000)
    ???             => ??? (0x520000)

正如您所看到的,正确定位了较新的库,就像在UNIX上发生的那样。但ldd不是实际的过程,可能使用不同的查找机制。

使用strace perl … | grep -i cygxml显示无输出。

在我看来,LD_LIBRARY_PATHLD_RUN_PATH被忽略了。因为如果不是为什么我会收到版本不匹配警告?

库加载机制是否特定于perl或Cygwin?它是如何工作的?如何让perl或Cygwin加载正确的库?

[我怀疑的是perl居住在/usr/bin,它将首先在{binnerie的目录/usr/bin中查找库,从而遵循Windows约定而不是UNIX约定。]

2 个答案:

答案 0 :(得分:1)

在编写Alien :: Base时,我需要使用DynaLoader直接删除特定的库。您可以阅读代码here,但快速和肮脏应该只是

require DynaLoader;
DynaLoader::dl_load_file( $library_path, 0x01 )

答案 1 :(得分:0)

cygwin确实支持LD_LIBRARY_PATH;尝试检查它是否在您的脚本开头按预期设置:

BEGIN { print "LD_LIBRARY_PATH: $ENV{LD_LIBRARY_PATH}.\n" }