Makefile:将C代码转换为mex代码(链接错误)

我有一个使用makefile C-code which works fineC-code which works fine 。 现在,我正在尝试convert it to mex文件,以便我可以从Matlab运行它。 在这里,我正在using makefile approach 。 但是,mex的makefile给了我错误。

这是我要与我的mex文件一起编译的tsnnls lib 。

C项目组织:

 tsnnls_test_DKU.c Include_4_TSNNLS.c Include_4_TSNNLS.h 

Include_4_TSNNLS.* ”文件具有调用第三部分库的函数TestingLibraries() ; 而我试图保持“ tsnnls_test_DKU.c ”非常简单,因为:

原始代码:tsnnls_test_DKU.c

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

现在,代码已更改:

更改的代码:tsnnls_test_DKU.c:

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

原始make文件(有效

 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注意,我已经用gcc编译器将链接部分恢复为原始版本; 但是,我想在这里使用mex。

我根据自己的理解更改了一些行,并使用了标签“#mex”。

此外,正在成功创建Include_4_TSNNLS.o。 此外,先前通过硬连线所有路径解决了“包含”的先前问题。

  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 

我收到以下链接错误:

 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 

有人可以帮我链接选项吗?

问题是$(OBJS_tsnnls0)(或者至少是libtsnnls_la-taucs_ccs_order.o)中列出的所有目标文件都是在没有-fPIC gcc编译器选项的情况下编译的。 gcc手册页说的是-fPIC

生成适合在共享库中使用的与位置无关的代码(PIC)

请注意,MEX文件是共享库。 因此,所有目标代码都完美地链接到一个独立的可执行文件(不需要PIC),但它只是没有编译链接到MEX文件(或任何共享库)。 如果您有原始源文件,则应该能够通过运行使用正确的开关重新编译它们

$(MEX)-c -o filename .o filename .c

对于每个源文件。

您对tsnnls_test_DKU.o有循环依赖性,因为OBJS_tsnnlsAll扩展为包含OBJS_tsnnls1 ,它在Makefile的第一行中定义为tsnnls_test_DKU.o

您也没有规则来构建OBJS_tsnnlsAll 。 您只是将所有目标文件的名称传递给编译器,由于-c标志而忽略它们。

您应该从tsnnls_test_DKU.o规则中删除$(OBJS_tsnnlsALL) ,并从最终目标中删除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