我已经编写了如下形式的程序:
#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编译命令哪些标志才能成功链接?
我认为我已经排除了不受支持的编译器警告,因为我已经能够使用gcc 4.4用OpenMP程序编译简单的mex,但是除了数学库之外,这些程序不需要链接到任何东西。此外,如果我使用gcc版本4.1.2或4.3.4编译,无论是否使用"-fopenmp“标志,我都会得到相同的错误。
最后,我确实需要版本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重新编译库吗?
我没有这个库的源代码,如果建议是重新编译库,有解决办法吗?
“异地拆迁”是什么意思?
我继续感谢你。
发布于 2011-02-07 19:20:31
不要在这些环境变量中放置-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发布于 2011-02-08 07:18:16
克瓦特福德用第二个问题让我走上了正确的轨道。我能够通过使用共享库重新构建太阳刻度盘解决程序来使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。
发布于 2011-02-07 18:57:07
Matlab使用自己的libstdc和libstdc++。
快捷方式是将这些库与要使用的gcc44库进行符号链接。
但这可能不是我们想要的方式。您可以尝试在matlab提示符之外编译,并查看它是否仍然首先失败编译。
https://stackoverflow.com/questions/4924701
复制相似问题