Làm thế nào để bạn xác định vị trí của các thư viện thành một nhị phân? (linux)


34

Đối với câu hỏi này, tôi sẽ sử dụng một ví dụ cụ thể, nhưng thực sự điều này khái quát cho hầu hết mọi nhị phân trên linux mà dường như không thể tìm thấy các thư viện phụ thuộc của nó. Vì vậy, tôi có một chương trình sẽ không chạy vì thiếu các thư viện:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd làm sáng tỏ vấn đề:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

Tuy nhiên, corona được cài đặt:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

Làm thế nào để tôi nói nhị phân nơi tìm thư viện "mất tích"?

Câu trả lời:


43

Đối với một lần tắt, đặt biến LD_LIBRARY_PATHthành một danh sách các thư mục được phân tách bằng dấu hai chấm để tìm kiếm. Điều này tương tự với PATHcác tệp thực thi, ngoại trừ các thư mục hệ thống tiêu chuẩn được tìm kiếm bổ sung sau các thư mục được chỉ định trong môi trường.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Nếu bạn có một chương trình giữ các thư viện ở một vị trí không chuẩn và không thể tự tìm thấy chúng, bạn có thể viết một tập lệnh bao bọc:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

Danh sách các thư mục hệ thống tiêu chuẩn được giữ trong /etc/ld.so.conf. Các hệ thống gần đây cho phép tệp này bao gồm các tệp khác; nếu include /etc/ld.so.conf.d/*.conftệp của bạn chứa nội dung nào đó giống như , hãy tạo một tệp mới /etc/ld.so.conf.d/mala.confcó tên chứa các thư mục bạn muốn thêm. Sau khi bạn thay đổi /etc/ld.so.confhoặc một tệp được bao gồm, hãy chạy /sbin/ldconfigđể các thay đổi của bạn có hiệu lực (điều này cập nhật bộ đệm).

( LD_LIBRARY_PATHCũng áp dụng cho nhiều unices khác, bao gồm FreeBSD, NetBSD, OpenBSD, Solaris và Tru64. HP-UX có SHLIB_PATHvà Mac OS X có DYLD_LIBRARY_PATH. /etc/ld.so.confCó chất tương tự trên hầu hết các unices nhưng vị trí và cú pháp khác rộng rãi hơn.)


1
Tuyệt vời, cảm ơn bạn rất nhiều. Tôi không có ý tưởng gì về /etc/ld.so.conf và nó sẽ rất hữu ích với tôi trong tương lai.
Mala

15

Nếu bạn muốn tránh LD_LIBRARY_PATH, bạn cũng có thể thực hiện việc này trong quá trình liên kết:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

-Wl, ... được sử dụng để truyền các lệnh bổ sung cho trình liên kết và trong trường hợp này, với -R, bạn báo cho trình liên kết lưu trữ đường dẫn này làm "đường dẫn tìm kiếm mặc định" cho .so.

Tôi ghi chú nhiều mẹo nhỏ như thế này, tại trang web của tôi:

https://www.thanrame.space/tricks.html


Nhưng nếu chính thư viện nghi vấn có các thư viện chia sẻ để tra cứu, thì đường dẫn được lưu trữ trong tệp nhị phân không được áp dụng đệ quy cho các tra cứu thư viện con. Tôi chưa tìm thấy cách nào khác ngoài việc đặt LD_LIBRARY_PATH trong môi trường, sau đó sẽ được áp dụng cho tra cứu đệ quy ...
Ethan

@Ethan: Đúng. Nhưng điều cũng đúng là các kịch bản thông thường nơi bạn muốn "đóng gói" các thư viện dùng chung cho một số nhị phân, là một trong những nơi bạn đặt chúng cùng nhau; ví dụ /opt/mypackage/bin/someBinarysẽ cần libs mà bạn lưu trữ /opt/mypackage/lib/. Khá nhiều tất cả các SW độc quyền được cài đặt theo / opt tuân theo quy tắc này - có nghĩa là cách hiển thị ở trên sẽ bao gồm tất cả các cài đặt như vậy. Sau đó, họ thường sẽ thêm một liên kết tượng trưng bên dưới / usr / bin trỏ đến nhị phân bên dưới / opt - biết rằng "đường dẫn tìm kiếm mặc định" sẽ tìm thấy .sos trong /opt/.../libthư mục thích hợp .
ttsiodras

vâng, trong trường hợp của tôi, tôi muốn kiểm tra một gói bằng cách liên kết với thư mục xây dựng của nó thay vì cài đặt nó ... (nhưng gói có một số nội bộ. với một số phụ thuộc lẫn nhau ... nhiều cách giải quyết khác nhau nhưng chỉ gây phiền nhiễu)
Ethan

0

Điều này cho thấy libcorona không được cài đặt trong đường dẫn chính xác. Di chuyển thư mục libcorona đến đúng đường dẫn, vấn đề sẽ được giải quyết ..


Làm thế nào là điều này tốt hơn so với câu trả lời khác?
Toto

@Toto không giống như các câu trả lời khác, về cơ bản bạn đang cài đặt các tệp theo cách thủ công ... Mặc dù điều đó không có nghĩa chính xác câu trả lời này tốt hơn, nhưng đó là một tùy chọn nên được xem xét (mọi người cũng làm điều này trong Windows bằng cách sao chép thư viện vào system32 / sysWOW64 khi các ứng dụng của họ không thể tìm thấy chúng), không phải là điều đó được khuyến khích, vì nó rất nản lòng.
Tcll
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.