matlab mex 文件的共享库位置:
我正在尝试编写一个使用 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
因此,实际上正在引用 /usr/lib64
中的 libhdf5.so
。然而,我相信,这被环境变量 LD_LIBRARY_PATH 覆盖,我的 Matlab 版本在运行时自动设置该环境变量,以便它可以找到自己的版本,例如 libmex.so< /code> 等。
我认为 crt_file.c
示例可以工作,因为它不使用我正在使用的函数(H5DOpen
,它有一个签名从 1.6 到 1.8 的变化(是的,我正在使用 -DH5_USE_16_API
)),或者,不太可能,b/c 它没有触及需要 hdf5 的 Matlab 内部部分。确认。
I am trying to write a matlab mex function which uses libhdf5; My Linux install provides libhdf5-1.8 shared libraries and headers. However, my version of Matlab, r2007b, provides a libhdf5.so from the 1.6 release. (Matlab .mat
files bootstrap hdf5, evidently). When I compile the mex, it segfaults in Matlab. If I downgrade my version of libhdf5 to 1.6 (not a long-term option), the code compiles and runs fine.
question: how do I solve this problem? how do I tell the mex compilation process to link against /usr/lib64/libhdf5.so.6 instead of /opt/matlab/bin/glnxa64/libhdf5.so.0 ? When I try to do this using -Wl,-rpath-link,/usr/lib64
in my compilation, I get errors like:
/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. the last resort would be to download a local copy of the hdf5-1.6.5 headers and be done with it, but this is not future proof (a Matlab version upgrade is in my future.). any ideas?
EDIT: per Ramashalanka's excellent suggestions, I
A) called mex -v
to get the 3 gcc
commands; the last is the linker command;
B) called that linker command with a -v
to get the collect
command;
C) called that collect2 -v -t
and the rest of the flags.
The relevant parts of my output:
/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
So, in fact the libhdf5.so
from /usr/lib64
is being referenced. However, this is being overriden, I believe, by the environment variable LD_LIBRARY_PATH
, which my version of Matlab automagically sets at run-time so it can locate its own versions of e.g. libmex.so
, etc.
I am thinking that the crt_file.c
example works either b/c it does not use the functions I am using (H5DOpen
, which had a signature change in the move from 1.6 to 1.8 (yes, I am using -DH5_USE_16_API
)), or, less likely, b/c it does not hit the parts of Matlab internals that need hdf5. ack.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下内容在我的系统上有效:
安装 hdf5 版本 1.8.4(您已经完成了此操作:我安装了源代码并编译以确保它与我的系统兼容,我获得了 gcc 版本并且获得了静态库 - 例如,为我的系统提供的二进制文件是
icc
特定的)。制作目标文件。您已经有了自己的文件。我使用了此处<的简单
h5_crtfile.c
/a> (首先从这个简单文件开始查看警告是个好主意)。我使用通常的参数将main
更改为mexFunction
并包含mex.h
。指定您想要显式加载的静态 1.8.4 库(不需要 -L 的完整路径),并且不要在文件中包含
-lhdf5
LDFLAGS
。包含-t
选项,以便确保没有加载动态 hdf5 库。您还需要安装了zlib
的-lz
。对于 darwin,我们还需要LDFLAGS
中的-bundle
:对于Linux,您需要一个等效的位置无关调用,例如
fPIC
,也许还有-shared
,但我没有带有matlab许可证的Linux系统,所以我无法检查:运行
h5_crtfile
mex 文件。这在我的机器上运行没有问题。它只是执行 H5Fcreate 和 H5Fclose 在当前目录中创建“file.h5”,当我调用file file.h5
时,我得到file.h5: Hierarchical Data Format (version 5)数据
。请注意,如果我在上面的步骤 3 中包含
-lhdf5
,那么当我尝试运行可执行文件时,matlab 会中止(因为它随后使用 matlab 的动态库,对我来说版本是 1.6.5),所以这绝对可以解决我的系统上的问题。谢谢你的提问。我上面的解决方案对我来说肯定比我之前所做的要容易得多。希望以上内容对您有用。
The following worked on my system:
Install hdf5 version 1.8.4 (you've already done this: I installed the source and compiled to ensure it is compatible with my system, that I get gcc versions and that I get the static libraries - e.g. the binaries offered for my system are
icc
specific).Make a target file. You already have your own file. I used the simple
h5_crtfile.c
from here (a good idea to start with this simple file first a look for warnings). I changedmain
tomexFunction
with the usual args and includedmex.h
.Specify the static 1.8.4 library you want to load explicitly (the full path with no -L for it necessary) and don't include
-lhdf5
in theLDFLAGS
. Include a-t
option so you can ensure that there is no dynamic hdf5 library being loaded. You also need-lz
, withzlib
installed. For darwin we also need a-bundle
inLDFLAGS
:For linux, you need an equivalent position-independent call, e.g.
fPIC
and maybe-shared
, but I don't have a linux system with a matlab license, so I can't check:Run the
h5_crtfile
mex file. This runs without problems on my machine. It just does a H5Fcreate and H5Fclose to create "file.h5" in the current directory, and when I callfile file.h5
I getfile.h5: Hierarchical Data Format (version 5) data
.Note that if I include a
-lhdf5
above in step 3, then matlab aborts when I try to run the executable (because it then uses matlab's dynamic libraries which for me are version 1.6.5), so this is definitely solving the problem on my system.Thanks for the question. My solution above is definitely much easier for me than what I was doing before. Hopefully the above works for you.
我接受 Ramashalanka 的答案,因为它引导我找到了确切的解决方案,我将在这里发布该解决方案只是为了完整性:
/usr/include
)。LDFLAGS
中使用-ldfh5
标志。我使用的命令本质上是:
这由 mex 翻译成命令:
这个解决方案应该适用于我所有的各种目标机器,至少在我升级到 matlab r2009a 之前,我相信它使用 hdf5-1.8。感谢您的所有帮助,很抱歉对此如此密集 - 我认为我过度致力于使用 hdf5 的打包版本,而不是本地的头文件集。
请注意,如果 Mathworks 随 Matlab 发行版提供了一组头文件,那么这一切都将变得微不足道...
I am accepting Ramashalanka's answer because it led me to the exact solution which I will post here for completeness only:
/usr/include
.)-ldfh5
flag inLDFLAGS
.the command I used is, essentially:
this gets translated by mex into the commands:
this solution should work on all my various target machines and at least until I upgrade to matlab r2009a, which I believe uses hdf5-1.8. thanks for all the help, sorry for being so dense with this--I think I was overly-committed to using the packaged version of hdf5, rather than a local set of header files.
Note this would all have been trivial if Mathworks had provided a set of the header files with the Matlab distribution...