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.

È stato utile?

Soluzione

I seguenti lavorato sul mio sistema:

  1. 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).

  2. 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 cambiato main per mexFunction con i soliti argomenti e mex.h incluso.

  3. 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 nel LDFLAGS. Includono un'opzione -t modo è possibile garantire che non v'è alcuna libreria HDF5 dinamica caricata. È inoltre necessario -lz, con zlib installato. Per Darwin abbiamo anche bisogno di un -bundle in LDFLAGS:

    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
    
  4. 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 chiamo file file.h5 ottengo file.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:

  1. scarica la libreria hdf5-1.6.5 dal sito HDF5, e installare i file di intestazione in una directory locale;
  2. dica mex a cercare "hdf5.h" in questa directory locale, piuttosto che nella posizione standard (ad esempio /usr/include.)
  3. dica mex per compilare il mio codice e la libreria di oggetti condiviso fornito da MATLAB , e fare non utilizzare il flag -ldfh5 in LDFLAGS.

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 ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top