如何在Matlab';s MEX编译
我写了一个如下形式的程序:如何在Matlab';s MEX编译,matlab,openmp,linker-errors,mex,Matlab,Openmp,Linker Errors,Mex,我写了一个如下形式的程序: #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 -ls
#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版本的集群上编译的。在阵列构建过程中,库Sundals_cvode和Sundals_InvecSerial用于求解几个微分方程
现在,当我想转到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标志是什么
- 如果我的分析是错误的,接下来该怎么办
-> 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重新编译库吗
我没有库的源代码,如果建议重新编译库,是否有解决方法
“针对本地对象重新定位”是什么意思
继续感谢。Matlab使用自己的libstdc和libstdc++ 快捷方式是将这些库符号链接到要使用的gcc44库
但这可能不是理想的方式。您可以尝试在matlab提示符外编译,然后首先查看编译是否仍然失败。尝试不要将
-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
夸特福德在第二个问题上让我走上了正确的轨道。通过使用共享库重建日晷解算器,我可以使mex命令正常工作。具体地说,我是通过以下方式构建的:
% 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。我尝试了这个命令,但得到了一个不同的错误(不知道这是否是进度)。我编辑了这个问题以显示新问题。谢谢您的帮助。@Svenless:对不起,如果您没有访问源代码的权限,我不知道如何解决这个新错误。这是一种比我所知道的更神奇的魔法,但其要点是:共享库(如mex文件)需要独立于位置,因为它们将在任意位置加载。您尝试链接的静态库是位置相关的,因此无法在任何ole内存位置正确加载它。它需要重新编译。所以我和我的系统管理员追查了源代码,我们用共享选项重新制作了解算器。它正在工作。感谢您提供了最初的修复程序,并帮助我正确使用这些库。@Sevenless我还在尝试将C代码的makefile转换为mex的makefile。但是,我怀疑我没有正确地进行编译和链接。如果您能看看我的帖子,我将非常感激: