2011-02-07 33 views
7

Tôi đã viết một chương trình có dạng như sau:Làm thế nào để liên kết trong biên soạn MEX Matlab của

#include "stuff_I_need.h" 

int main(){ 

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

return(0); 


} 

mà biên dịch, liên kết, và chạy một cách chính xác với lệnh sau đây:

`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 "chỉ đơn giản là gcc phiên bản 4.4 và được đặt tên như thế này bởi vì nó đang được biên dịch trên một cụm duy trì một số phiên bản của gcc. Các thư viện sundials_cvode và sundials_nvecserial được sử dụng trong việc giải quyết một số phương trình vi phân trong quá trình xây dựng mảng.

Bây giờ khi tôi muốn chuyển giao cho Matlab và thử biên dịch file mex có dạng:

#include "stuff_I_need.h" 

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

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

} 

và thử biên dịch bằng lệnh sau trong 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 

tôi nhận được các thông báo sau lên đến đỉnh điểm trong một lỗi liên kết:

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

Bằng cách nào đó, tôi không đưa ra correc t cờ để liên kết một cách thích hợp. Khi tôi nhận được cùng một tập hợp các lỗi (cộng thêm một vài) nếu tôi loại bỏ các lệnh để liên kết trong lệnh gcc44, tôi khá chắc chắn rằng tôi không nhận được trình biên dịch để "xem" các thư viện.

Câu hỏi của tôi là:

  • Nếu phân tích của tôi về lỗi là đúng, những gì cờ nào tôi cần phải vượt qua để lệnh biên soạn mex liên kết thành công?
  • Ngoài ra, các cờ gcc để biên dịch và liên kết ra ngoài môi trường Matlab để biên dịch tệp .mex64 là gì?
  • Nếu phân tích của tôi sai, phải đi đâu?

Tôi nghĩ tôi đã loại bỏ cảnh báo trình biên dịch không được hỗ trợ vì tôi đã có thể biên dịch mex đơn giản với các chương trình OpenMP bằng gcc 4.4, nhưng chúng không phải liên kết với bất kỳ thứ gì ngoại trừ thư viện toán. Ngoài ra, nếu tôi biên dịch với phiên bản gcc 4.1.2 hoặc 4.3.4 có hoặc không có cờ "-fopenmp", tôi nhận được lỗi tương tự.

Cuối cùng, tôi cần phiên bản 4.4 do một số hỗ trợ OpenMP nhất định không xuất hiện trong các phiên bản trước.

Cảm ơn bạn đã trợ giúp.

--Andrew

Chỉnh sửa: (@KWATFORD)

Vì vậy, tôi đã thử các lệnh với những điều khoản ngoài có dấu ngoặc kép, và đã nhận lỗi:

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

tôi là một bit bối rối về đề xuất để biên dịch lại với "-fPIC" bởi vì khi tôi nhìn vào lệnh gcc44 tôi thấy -fPIC như là một tùy chọn.

Họ đang nói để biên dịch lại thư viện bằng -fPIC?

Tôi không có nguồn cho thư viện, nếu đề xuất là biên dịch lại thư viện thì có cách giải quyết khác không?

"Di chuyển đối với đối tượng địa phương" có nghĩa là gì?

Cảm ơn của tôi.

Trả lời

5

Cố gắng không đặt các đối số -l, -L hoặc -I vào các biến môi trường đó. Hàm mex sẽ xử lý trực tiếp các kiểu đối số đó. Vì vậy, có lẽ một cái gì đó như:

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

Tôi đã thử lệnh và gặp lỗi khác (không biết nếu đó là tiến trình). Tôi đã chỉnh sửa câu hỏi để hiển thị vấn đề mới. Cảm ơn bạn đã giúp đỡ. – Sevenless

+1

@Svenless: Rất tiếc, nếu bạn không có quyền truy cập vào nguồn, tôi không biết lỗi này có thể được giải quyết như thế nào. Đây là phép thuật sâu sắc hơn tôi biết cách giải quyết, nhưng ý chính của nó là: các thư viện được chia sẻ (như các tệp mex) cần phải là vị trí độc lập, vì chúng sẽ được tải ở một vị trí tùy ý nào đó. Thư viện tĩnh mà bạn đang cố gắng liên kết là phụ thuộc vào vị trí, vì vậy nó không thể được tải đúng tại bất kỳ vị trí bộ nhớ ole nào. Nó cần phải được biên dịch lại. – kwatford

+1

Vì vậy, tôi đã truy tìm nguồn với quản trị viên hệ thống của mình và chúng tôi làm lại các trình giải quyết bằng các tùy chọn được chia sẻ. Nó đang làm việc bây giờ. Cảm ơn cả bản sửa lỗi gốc và đã giúp tôi đi đúng hướng với các thư viện. – Sevenless

0

Matlab sử dụng libstdc và libstdC++ của riêng nó.

Phím tắt sẽ là tạo biểu tượng cho các thư viện đó đến thư viện gcc44 mà bạn muốn sử dụng.

Nhưng điều này có thể không phải là cách bạn muốn. Bạn có thể thử biên dịch dấu nhắc matlab bên ngoài và xem nếu nó vẫn không biên dịch đầu tiên.

4

Kwatford đặt tôi đi đúng hướng với câu hỏi thứ hai. Tôi đã có thể nhận được lệnh mex để làm việc bằng cách xây dựng lại người giải quyết sundials với các thư viện được chia sẻ. Cụ thể, tôi xây dựng với:

% make distclean 
% ./configure --prefix=/home/matteson/sundials --enable-shared 
% make 
% make install 

Ngoài ra, nhờ vào kwatford cho việc sửa chữa với bản gốc bằng cách gọi:

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 

từ mex biết làm thế nào để xử lý các -L và -I.

Các vấn đề liên quan