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