2011-02-07 31 views
7

He escrito un programa de la siguiente forma:Cómo vincular durante MEX compilación de Matlab

#include "stuff_I_need.h" 

int main(){ 

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

return(0); 


} 

que recopila, enlaces, y funciona correctamente con el siguiente 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 "es simplemente la versión 4.4 de gcc y se llama así porque se está compilando en un clúster que mantiene varias versiones de gcc. Las bibliotecas sundials_cvode y sundials_nvecserial se usan para resolver varias ecuaciones diferenciales durante la construcción de la matriz.

Ahora cuando quiero transferir a Matlab y tratar de compilar el archivo mex de la 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(); 

} 

y tratar de compilar con el siguiente comando en 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 recibe los siguientes mensajes que culminan en un error de enlace:

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

De alguna manera, no estoy dando el correc t Indicadores para vincular apropiadamente. Como obtengo el mismo conjunto de errores (más algunos más) si elimino los comandos para vincular en el comando gcc44, estoy bastante seguro de que no estoy obteniendo el compilador para "ver" las bibliotecas.

Mis preguntas son:

  • Si mi análisis del error es correcto, lo banderas Qué necesito para pasar al comando mex compilación de vincular con éxito?
  • Como alternativa, ¿qué indicadores de gcc compilar y vincular fuera del entorno de Matlab para compilar un ejecutable .mex64?
  • Si mi análisis es incorrecto, ¿a dónde ir desde aquí?

Creo que he descartado la advertencia del compilador no compatible ya que he podido compilar mex simple con programas OpenMP utilizando gcc 4.4, pero estos no tienen que enlazarse con nada excepto con la biblioteca matemática. Además, si compilo con la versión gcc versión 4.1.2 o 4.3.4 con o sin las marcas "-fopenmp" obtengo el mismo error.

Al final necesito la versión 4.4 debido a cierto soporte de OpenMP que no apareció en versiones anteriores.

Gracias de antemano por la ayuda.

--Andrew

ediciones: (@KWATFORD)

así que he intentado el comando con las declaraciones fuera de las comillas, y tiene el error:

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

Soy una Poco confuso sobre la sugerencia de recompilar con "-fPIC" porque cuando miro el comando gcc44 veo el -fPIC como una opción.

¿Dicen que recompilan la biblioteca con -fPIC?

No tengo la fuente para la biblioteca, si la sugerencia es recompilar la biblioteca ¿hay alguna solución?

¿Qué significa "reubicación contra un objeto local"?

Mi continuación gracias.

Respuesta

5

Trate de no poner los argumentos -l, -L, o -I en esas variables de entorno. La función mex manejará esos tipos de argumentos directamente. Entonces quizás algo como:

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

Intenté el comando y obtuve un error diferente (no sé si eso es progreso). Edité la pregunta para mostrar el nuevo problema. Gracias por tu ayuda. – Sevenless

+1

@Svenless: Lo siento, si no tiene acceso a la fuente, no sé cómo se pudo resolver este nuevo error. Esta es una magia más profunda de lo que sé manejar, pero la esencia es que las bibliotecas compartidas (como los archivos mex) deben ser independientes de la posición, ya que se cargarán en alguna posición arbitraria. La biblioteca estática con la que intentas enlazar depende de la posición, por lo que no se puede cargar correctamente en ninguna ubicación de la memoria original. Necesita ser recompilado. – kwatford

+1

Así que busqué la fuente con el administrador de mi sistema y volvimos a crear los solucionadores con las opciones compartidas. Está funcionando ahora. Gracias por la corrección original y por ponerme en el camino correcto con las bibliotecas. – Sevenless

0

Matlab usa su propia libstdc y libstdC++.

El atajo sería hacer un simbolismo a esas bibliotecas a las bibliotecas gcc44 que desea utilizar.

Pero esta puede no ser la forma deseada de hacerlo. Podría intentar compilar el prompt externo de matlab y ver si aún falla la compilación.

4

Kwatford me puso en el camino correcto con la segunda pregunta. Logré hacer funcionar el comando mex reconstruyendo el solucionador de sol con bibliotecas compartidas. En concreto, he construido con:

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

Además, gracias a kwatford para la solución a la original, llamando al:

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 

ya Mex sabe cómo manejar la -L y -I.

Cuestiones relacionadas