我看到的问题是perl
在 Cygwin(1.7.15,截至 09/2012 的当前版本)上运行的进程中加载了错误版本的库。
简单地说,perl
starts,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
这是ldd
Perl/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
忽略了。因为如果不是,为什么我会收到版本不匹配警告?
库加载机制是特定于perl
Cygwin 还是 Cygwin?它是如何工作的?如何制作perl
或 Cygwin 加载正确的库?
[我的一个怀疑是,它perl
驻留在 中/usr/bin
,它将首先在其二进制文件目录中查找库/usr/bin
,因此遵循 Windows 约定而不是 UNIX 约定。]