2011-02-07 143 views
7

我已經寫了以下形式的節目中鏈接:如何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重新編譯庫嗎?

我沒有庫的來源,如果建議是重新編譯庫有沒有解決方法?

「針對本地對象的重定位」是什麼意思?

我繼續致謝。

回答

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 
+1

我試過命令,並得到了一個不同的錯誤(不知道這是否進展)。我編輯了這個問題來顯示新問題。謝謝你的幫助。 – Sevenless 2011-02-07 20:41:45

0

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

快捷方式是將這些庫的符號鏈接到您要使用的gcc44庫。

但這可能不是所需的方法。您可以嘗試編譯外部matlab提示,並查看它是否仍然首先編譯失敗。

4

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。