2010-02-02 23 views
9

Tôi đang cố gắng viết một hàm mex matlab sử dụng libhdf5; Cài đặt Linux của tôi cung cấp libhdf5-1.8 thư viện và tiêu đề được chia sẻ. Tuy nhiên, phiên bản Matlab của tôi, r2007b, cung cấp một libhdf5.so từ bản phát hành 1.6. (Matlab .mat tệp bootstrap hdf5, hiển nhiên). Khi tôi biên dịch mex, nó phân tách trong Matlab. Nếu tôi hạ cấp phiên bản libhdf5 xuống 1.6 (không phải tùy chọn dài hạn), mã sẽ biên dịch và chạy tốt.địa điểm thư viện được chia sẻ cho các tệp matlab mex:

câu hỏi: làm cách nào để giải quyết vấn đề này? làm thế nào để tôi nói với quá trình biên dịch mex để liên kết với /usr/lib64/libhdf5.so.6 thay vì /opt/matlab/bin/glnxa64/libhdf5.so.0? Khi tôi cố gắng thực hiện việc này bằng cách sử dụng -Wl,-rpath-link,/usr/lib64 trong biên soạn của mình, tôi nhận được các lỗi như:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libhdf5.so.0, needed by /opt/matlab/matlab75/bin/glnxa64/libmat.so, may conflict with libhdf5.so.6 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crt1.o: In function `_start': 
(.text+0x20): undefined reference to `main' 
collect2: ld returned 1 exit status 

    mex: link of 'hdf5_read_strings.mexa64' failed. 

make: *** [hdf5_read_strings.mexa64] Error 1 

ack. phương án cuối cùng sẽ là tải xuống một bản sao cục bộ của các tiêu đề hdf5-1.6.5 và được thực hiện với nó, nhưng đây không phải là bằng chứng trong tương lai (bản nâng cấp phiên bản Matlab là trong tương lai của tôi). bất kỳ ý tưởng?

EDIT: mỗi gợi ý tuyệt vời Ramashalanka, tôi

A) gọi là mex -v để có được 3 gcc lệnh; cuối cùng là lệnh linker;

B) được gọi là lệnh trình liên kết đó với -v để nhận lệnh collect;

C) được gọi là collect2 -v -t và phần còn lại của cờ.

Các bộ phận có liên quan của đầu ra của tôi:

/usr/bin/ld: mode elf_x86_64 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crti.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtbeginS.o 
hdf5_read_strings.o 
mexversion.o 
-lmx (/opt/matlab/matlab75/bin/glnxa64/libmx.so) 
-lmex (/opt/matlab/matlab75/bin/glnxa64/libmex.so) 
-lhdf5 (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libhdf5.so) 
/lib64/libz.so 
-lm (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libm.so) 
-lstdc++ (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libstdc++.so) 
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so) 
/lib64/libpthread.so.0 
/lib64/libc.so.6 
/lib64/ld-linux-x86-64.so.2 
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so) 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtendS.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crtn.o 

Vì vậy, trên thực tế các libhdf5.so từ /usr/lib64 đang được tham chiếu. Tuy nhiên, điều này đang được overriden, tôi tin rằng, bởi biến môi trường LD_LIBRARY_PATH, phiên bản của tôi của Matlab automagically thiết lập tại thời gian chạy để nó có thể xác định vị trí các phiên bản riêng của nó ví dụ. libmex.so, v.v.

Tôi nghĩ rằng ví dụ crt_file.c hoạt động hoặc b/c nó không sử dụng chức năng tôi đang sử dụng (H5DOpen, có thay đổi chữ ký trong di chuyển từ 1,6 đến 1,8 (vâng, tôi đang sử dụng -DH5_USE_16_API)), hoặc, ít có khả năng, b/c nó không nhấn các phần của nội bộ Matlab cần hdf5. ack.

+0

Trong đầu ra của bạn tôi thấy 'lib64/libhdf5.so' mà là một thư viện động. Bạn cần xác định đường dẫn rõ ràng cho thư viện tĩnh (với hậu tố .o) và không sử dụng '-lhdf5'. Sau đó, đăng đầu ra liên kết mới nếu nó vẫn không hoạt động. Nếu tệp '.so' là tệp duy nhất trong danh sách thì đó là tệp duy nhất được bao gồm. 'LD_LIBRARY_PATH' hoặc bất kỳ đường dẫn nào khác, chẳng hạn như trong' -L' không quan trọng nếu bạn không có '-lhdf5' làm tùy chọn và bạn chỉ định đường dẫn đến thư viện tĩnh một cách rõ ràng (xem bên dưới). Tôi đồng ý với ý kiến ​​của bạn về 'h5_crtfile.c', nhưng tất cả thông tin chúng tôi cần đều nằm trong đầu ra liên kết của bạn ở trên. – Ramashalanka

+0

Tôi không có tệp 'libhdf5.o'; Gói hdf5 của gentoo cung cấp 'libhdf5.so',' libhdf5.a', 'libhdf5.la' và một số tệp fortran và cpp. Tôi có phải tự biên dịch libhdf5 không? đây là một lựa chọn ... – shabbychef

+0

Xin lỗi, ý tôi là '.a', không phải' .o'. Bạn có thể kiểm tra xem tệp 'libhdf5.a' bạn có là phiên bản chính xác hay không, ví dụ: 'strings libhdf5.a'. Tôi thấy 'HDF5 Version: 1.8.4' trong của tôi. Nếu bạn không thể nhận được thư viện tĩnh đúng như một nhị phân, nó rất dễ dàng để biên dịch. Xem nhận xét của tôi cho truy vấn khác của bạn bên dưới. – Ramashalanka

Trả lời

8

Sau đây làm việc trên hệ thống của tôi:

  1. Install hdf5 phiên bản 1.8.4 (bạn đã làm điều này: Tôi đã cài đặt nguồn và biên soạn để đảm bảo nó là tương thích với hệ thống của tôi, rằng tôi nhận được phiên bản gcc và tôi nhận được các thư viện tĩnh - ví dụ: các tệp nhị phân được cung cấp cho hệ thống của tôi là icc cụ thể).

  2. Tạo tệp đích. Bạn đã có tệp riêng của mình. Tôi đã sử dụng đơn giản h5_crtfile.c từ here (một ý tưởng hay để bắt đầu với tệp đơn giản này trước tiên là tìm kiếm các cảnh báo). Tôi đã thay đổi main thành mexFunction bằng số arg thông thường và bao gồm mex.h.

  3. Chỉ định thư viện tĩnh 1.8.4 bạn muốn tải một cách rõ ràng (các đường dẫn đầy đủ với không -L cho thấy cần thiết) và không bao gồm -lhdf5 trong LDFLAGS.Bao gồm tùy chọn -t để bạn có thể đảm bảo rằng không có thư viện hdf5 động nào được tải. Bạn cũng cần -lz, với cài đặt zlib. Đối với darwin chúng ta cũng cần một -bundle trong LDFLAGS:

    mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v 
    

    Đối với Linux, bạn cần một cuộc gọi vị trí độc lập tương đương, ví dụ fPIC và có thể -shared, nhưng tôi không có một hệ thống Linux với một giấy phép matlab, vì vậy tôi không thể kiểm tra:

    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v 
    
  4. Chạy h5_crtfile tập tin mex. Điều này chạy mà không có vấn đề trên máy tính của tôi. Nó chỉ thực hiện một H5Fcreate và H5Fclose để tạo ra "file.h5" trong thư mục hiện tại, và khi tôi gọi file file.h5 tôi nhận được file.h5: Hierarchical Data Format (version 5) data.

Lưu ý rằng nếu tôi bao gồm -lhdf5 trên trong bước 3, sau đó matlab hủy bỏ khi tôi cố gắng chạy file thực thi (vì nó sau đó sử dụng các thư viện động matlab của mà đối với tôi là phiên bản 1.6.5), vì vậy đây là chắc chắn giải quyết vấn đề trên hệ thống của tôi.

Cảm ơn câu hỏi. Giải pháp của tôi ở trên chắc chắn dễ dàng hơn nhiều so với những gì tôi đã làm trước đây. Hy vọng rằng các công trình trên cho bạn.

+0

hmmm. khi tôi thử điều này, trình biên dịch không thành công b/c 'libmat.so' dựa trên' libhdf5.so'. một cái gì đó kỳ lạ ở đó. Thật không may, tôi không thể bao gồm 'mex.h' mà không cần phải kéo vào HDF5 của Mathworks; đáng tiếc, các tệp tiêu đề được Mathworks phân phối không bao gồm 'hdf5.h'. – shabbychef

+0

OK, tôi đã viết lại bài đăng, xem bài đăng đó như thế nào. – Ramashalanka

+0

Tôi biên dịch trong trình bao với lệnh gcc nhổ ra bởi mex. Vì vậy, tôi đã thử giải pháp của bạn, bỏ qua bước 2 & 3; ('-bundle' là Darwin cụ thể, BTW) sử dụng' h5_crtfile.c', tôi nhận được "Cảnh báo! Các tệp tiêu đề HDF5 được bao gồm trong ứng dụng này không khớp với phiên bản được sử dụng bởi Dữ liệu lỗi tham nhũng hoặc phân khúc có thể xảy ra nếu ứng dụng tiếp tục .'Biến môi trường' HDF5_DISABLE_VERSION_CHECK ', ứng dụng sẽ tiếp tục. Tiêu đề là 1.8.4, thư viện là 1.6.5 " tuy nhiên, 'file.h5' được tạo! NHƯNG, với mẹo này trên mex của tôi, nó vẫn còn segfaults. – shabbychef

3

Tôi chấp nhận câu trả lời Ramashalanka vì nó dẫn tôi đến giải pháp chính xác mà tôi sẽ gửi vào đây để chỉ đầy đủ:

  1. tải thư viện hdf5-1.6.5 từ trang web hdf5, và cài đặt các tập tin tiêu đề trong một thư mục cục bộ;
  2. nói mex để tìm kiếm "hdf5.h" trong thư mục địa phương này, chứ không phải ở vị trí tiêu chuẩn (ví dụ /usr/include.)
  3. nói mex để biên dịch mã của tôi và thư viện đối tượng chia sẻ được cung cấp bởi matlab, và làm không sử dụng cờ -ldfh5 trong LDFLAGS.

lệnh Tôi đã từng là, về cơ bản:

/opt/matlab/matlab_default/bin/mex -v CC#gcc CXX#g++ CFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include" CXXFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include " -O -lmwblas -largeArrayDims -L/usr/lib64 hdf5_read_strings.c /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 

này được dịch bằng mex vào lệnh:

gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG hdf5_read_strings.c 
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG /opt/matlab/matlab75/extern/src/mexversion.c 
gcc -O -pthread -shared -Wl,--version-script,/opt/matlab/matlab75/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o hdf5_read_strings.mexa64 hdf5_read_strings.o mexversion.o -lmwblas -L/usr/lib64 /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 -Wl,-rpath-link,/opt/matlab/matlab_default/bin/glnxa64 -L/opt/matlab/matlab_default/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++ 

giải pháp này sẽ làm việc trên tất cả các máy mục tiêu khác nhau của tôi và ít nhất cho đến khi tôi nâng cấp lên matlab r2009a, tôi tin rằng sử dụng hdf5-1.8. cảm ơn tất cả sự giúp đỡ, xin lỗi vì đã quá dày đặc với điều này - tôi nghĩ rằng tôi đã quá cam kết sử dụng phiên bản đóng gói của hdf5, chứ không phải là một tập hợp địa phương của các tập tin tiêu đề.

Chú giải này sẽ tất cả đã tầm thường nếu MathWorks đã cung cấp một bộ các tập tin tiêu đề với sự phân bố Matlab ...

+0

Đây là cách tôi xử lý các tệp mex đa luồng cần thiết để liên kết chuỗi tăng tốc. Nhưng phải có một số cách để làm cho nó liên kết với thư viện hệ thống thay vì một trong Matlab và tránh các segfaults theo cách đó. Đang bị mắc kẹt với bất cứ điều gì thúc đẩy bên trong Matlab không phải là rất tốt đẹp. – Chinasaur

+0

Về những gợi ý hữu ích của Ramashalanka, tôi cũng có thể nói rằng với tình huống liên kết tăng luồng của tôi, tôi phải thực hiện giải pháp này trong Linux nhưng không phải trong Mac; trong Mac có vẻ như lệnh mex không liên kết trong các phiên bản nội bộ như trong Linux. – Chinasaur

+1

Một cái gì đó giống như câu trả lời ở đây: http://stackoverflow.com/questions/9927568/compiling-c11-code-as-part-of-a-matlab-mex-file có thể hoạt động (mặc dù câu hỏi dành cho điều gì đó hơi khác) . Tôi sẽ báo cáo lại nếu tôi làm cho nó hoạt động. – Chinasaur

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