我正在尝试编写一个使用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
ACK。最后一种方法是下载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
因此,实际上正在引用来自libhdf5.so
的{{1}}。但是,我相信这是由环境变量/usr/lib64
覆盖的,我的Matlab版本在运行时自动设置,因此它可以找到自己的版本,例如LD_LIBRARY_PATH
等等。
我认为libmex.so
示例或者b / c它不使用我正在使用的函数(crt_file.c
,它在从1.6到1.8的移动中有一个签名变化(是的,我正在使用H5DOpen
)),或者,不太可能,b / c它没有达到需要hdf5的Matlab内部部分。 ACK。
答案 0 :(得分:8)
以下内容适用于我的系统:
安装hdf5版本1.8.4(你已经完成了这个:我安装了源代码并进行了编译以确保它与我的系统兼容,我获得了gcc版本并获得了静态库 - 例如为我的系统提供的二进制文件是icc
特定的。
制作目标文件。您已拥有自己的文件。我使用了来自here的简单h5_crtfile.c
(最好先从这个简单的文件开始查看警告)。我使用通常的参数将main
更改为mexFunction
并包含mex.h
。
指定要显式加载的静态 1.8.4库(必须没有-L的完整路径),并且不要在-lhdf5
中包含LDFLAGS
{1}}。包含-t
选项,以确保没有加载动态hdf5库。您还需要安装-lz
的{{1}}。对于达尔文,我们还需要zlib
中的-bundle
:
LDFLAGS
对于Linux,您需要一个等效的与位置无关的调用,例如mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v
也许fPIC
,但我没有带有matlab许可证的linux系统,所以我无法检查:
-shared
运行mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
mex文件。这在我的机器上运行没有问题。它只是在当前目录中创建一个H5Fcreate和H5Fclose来创建“file.h5”,当我调用h5_crtfile
时,我得到file file.h5
。
请注意,如果我在步骤3中包含file.h5: Hierarchical Data Format (version 5) data
,那么当我尝试运行可执行文件时,matlab就会中止(因为它然后使用了matlab的动态库,对我来说是版本1.6.5),所以这是肯定解决了我系统上的问题。
感谢您的提问。对我来说,上面的解决方案对我来说比以前更容易。希望上述内容适合您。
答案 1 :(得分:3)
我接受Ramashalanka的答案,因为它引导我找到确切的解决方案,我将在此处仅为了完整性而发布:
/usr/include
)。)-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分发的头文件,那么这一切都是微不足道的......