2014-09-18 14 views
11

Vì vậy, tôi có một chương trình chạy với OpenBlas và tôi muốn biên dịch nó. Quá trình liên kết trông giống như sau:Tại sao LD_LIBRARY_PATH là BAD và cách chính xác để tải thư viện động

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas 

Cho đến nay rất tốt. Nếu tôi xóa tùy chọn -L, tôi gặp lỗi trong quy trình liên kết

/usr/bin/ld: cannot find -lopenblas 

Với mọi liên kết không có lỗi. Tuy nhiên, khi tôi cố gắng chạy nó tôi nhận được lỗi sau:

./prog: error while loading shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory 

Nếu tôi đặt biến env LD_LIBRARY_PATH-/opt/OpenBlas/lib tôi có thể chạy các chương trình, nhưng nhiều nguồn như http://xahlee.info/UnixResource_dir/_/ldpath.html coi đây là một thực tế xấu và tôi có thể hiểu hầu như tất cả các lý do. Phương pháp khác được đề cập trong bài viết (sửa đổi cấu hình ld) cũng được coi là một thực tế không tốt. Cuối cùng, bạn chỉ có thể thêm một liên kết tượng trưng vào thư viện trong /usr/lib. Một vấn đề lớn với hai phương thức cuối cùng là bạn cần truy cập sudo. Vì vậy, câu hỏi của tôi là làm thế nào tôi có thể biên dịch và chạy một chương trình liên kết với một thư viện được chia sẻ không nằm trong đường dẫn mặc định (/usr/lib) mà không cần sử dụng LD_LIBRARY_PATH và truy cập sudo. Trong bài viết họ nói rằng bạn chỉ có thể 'viết' trong nhị phân nơi để tìm kiếm các thư viện được chia sẻ nhưng tôi không biết làm thế nào để làm điều đó (cờ -L dường như không được làm điều đó). Tôi sẽ đánh giá cao nếu bất cứ ai có thể giải thích vấn đề này, vì tôi đã tìm kiếm ở khắp mọi nơi và tôi rất bối rối (một số tài liệu tham khảo dường như cho rằng cờ `-L 'nên làm điều đó nhưng tôi không làm việc cho tôi). Cảm ơn bạn trước.

+0

Bạn có thể sử dụng -rpath để thiết lập các đường dẫn tìm kiếm thư viện runtime – sshannin

Trả lời

12

Thêm đường dẫn đến đường dẫn tìm kiếm trong thư viện thời gian chạy.

gcc -Wl,-rpath=/opt/OpenBlas/lib ... 

Tùy chọn -L làm gì tại thời điểm liên kết, tùy chọn -rpath sẽ hoạt động vào thời gian chạy.

+3

Đây có lẽ là câu trả lời OP đang tìm kiếm, mặc dù nó cũng xấu bởi vì nó được xây dựng con đường vào thực thi, đòi hỏi thực thi được biên dịch lại chuyển nơi ở thư viện . Vì vậy, về cơ bản bạn nên hiểu tất cả các giải pháp, tại sao tất cả chúng đều xấu, và sau đó chọn một giải pháp tồi tệ nhất cho trường hợp sử dụng của bạn. ;) –

+0

@DavidSchwartz: Bạn có thể di chuyển thư viện mà không cần biên dịch lại, bạn chỉ cần di chuyển nó đến một nơi khác trong đường dẫn tìm kiếm thời gian chạy ... đó là lựa chọn tương tự bạn có nếu bạn không sử dụng '-rpath'. Và bạn luôn có thể sử dụng 'LD_LIBRARY_PATH' nếu bạn thực sự muốn di chuyển thư viện ở một nơi khác. Xin lỗi, tôi không thấy những hạn chế, ngoại trừ khả năng '-rpath' hơi ồn * nếu bạn sao chép nhị phân sang hệ thống khác. –

+0

@DavidSchwartz: Bạn cũng có thể sửa đổi 'đường dẫn 'mà không biên dịch lại, sử dụng công cụ' chrpath'.Bạn không thể làm điều này trên OS X trừ khi 'rpath' mới ngắn hơn, nhưng than ôi, không có gì là hoàn hảo. –

5

Trên Linux, bạn cũng có thể sử dụng $ ORIGIN trong rpath để có nghĩa là đường dẫn thư mục đến ứng dụng và tạo đường dẫn tương đối từ đó. Sau đó bạn sẽ di chuyển thư viện đến một đường dẫn tương đối đã biết đến nhị phân.

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -Wl,-rpath=\$ORIGIN/lib -L/opt/OpenBLAS/lib -lopenblas 

Bạn cũng có thể sử dụng đầy đủ đường dẫn đến THƯ VIỆN, và nó sẽ được liên kết trong:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include /opt/OpenBLAS/lib/libopenblas.so 

Nếu bạn chạy "ldd" trên thực thi, bạn sẽ thấy đường dẫn đầy đủ mã hóa.

+0

Bạn sẽ cần báo giá '$ ORIGIN', hoặc trình bao sẽ mở rộng nó (có thể là một chuỗi rỗng). ''-Wl, -rpath = $ ORIGIN/lib'' sẽ hoạt động. –

+0

bắt tốt, cảm ơn – Juan

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