【发布时间】:2011-01-12 10:02:44
【问题描述】:
我正在尝试编写一个使用 libhdf5 的 matlab mex 函数;我的 Linux 安装提供了 libhdf5-1.8 共享库和头文件。但是,我的 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
确认。最后的手段是下载 hdf5-1.6.5 标头的本地副本并完成它,但这不是未来的证明(我将来会升级 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
所以,实际上来自/usr/lib64 的libhdf5.so 正在被引用。但是,我相信这会被环境变量 LD_LIBRARY_PATH 覆盖,我的 Matlab 版本会在运行时自动设置它,因此它可以找到自己的版本,例如libmex.so等
我认为crt_file.c 示例在 b/c 中起作用,它不使用我正在使用的功能(H5DOpen,它在从 1.6 到 1.8 的移动中具有签名更改(是的,我正在使用 @ 987654336@)),或者,不太可能,b/c 它没有击中需要 hdf5 的 Matlab 内部部件。确认。
【问题讨论】:
-
在您的输出中,我看到
lib64/libhdf5.so这是一个动态库。您需要指定静态库的显式路径(带有 .o 后缀),而不是使用-lhdf5。如果仍然无法正常工作,则发布新的链接器输出。如果.so文件是列表中唯一的一个,那么它就是唯一包含的一个。LD_LIBRARY_PATH或任何其他路径,例如-L,如果您没有-lhdf5作为选项并且明确指定静态库的路径(见下文),则无关紧要。我同意h5_crtfile.c上的 cmets,但我们需要的所有信息都在上面的链接器输出中。 -
我没有
libhdf5.o文件; gentoo 的 hdf5 包提供了libhdf5.so、libhdf5.a、libhdf5.la,以及一些fortran 和cpp 文件。我必须自己编译 libhdf5 吗?这是一个选项... -
抱歉,我指的是
.a,而不是.o。您可以通过例如检查您拥有的libhdf5.a文件是否是正确的版本。strings libhdf5.a。我看到HDF5 Version: 1.8.4在我的。如果您无法将正确的静态库作为二进制文件获取,则很容易编译。在下面查看我的 cmets 到您的其他查询。 -
strings /usr/lib64/libhdf5.a | grep 'library version'给出输出“HDF5 库版本:1.8.4 HDF5 库版本:1.8.4 ...”由于某种原因,我无法链接到静态库。关于-fPIC的同样警告 -
好的。我发现如果我关闭
-bundle会出现同样的undefined reference to 'main'错误。因此,当您调用 mex 时,您的系统上需要相当于-bundle。从手册看来,-fPIC(或-fpic)是CFLAG,(可能)-shared是LDFLAG。是的,您的标头和库 do 似乎是正确的版本。我怀疑您是否需要重新编译hdf5和-fPIC,因为在我的系统上使用-bundle一切正常。