Pregunta

Estoy intentando escribir una función MATLAB mex que utiliza libhdf5; Mi instalación de Linux proporciona bibliotecas y cabeceras libhdf5-1.8 compartido. Sin embargo, mi versión de Matlab, R2007b, proporciona una libhdf5.so de la versión 1.6. (Archivos de arranque .mat Matlab hdf5, evidentemente). Cuando compilo el mex, que segfaults en Matlab. Si Downgrade mi versión de libhdf5 a 1.6 (no es una opción a largo plazo), el código se compila y se ejecuta bien.

pregunta: ¿cómo puedo solucionar este problema? ¿cómo le digo el proceso de compilación mex enlazar con /usr/lib64/libhdf5.so.6 en lugar de /opt/matlab/bin/glnxa64/libhdf5.so.0? Cuando trato de hacer esto utilizando -Wl,-rpath-link,/usr/lib64 en mi compilación, consigo errores como:

/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. el último recurso sería para descargar una copia local de los encabezados hdf5-1.6.5 y acabar de una vez, pero esto no es a prueba del futuro (una actualización de versión de Matlab está en mi futuro.). Algunas ideas?

EDIT: por excelentes sugerencias de Ramashalanka, I

A) denominado mex -v para obtener los comandos 3 gcc; el último es el comando enlazador;

B) llama ese comando con un enlazador -v para obtener el comando collect;

C) que llama collect2 -v -t y el resto de las banderas.

Las partes pertinentes de mi producción:

/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

Así que, de hecho, se está haciendo referencia al libhdf5.so de /usr/lib64. Sin embargo, esto está siendo anulado, creo, por la LD_LIBRARY_PATH variable de entorno, que mi versión de Matlab automágicamente conjuntos en tiempo de ejecución para que pueda ubicar sus propias versiones de ejemplo libmex.so, etc.

Pienso que el ejemplo crt_file.c funciona bien b / c que no utiliza las funciones que estoy usando (H5DOpen, que tenía un cambio de la firma en el paso de 1.6 a 1.8 (sí, estoy usando -DH5_USE_16_API)), o , menos probable, b / c que no golpea las partes internas de Matlab que hdf5 necesidad. ack.

¿Fue útil?

Solución

A continuación trabajó en mi sistema:

  1. Instalar la versión 1.8.4 hdf5 (ya has hecho esto: He instalado la fuente y compilado para asegurarse de que es compatible con mi sistema, que consigo versiones de gcc y que me da las bibliotecas estáticas - por ejemplo, el binarios que se ofrecen para mi sistema son específicos icc).

  2. Hacer un archivo de destino. Ya tiene su propio archivo. He utilizado el h5_crtfile.c sencillo desde aquí (una idea buena para empezar con este simple archivo primero un vistazo a las advertencias). He cambiado main a mexFunction con los argumentos habituales y mex.h incluido.

  3. Especifique el estática 1.8.4 biblioteca que desea cargar explícitamente (la ruta completa sin -L para ello es necesario) y no incluyen -lhdf5 en el LDFLAGS. Incluir una opción -t por lo que puede asegurarse de que no hay ninguna biblioteca hdf5 dinámica que se está cargando. También es necesario -lz, con zlib instalado. Para Darwin también necesitamos un -bundle en LDFLAGS:

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

    Para Linux, necesita una llamada independiente de la posición equivalente, por ejemplo, fPIC y tal vez -shared, pero no tengo un sistema Linux con una licencia de Matlab, así que no puedo comprobar:

    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
    
  4. Ejecutar el archivo h5_crtfile Mex. Esto se ejecuta sin problemas en mi máquina. Simplemente hace un H5Fcreate y H5Fclose para crear "file.h5" en el directorio actual, y cuando llamo file file.h5 consigo file.h5: Hierarchical Data Format (version 5) data.

Tenga en cuenta que si incluyo un -lhdf5 anteriormente en el paso 3, a continuación, aborta MATLAB cuando trato de ejecutar el archivo ejecutable (ya que a continuación, utiliza las librerías dinámicas de MATLAB que para mí son la versión 1.6.5), así que esto es definitivamente la solución del problema en mi sistema.

Gracias por la pregunta. Mi solución anterior es sin duda mucho más fácil para mí que lo que estaba haciendo antes. Espero que los trabajos anteriores para usted.

Otros consejos

Estoy aceptando la respuesta de Ramashalanka porque me llevó a la solución exacta que voy a publicar aquí para completar solamente:

  1. descargar la biblioteca hdf5-1.6.5 desde el sitio web hdf5, e instalar los archivos de cabecera en un directorio local;
  2. diga mex para buscar "hdf5.h" en este directorio local, en lugar de en la ubicación estándar (por ejemplo /usr/include.)
  3. diga mex para compilar el código y la biblioteca de objetos compartidos proporcionada por MATLAB , y hacer no usar la bandera -ldfh5 en LDFLAGS.

el comando que utiliza es, en esencia:

/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

Esto se traduce por mex en los comandos:

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

esta solución debería funcionar en todos mis varios equipos de destino y al menos hasta migrar a Matlab R2009a, que creo que hdf5-1.8 usos. gracias por toda la ayuda, lo siento por ser tan densa con esto - creo que estaba excesivamente comprometido con el uso de la versión empaquetada de hdf5, en lugar de un conjunto local de los archivos de cabecera.

Tenga en cuenta esto habría sido todo si trivial si Mathworks había proporcionado un conjunto de los ficheros de cabecera con la distribución de Matlab ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top