2012-09-23 20 views
1

我看到的問題是,在Cygwin上運行的perl進程(1.7.15,截至09年9月當前)中加載了錯誤的庫版本。如何讓Cygwin/perl加載LD_LIBRARY_PATH/LD_RUN_PATH中的特定庫?

簡而言之,perl開始,確實use XML::LibXML,這是Perl接口libxml2,丹尼爾VEILLARD的C庫爲XML,然後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

下面是從屏幕上覆制的作用:

[email protected]: /tmp > export LD_LIBRARY_PATH=/usr/local/bin 
[email protected]: /tmp > export LD_RUN_PATH=/usr/local/bin 
[email protected]: /tmp > ls -l /usr/bin/cygxml2-2.dll 
-rwxr-xr-x 1 MiLu root 1096206 1. Mrz 2012 /usr/bin/cygxml2-2.dll 
[email protected]: /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 
[email protected]: /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_PATHLD_RUN_PATH被忽略。因爲如果不是,我爲什麼會收到版本不匹配警告?

是否特定於perl或Cygwin的庫加載機制?它是如何工作的?我如何使perl或Cygwin加載正確的庫?

[大懷疑我是perl居住在/usr/bin,它將第一查找圖書館/usr/bin,其binarie的目錄,因此,繼Windows約定,而不是UNIX約定。]

回答

1

在寫外國人:: Base的,我需要使用動態加載直接dlopen的專用庫。你可以閱讀代碼here但快速和骯髒的應該是簡單的

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

謝謝。添加'DynaLoader :: dl_load_file('/usr/local/bin/cygxml2-2.dll',0x01)'不會擺脫警告。一個明確的加載指令完成這項工作,毫不奇怪。但它不應該被要求。它仍然看起來像Perl或Cygwin中的一個功能或故障。不知道它應該如何工作,以及它出錯的地方是否確實出錯。 – Lumi

0

Cygwin並支持LD_LIBRARY_PATH;嘗試檢查它的設置爲你希望在你的腳本的開頭:

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

感謝。 'LD_LIBRARY_PATH'設置正確。必須按照'perl'命令之前的'export'命令。問題必須在別處。 – Lumi

相關問題