Trường hợp thực thi tìm kiếm các đối tượng chia sẻ trong thời gian chạy?


102

Tôi hiểu làm thế nào để xác định bao gồm các đối tượng chia sẻ tại thời gian liên kết / biên dịch. Tuy nhiên, tôi vẫn tự hỏi làm thế nào để các thực thi tìm kiếm đối tượng chia sẻ ( *.sothư viện) tại thời điểm thực hiện.

Chẳng hạn, ứng dụng của tôi a.outgọi các hàm được định nghĩa trong lib.sothư viện. Sau khi biên dịch, tôi chuyển lib.sosang một thư mục mới trong $HOME.

Làm thế nào tôi có thể nói a.outđể đi tìm nó ở đó?

Câu trả lời:


102

Các chia sẻ HOWTO thư viện giải thích hầu hết các cơ chế liên quan, và các bộ nạp thủ công động đi vào chi tiết hơn. Mỗi biến thể unix có cách riêng, nhưng hầu hết sử dụng cùng định dạng thực thi ( ELF ) và có các trình liên kết động tương tự (có nguồn gốc từ Solaris). Dưới đây tôi sẽ tóm tắt các hành vi phổ biến với trọng tâm là Linux; kiểm tra hướng dẫn sử dụng hệ thống của bạn để biết câu chuyện hoàn chỉnh.

Tóm lại, khi tìm kiếm một thư viện động ( .sotệp), trình liên kết sẽ thử:

  • các thư mục được liệt kê trong LD_LIBRARY_PATHbiến môi trường ( DYLD_LIBRARY_PATHtrên OSX);
  • các thư mục được liệt kê trong rpath thực thi ;
  • các thư mục trên đường dẫn tìm kiếm hệ thống, mà (ít nhất là trên Linux) bao gồm các mục /etc/ld.so.confcộng /lib/usr/lib.

Đường dẫn được lưu trữ trong tệp thực thi ( thuộc tính động DT_RPATHhoặc DT_RUNPATHthuộc tính động). Nó có thể chứa các đường dẫn hoặc đường dẫn tuyệt đối bắt đầu $ORIGINđể chỉ ra một đường dẫn liên quan đến vị trí của tệp thực thi (ví dụ: nếu tệp thực thi nằm trong /opt/myapp/binvà đường dẫn của nó là $ORIGIN/../lib:$ORIGIN/../pluginsthì trình liên kết động sẽ nhìn vào /opt/myapp/lib/opt/myapp/plugins). Thông thường rpath được xác định khi thực thi được biên dịch, với -rpathtùy chọn này ld, nhưng bạn có thể thay đổi nó sau đó chrpath.

Trong kịch bản mà bạn mô tả, nếu bạn là nhà phát triển hoặc đóng gói của ứng dụng và có ý định cho nó được cài đặt trong một …/bin, …/libkết cấu, sau đó liên kết với -rpath='$ORIGIN/../lib'. Nếu bạn đang cài đặt nhị phân dựng sẵn trên hệ thống của mình, hãy đặt thư viện vào một thư mục trên đường dẫn tìm kiếm ( /usr/local/libnếu bạn là quản trị viên hệ thống, nếu không là thư mục bạn thêm vào $LD_LIBRARY_PATH) hoặc thử chrpath.


3
Trên một số hệ thống, /lib64/usr/lib64được sử dụng cho các nhị phân 64 bit /lib/usr/libđược sử dụng cho các nhị phân 32 bit.
Mark Lakata

Tại sao câu trả lời đúng này không nói gì về ldconfig ??
Yêu xác suất

1
@LoveProbability Vì câu hỏi là về nơi thực thi tìm thư viện, không liên quan ldconfig. ldconfigđược tham gia khi bạn cài đặt một thư viện.
Gilles

1
Lưu ý rằng "đường dẫn tìm kiếm hệ thống" cho *.socác thư viện không giống như $PATH. Đường dẫn tìm kiếm được đưa ra bởi @enzotib trong câu trả lời của họ. Để in ra các đường dẫn sẽ được tìm kiếm, chạy ldconfig -v 2>/dev/null | grep -v ^$'\t'.
Andrew Bate

đối với tôi, để chạy ldconfig, tôi cần /sbin/ldconfigvà phép thuật khác của Andrew Bate để khiến nó chạy không root
Robert Lugg

16

Trong Linux, hành vi được khám phá trong ld(1)trang man

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.

1
"Các thư mục mặc định, thường / lib và / usr / lib." -> làm thế nào tôi có thể tìm ra nếu hệ thống của tôi bình thường?
Thorsten Staerk

2
Câu hỏi là về thời gian chạy và không phải thời gian liên kết
Talespin_Kit 6/03/2015

2

Tôi khá chắc chắn câu trả lời ở đây là ldconfig.

ldconfig tạo các liên kết và bộ đệm cần thiết cho các thư viện chia sẻ gần đây nhất được tìm thấy trong các thư mục được chỉ định trên dòng lệnh, trong tệp /etc/ld.so.conf và trong các thư mục đáng tin cậy (/ lib và / usr / lib). Bộ đệm được sử dụng bởi trình liên kết thời gian chạy, ld.so hoặc ld-linux.so. ldconfig kiểm tra tiêu đề và tên tệp của các thư viện mà nó gặp phải khi xác định phiên bản nào cần cập nhật liên kết của chúng.

http://linux.die.net/man/8/ldconfig


0

Để chạy các ứng dụng, tệp /proc/1234/mapschứa tất cả các thư viện được liên kết động thực tế.

Trường hợp 1234là pid của thực thi đang chạy.

Linux tuân theo LD_LIBRARY_PATH và các biến khác, như được chỉ ra trong câu trả lời của Gilles.


4
Thật tuyệt khi bạn xác nhận trong câu thứ hai của mình rằng câu trả lời của Gilles giúp ích. Tuy nhiên, phần đầu tiên hoàn toàn không đóng góp vào việc giải thích làm thế nào để biết a.out nơi các tệp đang ở đâu, chỉ nơi chúng được lấy từ khi chúng đã được tìm thấy. Tất cả trong tất cả điều này chỉ nên là một nhận xét, không phải là một câu trả lời.
Anthon
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.