2015-02-12 18 views
8

Ho un C-code which works fine utilizzando makefile. Ora, sto cercando di file convert it to mex in modo che io possa eseguirlo da Matlab. Anche qui, sono using makefile approach. Ma makefile per mess mi dà errore.Makefile: conversione del codice C in codice mex (errore di collegamento)

Ecco lo tsnnls lib che voglio compilare insieme al mio file mex.

Organizzazione di C-progetto:

tsnnls_test_DKU.c 
Include_4_TSNNLS.c 
Include_4_TSNNLS.h 

"Include_4_TSNNLS.*" file hanno la funzione TestingLibraries() che richiedono 3rd librerie di componenti; mentre ho cercato di mantenere "tsnnls_test_DKU.c" molto semplice:

Codice originale: tsnnls_test_DKU.c

int TestingLibraries() ; 

int main(int argc, char* argv[]) 
{ 

    int k = TestingLibraries() ; 
    return(1); 
} 

Ora, il codice è stato cambiato:

codice modificato: tsnnls_test_DKU.c:

#include "mex.h" 
#include <math.h> 

int TestingLibraries() ; 

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

    int k = TestingLibraries() ; 

} 

mak originale e di file (che funziona

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 [email protected] $(INCLUDE) $(CFLAGS) $^ 

Cambiato Makefile che non viene eseguito Avviso, ho ripristinare la parte che collega l'originale con il compilatore gcc; tuttavia, mi piacerebbe usare mex qui.

Ho modificato alcune righe in base alla mia comprensione e ho utilizzato il tag "# mex".

Inoltre, Include_4_TSNNLS.o è stato creato correttamente. Inoltre, il precedente problema con "include" è stato risolto dal cablaggio fisso di tutti i percorsi.

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 

ottengo i seguenti errori di collegamento:

[email protected] ~/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 

Potrebbe qualcuno soddisfare per aiutarlo con le opzioni di collegamento?

+1

uso -I (matlab_dir)/extern/include per puntare al Makefile header – user3528438

+0

@ user3528438 Penso di aver già utilizzato include: 'INCLUDE = -I $ (MATLABHOME)/extern/include $ (INCLUDE_TSNNLS)' e quindi includo questo mentre fai TARGET. Ma, potrei averlo sbagliato nelle opzioni del compilatore e non riuscivo a capirlo. –

+1

Nella parte inferiore del codice, si utilizza "gcc -c -o ..." per compilare e utilizzare "$ (MEX) -g -o ...." per il collegamento. Come il tuo $ (INCLUDE) è dopo $ (MEX), quindi è considerato un'opzione linker piuttosto che l'opzione del compilatore. Prova a spostare $ (INCLUDE) e $ (CFLAGS) più vicino a gcc. – user3528438

risposta

4

Il problema è che tutti i file oggetto elencati in $ (OBJS_tsnnls0) (o, per lo meno, libtsnnls_la-taucs_ccs_order.o) sono stati compilati senza l'opzione -fpIC del compilatore gcc. La pagina man di gcc dice per -fPIC

Generate position-independent code (PIC) suitable for use in a shared library

Nota che i file MEX sono librerie condivise. Quindi, tutti i collegamenti di codice oggetto perfettamente bene in un eseguibile standalone (che non richiede PIC), ma non è semplicemente compilato correttamente per collegarsi a un file MEX (o qualsiasi libreria condivisa). Se si dispone dei file sorgente originale, si dovrebbe essere in grado di ricompilare loro con gli interruttori giusti eseguendo

$ (MEX) -c -o nome .o nome del file .c

per ciascuno dei i file di origine.

+0

La libreria sembra utilizzare alcuni autotools (libtool). Usando 'makefile' dopo' configure' in $ (OBJS_tsnnls0), posso vedere un comando come questo: libtool: compile: 'gcc -DHAVE_CONFIG_H -I. -I .. -Wall -MT libtsnnls_la-taucs_ccs_order.lo -MD -MP -MF .deps/libtsnnls_lataucs_ccs_order.Tpo -c taucs_basic/taucs_ccs_order.c -fPIC -DPIC -o .libs/libtsnnls_la-taucs_ccs_order.o' . Sembra che usi '-fPIC' già. A cosa dovrei cambiare questo comando? –

+0

Sì, ho la libreria scaricata e tutti i codici sorgente: jasoncantarella.com/wordpress/software/tsnnls. Il suo makefile è stato creato usando 'makefile.am'. Tuttavia, dato che non sono bravo in C, non riesco a capire come 'makefile.am-> makefile' e come' cambiare il flag o il compilatore'. Potresti provare questa libreria da solo e aiutarmi a risolvere questo problema? Ti devo davvero la mia vita per questo. Sarei più che felice di ringraziarlo in particolare o di metterti come mio coautore. Ciò risolverebbe un problema eccezionale nell'imaging medico; quindi, molto importante –

2

Hai un dipendenza circolare sul tsnnls_test_DKU.o perché OBJS_tsnnlsAll espande per includere OBJS_tsnnls1 definito come tsnnls_test_DKU.o nella prima riga del Makefile.

Inoltre non si dispone di una regola per creare OBJS_tsnnlsAll. Stai solo passando i nomi di tutti i file oggetto al compilatore che li sta ignorando a causa del flag -c.

È necessario rimuovere $(OBJS_tsnnlsALL) dalla regola tsnnls_test_DKU.o, e rimuovere il tsnnls_test_DKU.o dalla destinazione finale in modo ultime due regole simile a questa:

# 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 
+0

ho ancora lo stesso errore. –