1

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

简单地说,perlstarts,does use XML::LibXML,它是 Daniel Veillard 的 XML 的 C 库的 Perl 接口libxml2,然后 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

这是lddPerl/C 胶水库的输出:

$ 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_PATH并被LD_RUN_PATH忽略了。因为如果不是,为什么我会收到版本不匹配警告?

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

[我的一个怀疑是,它perl驻留在 中/usr/bin,它将首先在其二进制文件目录中查找库/usr/bin,因此遵循 Windows 约定而不是 UNIX 约定。]

4

2 回答 2

1

在编写 Alien::Base 时,我需要使用 DynaLoader 直接 dlopen 特定库。你可以在这里阅读代码,但快速和肮脏的应该是简单的

require DynaLoader;
DynaLoader::dl_load_file( $library_path, 0x01 )
于 2012-09-24T02:02:16.830 回答
0

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

BEGIN { print "LD_LIBRARY_PATH: $ENV{LD_LIBRARY_PATH}.\n" }
于 2012-09-23T21:48:35.773 回答