2011-02-07 2 views
7

matlab에의 MEX 컴파일시에 연결하는 방법 :나는 다음과 같은 형식의 프로그램을 작성했습니다

`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 : 링크, 컴파일하고 다음 명령을 제대로 실행

#include "stuff_I_need.h" 

int main(){ 

construct_array(); // uses OpenMP pragma's 
print_array(); 

return(0); 


} 

"는 단순히 gcc 버전 4.4이며 여러 버전의 gcc를 유지 관리하는 클러스터에서 컴파일되므로이 이름이 지정됩니다. sundials_cvode 및 sundials_nvecserial 라이브러리는 배열을 생성하는 동안 여러 미분 방정식을 푸는 데 사용됩니다.

#include "stuff_I_need.h" 

void mexFunction(int nlhs,mxArray* plhs[], int nrhs, const mxArray* prhs[]){ 

construct_array(); // uses OpenMP pragma's 
print_array(); 

} 

및 매트랩 다음 명령을 사용하여 컴파일하려고 :

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

내가 지금은 matlab에까지 전송하고 양식의 MEX 파일을 컴파일하려고 할 때

링크 오류로 이어지는 다음 메시지를 얻으십시오 :

-> 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 적절하게 링크하기위한 플래그. gcc44 명령에서 링크 명령을 제거하면 동일한 오류 세트 (몇 가지 더 추가)가 발생하므로 컴파일러에서 라이브러리를 볼 수 없다는 것을 확신합니다.

내 질문이 있습니다 : 오류의 나의 분석이 맞다면

  • , 어떤 플래그 내가 성공적으로 연결하려면 MEX 컴파일 명령에 전달해야합니까?
  • 또는 Matlab 환경 외부에서 컴파일 및 링크하여 .mex64 실행 파일을 컴파일하는 gcc 플래그는 무엇입니까?
  • 분석 결과가 잘못 되었다면 여기에서 어디로 가야합니까?

은 내가 GCC 4.4을 사용하여 OpenMP의 프로그램과 간단한 MEX을 컴파일 할 수있었습니다 이후가 지원되지 않는 컴파일러 경고를 배제했다고 생각하지만, 이들은 수학 라이브러리를 제외하고 아무것도에 대한 링크가 없었다. 또한 "-fopenmp"플래그와 함께 또는없이 버전 gcc 버전 4.1.2 또는 4.3.4로 컴파일하면 동일한 오류가 발생합니다.

이전 버전에서는 나타나지 않은 특정 OpenMP 지원 때문에 결국 버전 4.4가 필요합니다.

도움을 미리 감사드립니다.

--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 함수는 이러한 유형의 인수를 직접 처리합니다. 그래서 아마도 다음과 같은 것이 될 것입니다.

+1

나는 명령을 시도하고 다른 오류가 발생했습니다 (진행 상황을 알 수 없음). 나는 새로운 문제를 보여주기 위해 질문을 편집했다. 당신의 도움을 주셔서 감사합니다. – Sevenless

+1

@Svenless : 죄송합니다. 출처에 대한 액세스 권한이 없으면이 새로운 오류를 어떻게 해결할 수 있는지 알 수 없습니다. 이것은 다루는 방법보다 더 깊은 마법이지만, 요지는 : 공유 라이브러리 (mex 파일과 같은)는 임의의 위치에로드되기 때문에 위치 독립적이어야합니다. 링크하려는 정적 라이브러리는 위치에 따라 다르므로 모든 메모리 위치에 제대로로드 할 수 없습니다. 다시 컴파일해야합니다. – kwatford

+1

그래서 시스템 관리자와 함께 소스를 쫓아 냈습니다. 공유 옵션으로 해결사를 다시 만듭니다. 이제 작동 중입니다. 원래의 픽스와 라이브러리를 통해 올바른 길을 찾아 주셔서 감사합니다. – Sevenless

0

Matlab은 자체 libstdc와 libstdC++를 사용합니다.

바로 가기는 사용하려는 gcc44 라이브러리에 대한 라이브러리에 대한 심볼 링크를 수행하는 것입니다.

하지만이 방법이 바람직한 방법은 아닙니다. 당신은 외부 matlab 프롬프트를 컴파일하고 컴파일이 실패하는지 먼저 확인해 볼 수 있습니다.

4

왓 포드는 두 번째 질문에 올바른 길을 걸었습니다. 나는 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를 처리하는 방법을 알고 있기 때문이다.