Makefile: Conversion du code C en code mex (erreur de liaison)

J’ai un C-code which works fine avec makefile. Maintenant, j’essaye de le convert it to mex fichier convert it to mex afin de pouvoir l’exécuter à partir de Matlab. Ici aussi, j’utilise l’ using makefile approach . Mais makefile pour mex me donne une erreur.

Voici la bibliothèque tsnnls que je veux comstackr avec mon fichier mex.

Organisation du projet C:

 tsnnls_test_DKU.c Include_4_TSNNLS.c Include_4_TSNNLS.h 

Les Include_4_TSNNLS.*Include_4_TSNNLS.* ” Ont une fonction TestingLibraries() qui appelle des bibliothèques de 3ème partie; alors que j’essayais de garder ” tsnnls_test_DKU.c ” très simple comme:

Code d’origine: tsnnls_test_DKU.c

 int TestingLibraries() ; int main( int argc, char* argv[] ) { int k = TestingLibraries() ; return(1); } 

Maintenant, le code a été changé:

Code modifié: tsnnls_test_DKU.c:

 #include "mex.h" #include  int TestingLibraries() ; void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int k = TestingLibraries() ; } 

Fichier make original (qui fonctionne

 CXX = gcc FLAGS = CFLAGS = "-m64" ## "-m32" INCLUDE_TSNNLS = -I/home/dkumar/libtsnnls-2.3.3 -I/home/dkumar/libtsnnls-2.3.3/tsnnls -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic #################### ALL TSNNLS lib related ########################## ## this is where all object file (*.o) generated by tsnnls library makefile are located. tsnnl_PATH = /home/dkumar/libtsnnls-2.3.3/tsnnls/ # Here is a simple Make Macro. OBJS_tsnnls1 = tsnnls_test_DKU.o OBJS_ADD = Include_4_TSNNLS.o # Here is a Make Macro that uses the backslash to extend to multiple lines. OBJS_tsnnls0 = libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \ libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \ libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \ libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \ libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \ libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \ libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \ libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o ## adding "$(OBJS_PATH)" to each word in "$(OBJS)" # which in our case is basically to add the same folder in front of all "*.o" object files. OBJS_TEMP = $(addprefix $(tsnnl_PATH), $(OBJS_tsnnls0)) # OBJS_LOC is in current working directory, OBJS_tsnnlsALL = $(OBJS_TEMP) $(OBJS_tsnnls1) # Libraries for tsnnls STLIB_tsnnls = /usr/local/lib/taucs_full/lib/linux/libtaucs.a LIBS_tsnnls = -largtable2 -llapack -lblas -lquadmath -lm ######################################################################## TARGET = tsnnls_test_DKU REBUILDABLES = $(OBJS_tsnnls1) $(TARGET) LIBS = $(LIBS_tsnnls) $(STLIB_tsnnls) INCLUDE = $(INCLUDE_TSNNLS) all : $(TARGET) echo All done clean : rm -f $(REBUILDABLES) echo Clean done $(OBJS_ADD): Include_4_TSNNLS.c gcc -c -o Include_4_TSNNLS.o Include_4_TSNNLS.c # Final linking $(TARGET) : $(OBJS_tsnnlsALL) $(OBJS_ADD) $(LIBS) $(CXX) -g -o $@ $(INCLUDE) $(CFLAGS) $^ 

Makefile modifié qui ne s’exécute pas Notice, j’ai rétabli le lien avec l’original avec le compilateur gcc; Cependant, je voudrais utiliser mex ici.

J’ai changé une ligne en fonction de ma compréhension et j’ai utilisé le tag “# mex”.

En outre, Include_4_TSNNLS.o est créé avec succès. En outre, le problème précédent avec “inclure” a été résolu en câblant tous les chemins.

  MEXSUFFIX = mexa64 # mex MATLABHOME = /usr/local/MATLAB/R2011b # mex MEX = /usr/local/MATLAB/R2011b/bin/mex # mex MEXFLAGS = -cxx CC='$(CXX)' CXX='$(CXX)' LD='$(CXX)' # mex CXX = gcc FLAGS = CFLAGS = -fPIC -pthread -DMX_COMPAT_32 -DMATLAB_MEX_FILE -m64 ## "-m32" INCLUDE_TSNNLS = -I/usr/local/MATLAB/R2011b/extern/include -I/home/dkumar/libtsnnls-2.3.3 -I/home/dkumar/libtsnnls-2.3.3/tsnnls -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic #################### ALL TSNNLS lib related ########################## ## this is where all object file (*.o) generated by tsnnls library makefile are located. tsnnl_PATH = /home/dkumar/libtsnnls-2.3.3/tsnnls/ # Here is a simple Make Macro. OBJS_tsnnls1 = tsnnls_test_DKU.o OBJS_ADD = Include_4_TSNNLS.o # Here is a Make Macro that uses the backslash to extend to multiple lines. OBJS_tsnnls0 = libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \ libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \ libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \ libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \ libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \ libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \ libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \ libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o ## adding "$(OBJS_PATH)" to each word in "$(OBJS)" # which in our case is basically to add the same folder in front of all "*.o" object files. OBJS_TEMP = $(addprefix $(tsnnl_PATH), $(OBJS_tsnnls0)) # OBJS_LOC is in current working directory, OBJS_tsnnlsALL = $(OBJS_TEMP) $(OBJS_tsnnls1) # Libraries for tsnnls ##STLIB_tsnnls = /usr/local/lib/taucs_full/lib/linux/libtaucs.a STLIB_tsnnls = /usr/local/lib/libtaucs.a #LIBS_tsnnls = -largtable2 -llapack -lblas -lquadmath -lm LIBS_tsnnls = -largtable2 -llapack -lblas -lm ######################################################################## ## TARGET = tsnnls_test_DKU TARGET_WO_EXTN = tsnnls_test_DKU # mex TARGET = TARGET_WO_EXTN #TARGET = $(TARGET_WO_EXTN).$(MEXSUFFIX) # mex REBUILDABLES = $(OBJS_tsnnls1) $(TARGET) *.mexa64 LIBS = $(LIBS_tsnnls) $(STLIB_tsnnls) INCLUDE = $(INCLUDE_TSNNLS) all : $(TARGET) echo All done clean : rm -f $(REBUILDABLES) echo Clean done $(OBJS_ADD): Include_4_TSNNLS.c gcc -c -o $(INCLUDE) Include_4_TSNNLS.o Include_4_TSNNLS.c # CHANGED FROM HERE # mex tsnnls_test_DKU.o: tsnnls_test_DKU.c Include_4_TSNNLS.c $(OBJS_tsnnlsALL) $(OBJS_ADD) $(CXX) $(CFLAGS) $(INCLUDE) -c $^ # Final linking $(TARGET): tsnnls_test_DKU.o $(OBJS_tsnnlsALL) $(OBJS_ADD) $(LIBS) $(MEX) $(MEXFLAGS) -output $(TARGET_WO_EXTN) $^ -largeArrayDims 

Je reçois les erreurs de liaison suivantes:

 dkumar@kumar-Aspire-E1-510 ~/CPP_ExampleCodes_DKU/Using_tsnnls_DKU_copy_2_MEX $ make make: Circular tsnnls_test_DKU.o <- tsnnls_test_DKU.o dependency dropped. gcc -fPIC -pthread -DMX_COMPAT_32 -DMATLAB_MEX_FILE -I/usr/local/MATLAB/R2011b/extern/include -I/home/dkumar/libtsnnls-2.3.3 -I/home/dkumar/libtsnnls-2.3.3/tsnnls -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic -c tsnnls_test_DKU.c Include_4_TSNNLS.c /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_malloc.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_order.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_ops.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_vec_base.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_complex.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-colamd.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdbar.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdexa.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdtru.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-genmmd.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_timer.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_sn_llt.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_base.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-tlsqr.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-tsnnls.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-lsqr.o Include_4_TSNNLS.o gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_malloc.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_order.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_ops.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_vec_base.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_complex.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-colamd.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdbar.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdexa.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdtru.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-genmmd.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_timer.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_sn_llt.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_base.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-tlsqr.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-tsnnls.o: linker input file unused because linking not done gcc: warning: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-lsqr.o: linker input file unused because linking not done gcc: warning: Include_4_TSNNLS.o: linker input file unused because linking not done /usr/local/MATLAB/R2011b/bin/mex -cxx CC='gcc' CXX='gcc' LD='gcc' -output tsnnls_test_DKU tsnnls_test_DKU.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_malloc.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_order.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_ops.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_vec_base.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_complex.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-colamd.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdbar.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdexa.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-amdtru.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-genmmd.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_timer.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_sn_llt.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_base.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-tlsqr.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-tsnnls.o /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-lsqr.o Include_4_TSNNLS.o /usr/lib/libargtable2.so /usr/lib/liblapack.so /usr/lib/libblas.so /usr/lib/x86_64-linux-gnu/libm.so /usr/local/lib/libtaucs.a -largeArrayDims Warning: You are using gcc version "4.8.2-19ubuntu1)". 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/ /usr/bin/ld: /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_order.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /home/dkumar/libtsnnls-2.3.3/tsnnls/libtsnnls_la-taucs_ccs_order.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status mex: link of ' "tsnnls_test_DKU.mexa64"' failed. make: *** [tsnnls_test_DKU] Error 1 

Quelqu’un pourrait-il m’aider s’il vous plaît avec les options de liaison?

Le problème est que tous les fichiers objects listés dans $ (OBJS_tsnnls0) (ou au moins libtsnnls_la-taucs_ccs_order.o) ont été compilés sans l’option de compilation -fPIC gcc. La page de manuel de gcc dit pour -fPIC

Générer un code indépendant de la position (PIC) adapté à une utilisation dans une bibliothèque partagée

Notez que les fichiers MEX sont des bibliothèques partagées. Ainsi, tous les liens de code object se marient parfaitement à un exécutable autonome (qui ne nécessite pas de PIC), mais il n’est tout simplement pas compilé pour créer un lien vers un fichier MEX (ou une bibliothèque partagée). Si vous avez les fichiers source originaux, vous devriez pouvoir les recomstackr avec les bons commutateurs en lançant

$ (MEX) -c -o nom du fichier .o nom du fichier .c

pour chacun des fichiers source.

Vous avez une dépendance circulaire sur tsnnls_test_DKU.o car OBJS_tsnnlsAll développe pour inclure OBJS_tsnnls1 qui est défini comme tsnnls_test_DKU.o dans la première ligne du tsnnls_test_DKU.o .

De plus, vous n’avez pas de règle pour générer OBJS_tsnnlsAll . Vous ne faites que transmettre les noms de tous les fichiers object au compilateur, qui les ignore en raison de l’indicateur -c .

Vous devez supprimer $(OBJS_tsnnlsALL) de la règle tsnnls_test_DKU.o et supprimer le tsnnls_test_DKU.o de la cible finale pour que les deux dernières règles se présentent comme tsnnls_test_DKU.o :

 # CHANGED FROM HERE # mex tsnnls_test_DKU.o: tsnnls_test_DKU.c Include_4_TSNNLS.c $(OBJS_ADD) $(CXX) $(CFLAGS) $(INCLUDE) -c $^ # Final linking $(TARGET): $(OBJS_tsnnlsALL) $(OBJS_ADD) $(LIBS) $(MEX) $(MEXFLAGS) -output $(TARGET_WO_EXTN) $^ -largeArrayDims