我正在尝试编写一个使用 libhdf5 的 matlab mex 函数;我的 Linux 安装提供了 libhdf5-1.8 共享库和标头。然而,我的 Matlab 版本 r2007b 提供了 1.6 版本的 libhdf5.so。(Matlab .mat 文件 bootstrap 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

确认。最后的手段是下载 hdf5-1.6.5 标头的本地副本并使用它,但这不是面向未来的(Matlab 版本升级是我的未来。)。有任何想法吗?

编辑:根据 Ramashalanka 的出色建议,我

A)被称为 mex -v 得到 3 gcc 命令;最后是链接器命令;

B) 使用 a 调用该链接器命令 -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, , ETC。

我认为 crt_file.c 示例可以工作 b/c 它不使用我正在使用的功能(H5DOpen, ,从 1.6 到 1.8 的过程中有一个签名更改(是的,我正在使用 -DH5_USE_16_API)),或者,不太可能,b/c 它没有触及 Matlab 内部需要 hdf5 的部分。确认。

有帮助吗?

解决方案

以下内容在我的系统上有效:

  1. 安装 hdf5 版本 1.8.4(您已经这样做了:我安装了源代码并编译以确保它与我的系统兼容,我获得了 gcc 版本并且获得了静态库 - 例如为我的系统提供的二进制文件是 icc 具体的)。

  2. 制作目标文件。您已经有了自己的文件。我用的是简单的 h5_crtfile.c这里 (最好先从这个简单的文件开始寻找警告)。我变了 mainmexFunction 与通常的参数并包含 mex.h.

  3. 指定 静止的 1.8.4 您想要显式加载的库(不需要 -L 的完整路径)并且不包含 -lhdf5 在里面 LDFLAGS. 。包括一个 -t 选项,这样您就可以确保没有加载动态 hdf5 库。你还需要 -lz, , 和 zlib 安装。对于达尔文,我们还需要一个 -bundleLDFLAGS:

    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
    
  4. 跑过 h5_crtfile 墨西哥文件。这在我的机器上运行没有问题。它只是执行 H5Fcreate 和 H5Fclose 在当前目录中创建“file.h5”,当我调用 file file.h5 我明白了 file.h5: Hierarchical Data Format (version 5) data.

请注意,如果我包括 -lhdf5 上面的步骤 3 中,然后当我尝试运行可执行文件时,matlab 中止(因为它随后使用 matlab 的动态库,对我来说版本是 1.6.5),所以这肯定解决了我的系统上的问题。

谢谢你的提问。我上面的解决方案对我来说肯定比我之前所做的要容易得多。希望以上内容对您有用。

其他提示

我接受 Ramashalanka 的答案,因为它引导我找到了确切的解决方案,我将在这里发布该解决方案只是为了完整性:

  1. 从hdf5网站下载hdf5-1.6.5库,并将头文件安装在本地目录中;
  2. 告诉 mex 在此本地目录中查找“hdf5.h”,而不是在标准位置(例如 /usr/include.)
  3. 告诉 mex 编译我的代码 以及matlab提供的共享对象库, ,并做 不是 使用 -ldfh5 标记在 LDFLAGS.

我使用的命令本质上是:

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

这个解决方案应该适用于我所有的各种目标机器,至少在我升级到 matlab r2009a 之前,我相信它使用 hdf5-1.8。感谢您的所有帮助,很抱歉对此如此密集 - 我认为我过度致力于使用 hdf5 的打包版本,而不是本地的头文件集。

请注意,如果 Mathworks 随 Matlab 发行版提供了一组头文件,那么这一切都将变得微不足道...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top