首页 文章

如何在Matlab的MEX编译过程中进行链接

提问于
浏览
7

我写了一个以下形式的程序:

#include "stuff_I_need.h"

int main(){

construct_array(); // uses OpenMP pragma's
print_array();

return(0);


}

使用以下命令正确编译,链接和运行:

`gcc44 -I/home/matteson/sundials/include/ main.c -lm -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial -fopenmp -o /home/matteson/MPI_test/CVODE_test/main_test`

“gcc44”只是gcc 4.4版本,因为它是在一个维护多个版本gcc的集群上编译的 . 库sundials_cvode和sundials_nvecserial用于在构造阵列期间求解几个微分方程 .

现在,当我想转移到Matlab并尝试编译表单的mex文件时:

#include "stuff_I_need.h"

void mexFunction(int nlhs,mxArray* plhs[], int nrhs, const mxArray* prhs[]){

construct_array(); // uses OpenMP pragma's
print_array();

}

并尝试在Matlab中使用以下命令进行编译:

>> mex -v CC="gcc44" CFLAGS="\$CFLAGS -I/home/matteson/sundials/include/ -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial" mex_cvode.c

我收到以下消息,最终导致链接错误:

-> mexopts.sh sourced from directory (DIR = $HOME/.matlab/$REL_VERSION)
   FILE = /home/matteson/.matlab/R2010b/mexopts.sh
----------------------------------------------------------------
->    MATLAB                = /misc/linux/64/opt/pkg/matlab/R2010b
->    CC                    = gcc44
->    CC flags:
         CFLAGS             = -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -L/home/matteson/sundials/lib -lsundials_nvecserial
         CDEBUGFLAGS        = -g
         COPTIMFLAGS        = -O -DNDEBUG
         CLIBS              = -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++
         arguments          =  -DMX_COMPAT_32
->    CXX                   = g++
->    CXX flags:
         CXXFLAGS           = -ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread
         CXXDEBUGFLAGS      = -g
         CXXOPTIMFLAGS      = -O -DNDEBUG
         CXXLIBS            = -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          =  -DMX_COMPAT_32
->    FC                    = g95
->    FC flags:
         FFLAGS             = -fexceptions -fPIC -fno-omit-frame-pointer
         FDEBUGFLAGS        = -g
         FOPTIMFLAGS        = -O
         FLIBS              = -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          =  -DMX_COMPAT_32
->    LD                    = gcc44
->    Link flags:
         LDFLAGS            = -pthread -shared -Wl,--version-script,/misc/linux/64/opt/pkg/matlab/R2010b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -fopenmpofopenmp
         LDDEBUGFLAGS       = -g
         LDOPTIMFLAGS       = -O
         LDEXTENSION        = .mexa64
         arguments          = 
->    LDCXX                 = 
->    Link flags:
         LDCXXFLAGS         = 
         LDCXXDEBUGFLAGS    = 
         LDCXXOPTIMFLAGS    = 
         LDCXXEXTENSION     = 
         arguments          = 
----------------------------------------------------------------


Warning: You are using gcc version "4.4.4".  The version
         currently supported with MEX is "4.3.4".
         For a list of currently supported compilers see: 
         http://www.mathworks.com/support/compilers/current_release/

-> gcc44 -c  -I/misc/linux/64/opt/pkg/matlab/R2010b/extern/include -I/misc/linux/64/opt/pkg/matlab/R2010b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -L/home/matteson/sundials/lib -lsundials_nvecserial  -DMX_COMPAT_32 -O -DNDEBUG  "mex_cvode.c"

-> gcc44 -O -pthread -shared -Wl,--version-script,/misc/linux/64/opt/pkg/matlab/R2010b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -fopenmpofopenmp -o  "mex_cvode.mexa64"  mex_cvode.o  -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++

mex_cvode.o: In function `mexFunction':
mex_cvode.c:(.text+0x2b2): undefined reference to `N_VNew_Serial'
mex_cvode.c:(.text+0x2db): undefined reference to `N_VNew_Serial'
mex_cvode.c:(.text+0x35b): undefined reference to `CVodeCreate'
mex_cvode.c:(.text+0x39c): undefined reference to `CVodeInit'
mex_cvode.c:(.text+0x3dd): undefined reference to `CVodeSVtolerances'
mex_cvode.c:(.text+0x412): undefined reference to `CVodeSetUserData'
mex_cvode.c:(.text+0x449): undefined reference to `CVDense'
mex_cvode.c:(.text+0x482): undefined reference to `CVDlsSetDenseJacFn'
mex_cvode.c:(.text+0x50c): undefined reference to `CVode'
mex_cvode.c:(.text+0x5b4): undefined reference to `N_VDestroy_Serial'
mex_cvode.c:(.text+0x5c0): undefined reference to `N_VDestroy_Serial'
mex_cvode.c:(.text+0x5cc): undefined reference to `CVodeFree'
collect2: ld returned 1 exit status

    mex: link of ' "mex_cvode.mexa64"' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

不知何故,我没有给出正确的标志来适当地链接 . 当我在gcc44命令中删除要链接的命令时,我得到了相同的错误集(加上一些),我很确定我没有让编译器“看到”库 .

我的问题是:

  • 如果我对错误的分析是正确的,我需要将哪些标志传递给mex编译命令才能成功链接?

  • 或者,在Matlab环境之外编译和链接以编译.mex64可执行文件的gcc标志是什么?

  • 如果我的分析错了,从哪里开始?

我认为我已经排除了不受支持的编译器警告,因为我已经能够使用gcc 4.4编译简单的mex和OpenMP程序,但这些不必连接除数学库之外的任何东西 . 此外,如果我使用或不使用“-fopenmp”标志使用版本gcc版本4.1.2或4.3.4进行编译,我会得到相同的错误 .

最后,我确实需要4.4版,因为某些OpenMP支持在先前版本中没有出现 .

在此先感谢您的帮助 .

  • 安德鲁

编辑:(@KWATFORD)

所以我尝试使用引号之外的语句命令,并得到错误:

-> gcc44 -c  -I/home/matteson/sundials/include/ -I/misc/linux/64/opt/pkg/matlab/R2010b/extern/include -I/misc/linux/64/opt/pkg/matlab/R2010b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread -fopenmp  -DMX_COMPAT_32 -O -DNDEBUG  "mex_cvode.c"

-> gcc44 -O -pthread -shared -Wl,--version-script,/misc/linux/64/opt/pkg/matlab/R2010b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -fopenmp -o  "mex_cvode.mexa64"  mex_cvode.o  -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++

/usr/bin/ld: /home/matteson/sundials/lib/libsundials_cvode.a(cvode.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/home/matteson/sundials/lib/libsundials_cvode.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

    mex: link of ' "mex_cvode.mexa64"' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

我对使用“-fPIC”重新编译的建议感到有点困惑,因为当我查看gcc44命令时,我看到-fPIC是一个选项 .

他们是说要用-fPIC重新编译库吗?

我没有库的源代码,如果建议重新编译库是否有解决方法?

“重新安置本地对象”是什么意思?

我继续感谢 .

3 回答

  • 5

    尽量不要在这些环境变量中放入 -l-L-I 参数 . mex函数将直接处理这些类型的参数 . 所以可能是这样的:

    mex -v CC="gcc44" CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp" -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial mex_cvode.c
    
  • 0

    第二个问题,Kwatford让我走上正轨 . 我能够通过使用共享库重建日历解算器来获得mex命令 . 具体来说,我 Build 了:

    % make distclean
    % ./configure --prefix=/home/matteson/sundials --enable-shared
    % make
    % make install
    

    另外,感谢kwatford通过调用修复原始内容:

    mex -v CC="gcc44" CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp" -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial mex_cvode.c
    

    因为mex知道如何处理-L和-I .

  • 4

    Matlab使用自己的libstdc和libstdc .

    快捷方式是对要使用的gcc44库的那些库执行符号链接 .

    但这可能不是理想的方式 . 您可以尝试编译外部的matlab提示,看看它是否仍然无法编译 .

相关问题