代码之家  ›  专栏  ›  技术社区  ›  shabbychef

Matlab Mex文件的共享库位置:

  •  10
  • shabbychef  · 技术社区  · 16 年前

    我正在尝试编写一个使用libhdf5的matlab mex函数;我的Linux安装程序提供libhdf5-1.8共享库和头文件。但是,我的matlab版本r2007b提供了1.6版本的libhdf5.so。(Matlab) .mat 文件引导HDF5,显然)。当我编译mex时,它会在matlab中进行segfaults。如果我将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 /usr/lib64 正在引用。然而,我相信,这正被环境变量所覆盖。 LD_LIBRARY_PATH ,我的matlab版本在运行时自动设置,以便它可以找到自己的版本,例如 libmex.so 等。

    我认为 crt_file.c 示例既适用于b/c,也不适用于我使用的函数( H5DOpen 在从1.6到1.8的移动中有一个签名更改(是的,我正在使用 -DH5_USE_16_API )或者,不太可能是B/C,它不会撞击到需要HDF5的matlab内部部件。ACK。

    2 回复  |  直到 16 年前
        1
  •  8
  •   Ramashalanka    16 年前

    以下内容适用于我的系统:

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

    2. 生成目标文件。你已经有了自己的文件。我用了简单的 h5_crtfile.c here (最好从这个简单的文件开始,首先查找警告)。我变了 main mexFunction 包含常规参数 mex.h .

    3. 指定 静止的 1.8.4要显式加载的库(不需要-l的完整路径),不包括 -lhdf5 LDFLAGS . 包括一个 -t 选项,这样您就可以确保不加载动态HDF5库。你也需要 -lz zlib 安装。对于达尔文,我们还需要 -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
      
    4. 运行 h5_crtfile MEX文件。这在我的机器上运行没有问题。它只是执行h5fcreate和h5fclose在当前目录中创建“file.h5”,当我调用 file file.h5 我得到 file.h5: Hierarchical Data Format (version 5) data .

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

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

        2
  •  3
  •   shabbychef    16 年前

    我接受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分发版的话,这一切都是微不足道的。

    推荐文章