2011-02-07 8 views
7

Ho scritto un programma della forma seguente:Come collegare durante MEX la compilazione di Matlab

#include "stuff_I_need.h" 

int main(){ 

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

return(0); 


} 

che compila, i collegamenti, e viene eseguito correttamente con il seguente comando:

`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 "è semplicemente gcc versione 4.4 ed è chiamato così perché è stato compilato su un cluster che mantiene diverse versioni di gcc. Le librerie sundials_cvode e sundials_nvecserial vengono utilizzate nella risoluzione di diverse equazioni differenziali durante la costruzione dell'array.

Ora, quando voglio trasferire verso Matlab e provare a compilare il file mex della forma:

#include "stuff_I_need.h" 

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

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

} 

e provare a compilare con il seguente comando in 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 

I i seguenti messaggi si conclude con un errore di collegamento:

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

in qualche modo, non sto dando il correc t flag da collegare in modo appropriato. Come ottengo lo stesso insieme di errori (più alcuni altri) se rimuovo i comandi da collegare nel comando gcc44, sono abbastanza sicuro che non sto facendo in modo che il compilatore "veda" le librerie.

Le mie domande sono:

  • Se la mia analisi dell'errore è corretto, quello bandiere ho bisogno di passare al comando mex compilation di collegare con successo?
  • In alternativa, quali sono i flag gcc da compilare e collegare all'esterno dell'ambiente Matlab per compilare un eseguibile .mex64?
  • Se la mia analisi è sbagliata, dove andare da qui?

Penso di aver escluso l'avviso del compilatore non supportato poiché sono stato in grado di compilare semplici mess con i programmi OpenMP utilizzando gcc 4.4, ma questi non dovevano collegarsi a nulla tranne la libreria matematica. Inoltre, se compilo con la versione gcc versione 4.1.2 o 4.3.4 con o senza i flag "-fopenmp" ottengo lo stesso errore.

Alla fine ho bisogno della versione 4.4 a causa di un certo supporto OpenMP che non appare nelle versioni precedenti.

Grazie in anticipo per l'aiuto.

--Andrew

modifiche: (@KWATFORD)

così ho provato il comando con le dichiarazioni di fuori delle virgolette, e ottenuto l'errore:

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

Sono un un po 'confuso riguardo al suggerimento da ricompilare con "-fPIC" perché quando guardo il comando gcc44 vedo l'opzione -fPIC come opzione.

Stanno dicendo di ricompilare la libreria con -fPIC?

Non ho il sorgente per la libreria, se il suggerimento è di ricompilare la libreria c'è una soluzione?

Che cosa significa "ricollocazione contro oggetto locale"?

Il mio continuo ringraziamento.

risposta

5

Provare a non inserire gli argomenti -l, -L o -I in quelle variabili di ambiente. La funzione mex gestirà direttamente questi tipi di argomenti. Quindi forse qualcosa tipo:

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

Ho provato il comando e ho ottenuto un errore diverso (non so se è in corso). Ho modificato la domanda per mostrare il nuovo problema. Grazie per l'aiuto. – Sevenless

+1

@Svenless: Siamo spiacenti, se non si ha accesso alla fonte, non so come questo nuovo errore possa essere risolto. Questa è una magia più profonda di quanto io sappia gestire, ma il succo è: le librerie condivise (come i file mex) devono essere indipendenti dalla posizione, dato che verranno caricate in una posizione arbitraria. La libreria statica a cui stai cercando di collegarsi dipende dalla posizione, quindi non può essere caricata correttamente in nessuna posizione di memoria ole. Ha bisogno di essere ricompilato. – kwatford

+1

Così ho inseguito il sorgente con il mio amministratore di sistema e abbiamo rifatto i risolutori con le opzioni condivise. Sta lavorando adesso. Grazie per la correzione originale e per avermi trovato sulla strada giusta con le librerie. – Sevenless

0

Matlab utilizza il proprio libstdc e libstdC++.

Il collegamento sarebbe eseguire un symbolink su quelle librerie alle librerie gcc44 che si desidera utilizzare.

Ma questo potrebbe non essere il modo desiderato di andare. Potresti provare a compilare il prompt di matlab e vedere se fallisce ancora la compilazione.

4

Kwatford mi ha messo sulla strada giusta con la seconda domanda. Sono stato in grado di far funzionare il comando mex ricostruendo il solutore delle meridiane con le librerie condivise. In particolare, ho costruito con:

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

Inoltre, grazie alla kwatford per la correzione all'originale chiamando:

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 

dal mex sa come gestire la -L e -I.