2011-11-07 20 views
15

Tôi đang cố gắng biên dịch một trong các dự án được tìm thấy tại đây Bộ điều hợp giao diện USB-I2C/SPI/GPIO.Không thể mở tệp đối tượng được chia sẻ

Tôi đã tải xuống gói i2c_bridge-0.0.1-rc2.tgz. Tôi đã cài đặt libusb và dường như hoạt động tốt mà không có vấn đề gì. Tôi đi vào thư mục i2c_bridge-0.0.1-rc2/ và thực hiện. Điều đó biên dịch. Tôi chuyển vào thư mục i2c_bridge-0.0.1-rc2/i2c và thực hiện. Nó biên dịch và cho tôi ./i2c. Tuy nhiên, khi tôi chạy nó, nó nói error while loading shared libraries: libi2cbrdg.so: cannot open shared object file: No such file or directory

Makefile in i2c_bridge-0.0.1-rc2/i2c có thư mục thư viện là ../. libi2cbrdg.so nằm trong thư mục này (i2c_bridge-0.0.1-rc2). Tôi cũng đã sao chép tệp này vào /usr/local/lib. Một ls của thư mục i2c_bridge-0.0.1-rc2/

i2c  i2cbrdg.d i2cbrdg.o libi2cbrdg.a Makefile tests 
i2cbrdg.c i2cbrdg.h INSTALL libi2cbrdg.so README u2c4all.sh 

(Đó i2c là một thư mục)

Nếu tôi sudo ./i2c, nó vẫn mang lại cho tôi những vấn đề.

Tôi phải lấy các tùy chọn -Werror-noWdecrepated (chính tả?) Trong tất cả các tệp makefiles để làm cho chúng biên dịch, nhưng điều đó không ảnh hưởng đến điều này?

Điều gì khác cần thiết để tìm tệp .so? Nếu bất cứ ai có thể giúp tôi tìm ra điều gì sai, tôi sẽ rất biết ơn. Nếu cần thêm thông tin, tôi có thể đăng nó.

Trả lời

39

Bạn phải phân biệt giữa việc tìm kiếm tại thời điểm biên dịch và thời gian chạy. Cờ -L bạn cung cấp tại thời gian biên dịch không liên quan gì tới việc bản địa hóa thư viện lúc chạy. Điều này được thực hiện khá tốt thông qua một số biến và một số đường dẫn được nhúng trong thư viện.

Các hot-sửa chữa tốt nhất cho vấn đề này thường được thiết lập LD_LIBRARY_PATH vào thư mục với file .so, ví dụ:

$ LD_LIBRARY_PATH=.. ./i2c 

Đối với một giải pháp lâu dài, bạn cần phải hoặc là có một cái nhìn cận cảnh toàn bộ hệ thống LD với rpath và runpath, hoặc sử dụng libtool (giải quyết những vấn đề này cho bạn một cách dễ dàng).

Sao chép tệp vào/usr/local/lib thường không đủ vì ld lưu trữ các thư viện có sẵn, vì vậy bạn cần chạy lại ldconfig (làm thư mục gốc) sau khi sao chép thư viện vào/usr/local/lib.

+0

LD_LIBRARY_PATH có phải là tất cả thư viện của tôi không? Vì vậy, nếu tôi làm điều đó lệnh, nó sẽ mess up những thứ khác cho đến khi tôi thay đổi nó trở lại? Làm thế nào để tôi xem nó được thiết lập cho đến bây giờ? – Sterling

+2

Đó là một biến môi trường. Vì vậy, bạn có thể kiểm tra nó thông qua "echo $ LD_LIBRARY_PATH" và, cách nó được thiết lập trong dòng lệnh, là cục bộ cho quá trình i2c và các quy trình con của nó. – thiton

+1

Không phải câu hỏi của tôi, nhưng cảm ơn điều này đã giúp giải quyết vấn đề chính xác của tôi – Rich

25

Nếu bạn đang xây dựng mã từ nguồn cần thư viện, bạn có thể đặt đường dẫn thư viện ở trong biến môi trường LD_RUN_PATH trước khi xây dựng và trình liên kết sẽ lưu đường dẫn đó vào nhị phân, sao cho nó sẽ tự động được tìm kiếm ở đúng nơi khi chạy.

Linux cụ thể: Cách khác, đặt thư viện trong /lib, /usr/lib, hoặc một số con đường khác được tham chiếu trong /etc/ld.so.conf hay mảnh vỡ cấu hình nhập khẩu của bạn, và sau đó tất cả các bạn cần làm là chạy /sbin/ldconfig để làm mới ld.so (mối liên kết động) 's bộ nhớ cache của thư viện.

+0

Mặc dù tôi đã có '/ usr/local/lib' trong'/etc/ld.so.conf.d/libc.conf', thư viện liên kết động ** làm mới bộ nhớ cache ** với 'sudo ldconfig' là nó đã làm gì cho tôi. –

1

Điều này phù hợp với vấn đề của tôi, hy vọng sẽ giúp mọi người.

gcc test.c -Wl,-rpath /usr/local/lib -lfcgi -o test.fcg 

Và tùy chọn -Wl,-rpath là mẹo chính.