2015-02-12 10 views
8

Tôi có C-code which works fine bằng cách sử dụng makefile. Bây giờ, tôi đang cố gắng để convert it to mex tập tin để tôi có thể chạy nó từ Matlab. Ở đây cũng có, tôi là using makefile approach. Nhưng, makefile cho mex cho tôi lỗi.Makefile: Chuyển đổi mã C thành mã mex (Lỗi liên kết)

Đây là tsnnls lib mà tôi muốn biên dịch cùng với tệp mex của tôi.

Tổ chức của C-dự án:

tsnnls_test_DKU.c 
Include_4_TSNNLS.c 
Include_4_TSNNLS.h 

"Include_4_TSNNLS.*" file có chức năng TestingLibraries() mà gọi thư viện phần thứ 3; trong khi tôi cố gắng giữ "tsnnls_test_DKU.c" rất đơn giản như:

gốc Mã số: tsnnls_test_DKU.c

int TestingLibraries() ; 

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

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

Bây giờ, các mã đã được thay đổi:

đang thay đổi: 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() ; 

} 

Original mak tập tin điện tử (làm việc

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) $^ 

Makefile đã thay đổi mà không chạy Thông báo, tôi phải phục hồi các bộ phận liên kết đến ban đầu với trình biên dịch gcc; tuy nhiên, tôi muốn sử dụng mex ở đây.

Tôi đã thay đổi một số dòng dựa trên sự hiểu biết của mình và đã sử dụng thẻ "# mex".

Ngoài ra, Include_4_TSNNLS.o đang được tạo thành công. Ngoài ra, vấn đề trước đó với "bao gồm" đã được giải quyết bằng cách cứng dây tất cả các đường dẫn.

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 

tôi nhận được các lỗi liên kết sau:

[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 

thể một ai đó hãy giúp tôi với các tùy chọn liên kết?

+1

sử dụng -I (matlab_dir)/extern/include chỉ makefile đến tiêu đề – user3528438

+0

@ user3528438 Tôi nghĩ rằng tôi đã sử dụng bao gồm: 'INCLUDE = -I $ (MATLABHOME)/extern/include $ (INCLUDE_TSNNLS)' và sau đó bao gồm điều này trong khi thực hiện TARGET. Nhưng, tôi có thể đã vượt qua nó sai trong các tùy chọn trình biên dịch và không thể tìm ra. –

+1

Ở cuối mã của bạn, bạn đang sử dụng "gcc -c -o ..." để biên dịch và sử dụng "$ (MEX) -g -o ...." để liên kết. Khi $ (INCLUDE) của bạn là sau $ (MEX), do đó, nó được coi là một tùy chọn trình liên kết chứ không phải là tùy chọn trình biên dịch. Thử di chuyển $ (INCLUDE) và $ (CFLAGS) gần gcc hơn. – user3528438

Trả lời

4

Vấn đề là tất cả các tệp đối tượng được liệt kê bằng $ (OBJS_tsnnls0) (hoặc ít nhất, libtsnnls_la-taucs_ccs_order.o) đã được biên dịch mà không có tùy chọn trình biên dịch gcc -fPIC. Trang người dùng gcc nói cho -fPIC

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

Lưu ý rằng tệp MEX là thư viện được chia sẻ. Vì vậy, tất cả các mã đối tượng liên kết hoàn toàn tốt vào một thực thi độc lập (không yêu cầu PIC), nhưng nó chỉ là không biên dịch quyền liên kết vào một tệp MEX (hoặc bất kỳ thư viện được chia sẻ nào). Nếu bạn có các tập tin nguồn gốc, bạn sẽ có thể biên dịch lại chúng với thiết bị chuyển mạch bằng việc tiến hành

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

cho mỗi các tệp nguồn.

+0

lib dường như sử dụng một số autotools (libtool). Trong khi sử dụng 'makefile' sau' configure' trong $ (OBJS_tsnnls0), tôi có thể thấy lệnh như sau: 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' . Có vẻ như đã sử dụng '-fPIC' rồi. Tôi nên thay đổi lệnh này thành gì? –

+0

Có, tôi có thư viện đã tải xuống và tất cả các mã nguồn: jasoncantarella.com/wordpress/software/tsnnls. Đó là makefile đang được tạo ra bằng cách sử dụng 'makefile.am'. Tuy nhiên, với điều kiện tôi không giỏi ở C, tôi không thể tìm ra cách 'makefile.am-> makefile' và cách' thay đổi cờ hoặc trình biên dịch'. Bạn có thể tự mình thử thư viện này và giúp tôi khắc phục sự cố này không? Tôi thực sự sẽ thực sự nợ cuộc sống của tôi cho bạn vì điều này. Tôi sẽ hạnh phúc hơn đặc biệt 'cảm ơn bạn trong bài viết của tôi hoặc đặt bạn là đồng tác giả của tôi'. Điều này sẽ giải quyết một vấn đề nổi bật trong hình ảnh y tế; do đó, rất quan trọng –

2

Bạn có phụ thuộc vòng tròn trên tsnnls_test_DKU.oOBJS_tsnnlsAll mở rộng để bao gồm OBJS_tsnnls1 được định nghĩa là tsnnls_test_DKU.o trong dòng đầu tiên của Makefile.

Ngoài ra, bạn không có quy tắc để xây dựng OBJS_tsnnlsAll. Bạn chỉ cần chuyển tên của tất cả các tệp đối tượng vào trình biên dịch, bỏ qua chúng vì cờ -c.

Bạn nên loại bỏ $(OBJS_tsnnlsALL) từ sự cai trị tsnnls_test_DKU.o, và loại bỏ các tsnnls_test_DKU.o từ mục tiêu cuối cùng để hai quy tắc cuối cùng trông như thế này:

# 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

Tôi vẫn gặp lỗi tương tự. –

Các vấn đề liên quan