如何Matlab的MEX编译
我已经写了以下形式的节目中链接:如何Matlab的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 -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.
不知何故,我没有给出correc t标志适当链接。当我得到相同的一组错误(再加上几个),如果我删除命令链接到gcc44命令,我敢肯定,我没有让编译器“看到”库。
我的问题是:
- 如果我的错误的分析是正确的,我需要什么样的标志传递给MEX编译命令成功链接?
- 另外,什么是海湾合作委员会的标志来编译和链接外部的Matlab环境编译.mex64可执行文件?
- 如果我的分析错了,该从哪里下去?
我想我已经排除了不支持的编译器警告,因为我已经能够编写简单MEX使用GCC 4.4 OpenMP程序,但这些并没有除了数学库反对任何链接。另外,如果我使用带有或不带“-fopenmp”标志的gcc版本4.1.2或4.3.4进行编译,我会得到相同的错误。
最终,我确实需要版本4.4,因为某些OpenMP支持并未出现在先前版本中。
在此先感谢您的帮助。
--Andrew
编辑:(@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重新编译库吗?
我没有库的来源,如果建议是重新编译库有没有解决方法?
“针对本地对象的重定位”是什么意思?
我继续致谢。
请勿尝试将-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
Matlab使用自己的libstdc和libstdC++。
快捷方式是将这些库的符号链接到您要使用的gcc44库。
但这可能不是所需的方法。您可以尝试编译外部matlab提示,并查看它是否仍然首先编译失败。
Kwatford让我在第二个问题的正确轨道上。通过使用共享库重建日sol求解器,我能够获得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。
我试过命令,并得到了一个不同的错误(不知道这是否进展)。我编辑了这个问题来显示新问题。谢谢你的帮助。 – Sevenless 2011-02-07 20:41:45