condiviso posizioni delle librerie per i file MATLAB mex:
Domanda
Sto cercando di scrivere una funzione MATLAB mex che utilizza libhdf5; Il mio Linux installare fornisce librerie e header libhdf5-1.8 condiviso. Tuttavia, la mia versione di Matlab, R2007b, fornisce un libhdf5.so dal rilascio 1.6. (File .mat
Matlab bootstrap HDF5, evidentemente). Quando compilo il mex, si segfaults in Matlab. Se io downgrade la mia versione di libhdf5 a 1,6 (non un'opzione a lungo termine), la compila codice e viene eseguito bene.
domanda: come faccio a risolvere questo problema? Come faccio a dire il processo di compilazione mex di collegamento contro /usr/lib64/libhdf5.so.6 invece di /opt/matlab/bin/glnxa64/libhdf5.so.0? Quando provo a farlo usando -Wl,-rpath-link,/usr/lib64
nella mia compilation, ricevo errori come:
/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. l'ultima risorsa sarebbe quella di scaricare una copia locale delle intestazioni hdf5-1.6.5 e da fare con esso, ma questo non è a prova di futuro (un aggiornamento di versione di Matlab è nel mio futuro.). tutte le idee?
EDIT: per suggerimenti eccellenti di Ramashalanka, I
A) chiamato mex -v
per ottenere i comandi 3 gcc
; l'ultimo è il comando del linker;
B) chiamato così di comando del linker con un -v
per ottenere il comando collect
;
C) chiamato così collect2 -v -t
e il resto delle bandiere.
Le parti rilevanti della mia uscita:
/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
Quindi, in realtà il libhdf5.so
da /usr/lib64
viene fatto riferimento. Tuttavia, questo è stato sovrascritto, credo, dal LD_LIBRARY_PATH
variabile d'ambiente, che la mia versione di Matlab automagicamente set in fase di esecuzione in modo da poter individuare le proprie versioni di esempio libmex.so
, ecc.
Sto pensando che l'esempio crt_file.c
funziona sia b / c non usa le funzioni che sto usando (H5DOpen
, che ha avuto un cambiamento di firma nel passaggio 1,6-1,8 (sì, sto usando -DH5_USE_16_API
)), o , meno probabile, b / c non ha colpito le parti di interni Matlab quel bisogno HDF5. ACK.
Soluzione
I seguenti lavorato sul mio sistema:
-
Installa HDF5 versione 1.8.4 (hai già fatto questo: ho installato la fonte e compilato per assicurarsi che sia compatibile con il mio sistema, che ricevo le versioni di gcc e che ottengo le librerie statiche - ad esempio, il binari offerti per il mio sistema sono
icc
specifica). -
Crea un file di destinazione. Hai già un tuo file. Ho usato il semplice
h5_crtfile.c
da qui (una buona idea per iniziare con questo semplice file prima un'occhiata per gli avvisi). Ho cambiatomain
permexFunction
con i soliti argomenti emex.h
incluso. -
Specificare il static 1.8.4 libreria che si desidera caricare in modo esplicito (il percorso completo senza -L per esso necessario) e non includono
-lhdf5
nelLDFLAGS
. Includono un'opzione-t
modo è possibile garantire che non v'è alcuna libreria HDF5 dinamica caricata. È inoltre necessario-lz
, conzlib
installato. Per Darwin abbiamo anche bisogno di un-bundle
inLDFLAGS
:mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v
Per Linux, è necessario un invito indipendente dalla posizione equivalente, per esempio
fPIC
e forse-shared
, ma non ho un sistema Linux con una licenza MATLAB, quindi non posso controllare:mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
-
Esegui il file
h5_crtfile
mex. Questo viene eseguito senza problemi sulla mia macchina. Lo fa solo un H5Fcreate e H5Fclose per creare "file.h5" nella directory corrente, e quando chiamofile file.h5
ottengofile.h5: Hierarchical Data Format (version 5) data
.
Si noti che se includo un -lhdf5
sopra al punto 3, quindi di interrompere la MATLAB, quando si tenta di eseguire il file eseguibile (perché poi utilizza le librerie dinamiche di MATLAB che per me sono la versione 1.6.5), quindi questo è sicuramente la soluzione del problema sul mio sistema.
Grazie per la domanda. La mia soluzione di cui sopra è sicuramente molto più facile per me di quello che facevo prima. Speriamo che i lavori di cui sopra per voi.
Altri suggerimenti
sto accettando la risposta di Ramashalanka perché mi ha portato alla soluzione esatta, che mi post qui solo per completezza:
- scarica la libreria hdf5-1.6.5 dal sito HDF5, e installare i file di intestazione in una directory locale;
- dica mex a cercare "hdf5.h" in questa directory locale, piuttosto che nella posizione standard (ad esempio
/usr/include
.) - dica mex per compilare il mio codice e la libreria di oggetti condiviso fornito da MATLAB , e fare non utilizzare il flag
-ldfh5
inLDFLAGS
.
il comando che ho usato è, in sostanza:
/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
questo viene tradotto da mex nei comandi:
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++
questa soluzione dovrebbe funzionare su tutte le mie diverse macchine di destinazione e almeno fino a quando aggiorno a MATLAB R2009a, che credo usi hdf5-1.8. grazie per tutto l'aiuto, mi dispiace per essere così densa di questo - penso di essere stato eccessivamente impegnato a utilizzare la versione pacchettizzata di HDF5, piuttosto che un insieme locale dei file di intestazione.
Nota questo sarebbe tutto stato banale se Mathworks aveva fornito una serie di file di intestazione con la distribuzione Matlab ...