Расположение общих библиотек для файлов MATLAB MEX: - PullRequest
10 голосов
/ 03 февраля 2010

Я пытаюсь написать mex-функцию matlab, которая использует libhdf5; Моя установка Linux предоставляет совместно используемые библиотеки и заголовочные файлы libhdf5-1.8. Тем не менее, моя версия Matlab, r2007b, содержит libhdf5.so из версии 1.6. (Matlab .mat файлы начальной загрузки hdf5, очевидно). Когда я компилирую mex, он в Segfaults в Matlab. Если я понижаю версию libhdf5 до версии 1.6 (не для долгосрочной версии), код компилируется и работает нормально.

вопрос: как мне решить эту проблему? Как мне сказать, чтобы процесс компиляции 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

извед. В крайнем случае следует загрузить локальную копию заголовков hdf5-1.6.5 и покончить с этим, но это не является перспективой (обновление версии Matlab будет в моем будущем.). есть идеи?

РЕДАКТИРОВАТЬ: за отличные предложения Рамашаланки, я

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

Итак, на самом деле на libhdf5.so из /usr/lib64 ссылаются. Однако, я полагаю, это переопределяется переменной окружения LD_LIBRARY_PATH, которую моя версия Matlab автоматически устанавливает во время выполнения, чтобы он мог найти свои собственные версии, например. libmex.so и т. Д.

Я думаю, что пример crt_file.c работает либо b / c, он не использует функции, которые я использую (H5DOpen, у которого было изменение сигнатуры при переходе с 1.6 на 1.8 (да, я использую -DH5_USE_16_API)), или, что менее вероятно, b / c не затрагивает части внутреннего пространства Matlab, для которых требуется hdf5. извед.

Ответы [ 2 ]

8 голосов
/ 03 февраля 2010

В моей системе работали:

  1. Установите hdf5 версии 1.8.4 (вы уже сделали это: я установил исходный код и скомпилировал его, чтобы убедиться, что он совместим с моей системой, что я получаю версии gcc и что я получаю статические библиотеки - например, двоичные файлы, предлагаемые для моей системы, icc специфичны).

  2. Создать целевой файл. У вас уже есть свой файл. Я использовал простой h5_crtfile.c из здесь (хорошая идея, чтобы начать с этого простого файла, сначала посмотрите на предупреждения). Я изменил main на mexFunction с обычными аргументами и включил mex.h.

  3. Укажите статическую 1.8.4 библиотеку, которую вы хотите явно загрузить (полный путь без -L для этого необходимо) и не включайте -lhdf5 в LDFLAGS. Включите параметр -t, чтобы убедиться, что динамическая библиотека hdf5 не загружается. Вам также нужно -lz, с установленным zlib. Для Дарвина нам также нужно -bundle в LDFLAGS:

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

    Для linux вам необходим эквивалентный независимый от позиции вызов, например, fPIC и, возможно, -shared, но у меня нет системы linux с лицензией matlab, поэтому я не могу проверить:

    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.

Обратите внимание, что если я включу -lhdf5 выше в шаге 3, то Matlab прерывается, когда я пытаюсь запустить исполняемый файл (потому что тогда он использует динамические библиотеки Matlab, которые для меня версии 1.6.5), так что это определенно решает проблема в моей системе.

Спасибо за вопрос. Мое решение выше определенно намного проще для меня, чем то, что я делал раньше. Надеюсь, вышесказанное работает для вас.

3 голосов
/ 09 февраля 2010

Я принимаю ответ Рамашаланки, потому что он привел меня к точному решению, которое я опубликую здесь только для полноты:

  1. загрузите библиотеку hdf5-1.6.5 с веб-сайта hdf5 и установитефайлы заголовков в локальном каталоге;
  2. заставляет mex искать «hdf5.h» в этом локальном каталоге, а не в стандартном месте (например, /usr/include.)
  3. .скомпилируйте мой код и библиотеку общих объектов, предоставляемую matlab , и выполните not , используя флаг -ldfh5 в LDFLAGS.

в команде Iиспользуется, по сути:

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

это решение должно работать на всех моих различных целевых машинах и по крайней мере до тех пор, пока я не обновлюсь до matlabr2009a, который я считаю, использует hdf5-1.8.спасибо за всю помощь, извините за то, что я был настолько плотен с этим - я думаю, что я был чрезмерно привержен использованию упакованной версии hdf5, а не локального набора заголовочных файлов.

Обратите внимание, что все это было бы тривиально, если бы Mathworks предоставил набор файлов заголовков для дистрибутива Matlab ...

...