2010-02-02 76 views
9

我想寫一個使用libhdf5的matlab mex函數;我的Linux安裝提供了libhdf5-1.8共享庫和頭文件。不過,我的Matlab版本r2007b在1.6版本中提供了libhdf5.so。 (顯然,Matlab .mat文件bootstrap hdf5)。當我編譯mex時,它在Matlab中進行段錯誤。如果我將我的libhdf5版本降級到1.6(不是長期選項),代碼編譯並運行良好。共享庫位置爲matlab mex文件:

問題:我該如何解決這個問題?如何告訴mex編譯過程鏈接到/usr/lib64/libhdf5.so.6而不是/opt/matlab/bin/glnxa64/libhdf5.so.0?當我嘗試在我的編譯做到這一點使用-Wl,-rpath-link,/usr/lib64,我得到這樣的錯誤:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libhdf5.so.0, needed by /opt/matlab/matlab75/bin/glnxa64/libmat.so, may conflict with libhdf5.so.6 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crt1.o: In function `_start': 
(.text+0x20): undefined reference to `main' 
collect2: ld returned 1 exit status 

    mex: link of 'hdf5_read_strings.mexa64' failed. 

make: *** [hdf5_read_strings.mexa64] Error 1 

ACK。最後的辦法是下載hdf5-1.6.5頭文件的本地副本並完成它,但這不是未來的證明(我將來會進行一次Matlab版本升級)。有任何想法嗎?

編輯:每Ramashalanka的很好的建議,我

A)稱爲mex -v拿到3個gcc命令;最後一個是鏈接器命令; B)用-v調用該鏈接器命令以獲得collect命令;

C)稱爲collect2 -v -t和其餘的標誌。

我輸出的相關部分:

/usr/bin/ld: mode elf_x86_64 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crti.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtbeginS.o 
hdf5_read_strings.o 
mexversion.o 
-lmx (/opt/matlab/matlab75/bin/glnxa64/libmx.so) 
-lmex (/opt/matlab/matlab75/bin/glnxa64/libmex.so) 
-lhdf5 (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libhdf5.so) 
/lib64/libz.so 
-lm (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libm.so) 
-lstdc++ (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libstdc++.so) 
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so) 
/lib64/libpthread.so.0 
/lib64/libc.so.6 
/lib64/ld-linux-x86-64.so.2 
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so) 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtendS.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crtn.o 

所以,實際上從/usr/lib64libhdf5.so被引用。然而,我相信這是由環境變量LD_LIBRARY_PATH覆蓋,我的Matlab版本在運行時自動設置,因此它可以找到它自己的版本,例如, libmex.so

我想到的是,crt_file.c例如,c它不使用我使用的是的,我使用的功能(H5DOpen,其中有從1.6遷移到1.8的簽名更改(無論是工作B/-DH5_USE_16_API)),或者不太可能,b/c它不會碰到需要hdf5的Matlab內部部分。 ACK。

+0

在輸出我看到'lib64的/ libhdf5.so'這是一個動態庫。您需要爲靜態庫指定顯式路徑(帶有.o後綴),而不是使用「-lhdf5」。然後發佈新的鏈接器輸出,如果它仍然沒有工作。如果'.so'文件是列表中唯一的文件,那麼這是唯一包含的文件。如果你沒有'-lhdf5'作爲選項,並且你明確指定了靜態庫的路徑(見下文),'LD_LIBRARY_PATH'或者任何其他的路徑,比如'-L'中的路徑應該沒有問題。我同意你對'h5_crtfile.c'的評論,但是我們需要的所有信息都在上面的鏈接器輸出中。 – Ramashalanka 2010-02-05 00:43:01

+0

我沒有'libhdf5.o'文件; gentoo的hdf5包提供'libhdf5.so','libhdf5.a','libhdf5.la',以及一些fortran和cpp文件。我必須自己編譯libhdf5嗎?這是一個選項... – shabbychef 2010-02-05 01:16:28

+0

對不起,我的意思是'.a',而不是'.o'。你可以檢查你的libhdf5.a文件是否是正確的版本。 '字符串libhdf5.a'。我在我的視頻中看到了'HDF5 Version:1.8.4'。如果無法將正確的靜態庫作爲二進制文件獲取,則編譯起來很容易。在下面查看我的評論。 – Ramashalanka 2010-02-05 01:28:52

回答

8

以下我的系統上工作:

  1. 安裝HDF5 1.8.4版本(你已經做到了這一點:我安裝的來源和編制,以確保它是與我的系統兼容,我得到gcc版本和我得到的靜態庫 - 例如我的系統提供的二進制文件是icc具體)。

  2. 製作目標文件。您已擁有自己的文件。我使用here的簡單h5_crtfile.c(一個好主意,首先從這個簡單的文件開始尋找警告)。我使用通常的參數將main更改爲mexFunction,其中包括mex.h

  3. 指定要(而且不需要-L爲它的完整路徑)來加載明確,不包括在LDFLAGS-lhdf5靜態 1.8.4庫。包含一個-t選項,以便確保沒有加載動態hdf5庫。您還需要-lz,並安裝了zlib。達爾文我們還需要一個-bundleLDFLAGS

    mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v 
    

    對於Linux,需要一個相當的位置無關的呼叫,例如fPIC也許-shared,但我沒有用MATLAB許可證Linux系統,所以我無法檢查:

    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v 
    
  4. 運行h5_crtfile MEX文件。這在我的機器上運行時沒有問題。它只是做一個H5Fcreate和H5Fclose在當前目錄中創建「file.h5」,當我撥打file file.h5時,我得到file.h5: Hierarchical Data Format (version 5) data

需要注意的是,如果我包括以上步驟3中-lhdf5,則MATLAB中止,當我嘗試運行可執行文件(因爲它然後使用MATLAB的動態庫這對我來說是1.6.5版本),所以這是絕對可以解決我係統中的問題。

感謝您的提問。上面的解決方案對我來說肯定比我之前做的更容易。希望上面的作品適合你。

+0

嗯。當我嘗試這個時,編譯失敗b/c'libmat.so'依賴'libhdf5.so'。有些奇怪的地方。不幸的是,我不能在沒有拉入Mathworks的hdf5的情況下包含'mex.h';令人遺憾的是,Mathworks發佈的頭文件不包含'hdf5.h'。 – shabbychef 2010-02-03 18:59:33

+0

好的,我已經重寫了這篇文章,看看那是怎麼回事。 – Ramashalanka 2010-02-03 23:33:49

+0

我在shell中用gcc命令吐出了mex。所以我嘗試了你的解決方案,使用'h5_crtfile.c'跳過步驟2 & 3;('-bundle'是達爾文特定的,BTW),我得到「警告!這個應用程序包含的HDF5頭文件不匹配 版本如果應用程序繼續,則可能發生損壞或分段錯誤 'HDF5_DISABLE_VERSION_CHECK'環境變量集,應用程序將 繼續。 標題爲1.8.4,庫爲1.6.5「 然而,'file.h5'被創建!但是,用我的mex這個技巧,它仍然是段錯誤。 – shabbychef 2010-02-04 19:38:33

3

我接受Ramashalanka的答案,因爲它使我確切的解決方案,我將張貼在這裏只有完整性:

  1. 下載從HDF5網站hdf5-1.6.5庫,並安裝頭文件在本地目錄中;
  2. 告訴MEX尋找「hdf5.h」這個本地目錄中,而不是在標準的位置(例如/usr/include
  3. 告訴MEX編譯我的代碼和MATLAB提供的共享對象庫,並不是使用LDFLAGS中的-ldfh5標誌。

我用的命令是,主要有:

/opt/matlab/matlab_default/bin/mex -v CC#gcc CXX#g++ CFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include" CXXFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include " -O -lmwblas -largeArrayDims -L/usr/lib64 hdf5_read_strings.c /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 

此得到由MEX翻譯成命令:

gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG hdf5_read_strings.c 
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG /opt/matlab/matlab75/extern/src/mexversion.c 
gcc -O -pthread -shared -Wl,--version-script,/opt/matlab/matlab75/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o hdf5_read_strings.mexa64 hdf5_read_strings.o mexversion.o -lmwblas -L/usr/lib64 /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 -Wl,-rpath-link,/opt/matlab/matlab_default/bin/glnxa64 -L/opt/matlab/matlab_default/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++ 

這個解決方案應該對所有我的各種目標機器和至少工作直到我升級到matlab r2009a,我相信它使用hdf5-1.8。感謝所有的幫助,對於這麼密集感到抱歉 - 我認爲我過分致力於使用hdf5的打包版本,而不是本地的一套頭文件。

注意那麼這一切已經平凡的,如果Mathworks公司提供了一組與Matlab的分佈的頭文件...

+0

這就是我如何處理需要鏈接boost-thread的多線程mex文件。但是必須有一些方法可以讓它連接到系統庫而不是Matlab內部的庫,並避免這種段錯誤。被卡在Matlab裏面的任何提升都不是很好。 – Chinasaur 2012-07-03 08:45:03

+0

關於Ramashalanka的有用建議,我也可以說我的boost-thread鏈接情況下,我不得不在Linux中做這個解決方法,但不是在Mac中;在Mac中,似乎mex命令不像內部版本那樣在Linux中鏈接。 – Chinasaur 2012-07-03 08:47:08

+1

就像這裏的答案:http://stackoverflow.com/questions/9927568/compiling-c11-code-as-part-of-a-matlab-mex-file可能工作(雖然問題是有點不同) 。我會報告回來,如果我得到它的工作。 – Chinasaur 2012-07-03 09:03:11