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 使用 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重新编译库吗?

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

“针对本地对象重新定位”是什么意思?

我继续感谢。

4

3 回答 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
于 2011-02-07T19:20:31.897 回答
4

Kwatford 让我在第二个问题上走上了正轨。通过使用共享库重建日晷求解器,我能够让 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-08T07:18:16.897 回答
0

Matlab 使用自己的 libstdc 和 libstdc++。

快捷方式是将这些库符号链接到您要使用的 gcc44 库。

但这可能不是理想的方式。您可以尝试在 matlab 提示符之外编译,看看它是否仍然无法首先编译。

于 2011-02-07T18:57:07.217 回答