我正在尝试编写一个使用libhdf5的matlab mex函数;我的Linux安装提供了libhdf5-1.8共享库和 header 。但是,我的Matlab版本r2007b从1.6版本开始提供了libhdf5.so。 (显然,Matlab的.mat文件引导了hdf5)。当我编译mex时,在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

ack。不得已的方法是下载hdf5-1.6.5 header 的本地副本并完成此操作,但这并不是 future 的证明(我将来会进行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

因此,实际上正在引用libhdf5.so中的/usr/lib64。但是,我相信环境变量LD_LIBRARY_PATH已覆盖了该变量,我的Matlab版本在运行时自动设置了该变量,以便可以定位自己的版本。 libmex.so

我认为crt_file.c示例可以在不使用我正在使用的功能的情况下运行(H5DOpen,它在从1.6到1.8的过程中发生了签名更改(是的,我在使用-DH5_USE_16_API)),或者不太可能,因为它没有碰到需要hdf5的Matlab内部零件。 ack。

最佳答案

以下在我的系统上工作:

  • 安装hdf5版本1.8.4(您已经完成了此操作:安装了源代码并进行编译,以确保它与我的系统兼容,获得gcc版本并获得静态库-例如,为系统提供的二进制文件特定于icc)。
  • 制作目标文件。您已经拥有了自己的文件。我使用了here中的简单h5_crtfile.c(从这个简单的文件开始,首先是一个警告提示的好主意)。我使用通常的args将main更改为mexFunction,并包含了mex.h
  • 指定要显式加载的静态1.8.4库(完整路径,必要时不带-L),并且在-lhdf5中不要包括LDFLAGS。包括-t选项,以便您可以确保没有正在加载的动态hdf5库。您还需要安装-lzzlib。对于darwin,我们还需要-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,但是我没有具有matlab许可证的linux系统,所以我无法检查:
    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
    
  • 运行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),因此,这肯定可以解决系统上的问题。

    谢谢你的问题。对于我来说,上述解决方案绝对比以前做起来容易得多。希望以上对您有用。

    10-08 09:47
    查看更多