Cách in đường dẫn tìm kiếm ld (linker)


153

Cách in các đường dẫn tìm kiếm mà ld tìm kiếm theo thứ tự nó tìm kiếm là gì.

Câu trả lời:


95

Bạn có thể làm điều này bằng cách thực hiện lệnh sau:

ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012

gcc chuyển một vài đường dẫn -L bổ sung cho trình liên kết mà bạn có thể liệt kê bằng lệnh sau:

gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,;  ,g' | tr \; \\012

Các câu trả lời gợi ý sử dụng ld.so.conf và ldconfig là không chính xác vì chúng đề cập đến các đường dẫn được tìm kiếm bởi trình liên kết động thời gian chạy (nghĩa là bất cứ khi nào một chương trình được thực thi), không giống với đường dẫn được tìm kiếm bởi ld (tức là bất cứ khi nào một chương trình được liên kết).


2
Bạn đánh tại chỗ. Tôi có một vấn đề liên kết, trong quá trình liên kết quá trình liên kết tìm thấy các thư viện được cài đặt thủ công trong /usr/local/..đó gây ra lỗi thư viện bị thiếu và liên kết không thành công. Tôi phải đổi tên /usr/localmọi lúc để loại trừ đường dẫn tìm kiếm đó. Có một cách đơn giản để loại trừ hoặc ghi đè /usr/localđường dẫn?
kenn

1
Bạn có thể thử chỉ định thủ công các đường dẫn thư viện với tùy chọn -L cho GCC, mà tôi nghĩ (không chắc chắn) sẽ ghi đè các đường dẫn thư viện hệ thống. Bạn cũng có thể thử đặt biến LIBRARY_PATH env trước khi biên dịch: $ LIBRARY_PATH = / somedir / gcc ...
faken

1
Tôi biết rằng liên kết trong biên dịch dòng lệnh. Tôi có nghĩa là một cách toàn cầu để ghi đè ldđường dẫn tìm kiếm. Ví dụ, đôi khi tôi phải biên dịch mã nguồn từ makefilehoặc tạo tệp tạo tệp từ configuretập lệnh hoặc từ CMakeLists.txthoặc thậm chí phức tạp hơn như valahoặc srt. Thật khó cho tôi để sửa đổi ldđường dẫn tìm kiếm trong những trường hợp như vậy
kenn

Khi sử dụng CMake, bạn có thể chọn các thư viện chính xác được sử dụng trong giai đoạn cấu hình (một số mục này chỉ được hiển thị ở chế độ nâng cao). Đối với cấu hình tập lệnh từ Autotools, hãy xem câu trả lời sau: stackoverflow.com/questions/7561509/ mẹo . Điều này không trả lời trực tiếp câu hỏi của bạn, nhưng có thể giúp bạn làm những gì bạn muốn.
faken

81

Trên Linux, bạn có thể sử dụng ldconfig, trong đó duy trì cấu hình ld.so và bộ nhớ cache, để in ra các thư mục tìm kiếm theo ld.sovới

ldconfig -v 2>/dev/null | grep -v ^$'\t'

ldconfig -vin ra các tìm kiếm thư mục bởi trình liên kết (không có tab hàng đầu) và các thư viện chia sẻ được tìm thấy trong các thư mục đó (với một tab hàng đầu); các grepthư mục được. Trên máy của tôi, dòng này in ra

/usr/lib64/atlas:
/usr/lib/llvm:
/usr/lib64/llvm:
/usr/lib64/mysql:
/usr/lib64/nvidia:
/usr/lib64/tracker-0.12:
/usr/lib/wine:
/usr/lib64/wine:
/usr/lib64/xulrunner-2:
/lib:
/lib64:
/usr/lib:
/usr/lib64:
/usr/lib64/nvidia/tls: (hwcap: 0x8000000000000000)
/lib/i686: (hwcap: 0x0008000000000000)
/lib64/tls: (hwcap: 0x8000000000000000)
/usr/lib/sse2: (hwcap: 0x0000000004000000)
/usr/lib64/tls: (hwcap: 0x8000000000000000)
/usr/lib64/sse2: (hwcap: 0x0000000004000000)

Các đường dẫn đầu tiên, không có hwcaptrong dòng, được tích hợp hoặc đọc từ /etc/ld.so.conf. Trình liên kết sau đó có thể tìm kiếm các thư mục bổ sung theo đường dẫn tìm kiếm thư viện cơ bản, với các tên như sse2tương ứng với các khả năng bổ sung của CPU. Các đường dẫn này, với hwcapdòng, có thể chứa các thư viện bổ sung được tùy chỉnh cho các khả năng của CPU này.

Một lưu ý cuối cùng: sử dụng -pthay vì -vở trên tìm kiếm ld.sobộ đệm thay thế.


51
Anh ta đang hỏi về trình liên kết (ld) chứ không phải trình tải (ld.so)!
Fons

3
Làm thế nào có thể nếu tôi đặt export LD_LIBRARY_PATH=/some/other/dir, nó sẽ không ảnh hưởng đến đầu ra của lệnh này?! Có vẻ như nó không hoạt động 100%?
TMS

3
@fons Funnything là tôi đã ở đây để tìm câu trả lời này. :) đường dẫn thời gian liên kết hoặc thời gian chạy? Tôi đoán đó là câu hỏi. LIBRAY_PATH (thời gian liên kết) so với LD_LIBRARY_PATH.
Daniel Santos

2
Tôi đã tìm thấy trên một số nền tảng (ví dụ: nhánh với Linaro toolchain) rằng ldconfig không thực sự tìm kiếm các thư mục giống như trình liên kết thời gian chạy. Bạn có thể lấy nó để xuất đường dẫn tìm kiếm của nó và bao gồm các đường dẫn từ LD_LIBRARY_PATHbằng cách bật gỡ lỗi. Ví dụ LD_DEBUG=libs /lib/ld-linux.so --list cat(bạn có thể sử dụng bất kỳ thực thi nào, tôi đã chọn catlà điều đầu tiên tôi có thể nghĩ đến). Có thể đáng để grepping cho " search path". Lưu ý rằng nếu bạn có một /etc/ld.so.cachephù hợp với tất cả các lib cần thiết, bạn sẽ không thấy đường dẫn tìm kiếm hệ thống tích hợp, bởi vì nó sẽ không đi xa đến thế.
John O'M.

gccđường dẫn tìm kiếm giống với những cái này?
nn0p

67

Tôi không chắc chắn rằng có bất kỳ tùy chọn nào chỉ đơn giản là in đường dẫn tìm kiếm hiệu quả đầy đủ.

Nhưng: đường dẫn tìm kiếm bao gồm các thư mục được chỉ định bởi -Lcác tùy chọn trên dòng lệnh, theo sau là các thư mục được thêm vào đường dẫn tìm kiếm bằng SEARCH_DIR("...")các lệnh trong tập lệnh liên kết. Vì vậy, bạn có thể giải quyết nếu bạn có thể thấy cả hai thứ mà bạn có thể làm như sau:

Nếu bạn đang gọi ldtrực tiếp:

  • Các -Ltùy chọn là bất cứ điều gì bạn đã nói.
  • Để xem tập lệnh liên kết, thêm --verbosetùy chọn. Tìm kiếm các SEARCH_DIR("...")chỉ thị, thường là gần đầu ra. (Lưu ý rằng những điều này không nhất thiết giống nhau cho mỗi lần gọi ld- trình liên kết có một số tập lệnh liên kết mặc định tích hợp khác nhau và chọn giữa chúng dựa trên các tùy chọn liên kết khác nhau.)

Nếu bạn đang liên kết qua gcc:

  • Bạn có thể chuyển -vtùy chọn để gccnó chỉ cho bạn cách nó gọi trình liên kết. Trong thực tế, nó thường không gọi ldtrực tiếp, mà gián tiếp thông qua một công cụ được gọi là collect2(sống trong một trong các thư mục nội bộ của nó), lần lượt gọi ra ld. Điều đó sẽ cho bạn thấy những -Ltùy chọn đang được sử dụng.
  • Bạn có thể thêm -Wl,--verbosevào các gcctùy chọn để chuyển --verbosequa trình liên kết, để xem tập lệnh liên kết như được mô tả ở trên.

5
Tùy chọn --verbose cho trình liên kết đã thực hiện thủ thuật. Rất hữu ích!
Ari

Tôi đã cố gắng hết sức để tìm ra nơi trình liên kết đang tìm kiếm và không tìm thấy SEARCH_DIR trong đầu ra. Hóa ra khi tôi đang sử dụng -T scripttập lệnh của mình đã thay thế hoàn toàn tập lệnh mặc định của ld và chỉ nhìn vào nơi tôi đã chỉ.
thomasa88

29

Lệnh tương thích nhất mà tôi đã tìm thấy cho gcc và clang trên Linux (nhờ armando.sano):

$ gcc -m64 -Xlinker --verbose  2>/dev/null | grep SEARCH | sed 's/SEARCH_DIR("=\?\([^"]\+\)"); */\1\n/g'  | grep -vE '^$'

nếu bạn cho -m32, nó sẽ xuất ra các thư mục thư viện chính xác.

Ví dụ trên máy của tôi:

cho g++ -m64:

/usr/x86_64-linux-gnu/lib64
/usr/i686-linux-gnu/lib64
/usr/local/lib/x86_64-linux-gnu
/usr/local/lib64
/lib/x86_64-linux-gnu
/lib64
/usr/lib/x86_64-linux-gnu
/usr/lib64
/usr/local/lib
/lib
/usr/lib

cho g++ -m32:

/usr/i686-linux-gnu/lib32
/usr/local/lib32
/lib32
/usr/lib32
/usr/local/lib/i386-linux-gnu
/usr/local/lib
/lib/i386-linux-gnu
/lib
/usr/lib/i386-linux-gnu
/usr/lib

Cảm ơn bạn! tăng cường tuổi teen - thoát khỏi một hoặc hai grep: sed -n 's / SEARCH_DIR ("= \? ([^"] \ +) "); * / \ 1 \ n / gp'
Bruce K

2
Tại sao điều này đòi hỏi một phương pháp tối nghĩa như vậy?
bmacnaughton

Điều này làm việc như một nét duyên dáng! Làm thế nào để chúng ta thêm các thư mục trong danh sách này, đường dẫn tìm kiếm liên kết?
pari

6

Câu hỏi được gắn thẻ Linux, nhưng có lẽ điều này cũng hoạt động tốt với Linux?

gcc -Xlinker -v

Trong Mac OS X, bản in này:

@(#)PROGRAM:ld  PROJECT:ld64-224.1
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 armv6m armv7m armv7em
Library search paths:
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib
Framework search paths:
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/
[...]

Các -Xlinkertùy chọn gccở trên chỉ cần chuyển -vđến ld. Tuy nhiên:

ld -v

không in đường dẫn tìm kiếm.


Trên Linux, nó cũng in các thư mục, nhưng ở dạng -Lpath. Vì vậy, câu trả lời @ Raphaël Londeix là tốt hơn.
pevik

2

Phiên bản Mac: $ ld -v 2, không biết cách lấy đường dẫn chi tiết. đầu ra

Library search paths:
    /usr/lib
    /usr/local/lib
Framework search paths:
    /Library/Frameworks/
    /System/Library/Frameworks/

3
Tôi nhận được "không thể mở 2: không có tập tin hoặc thư mục như vậy". Chạyld -v 2
Jack

2
Câu hỏi được gắn thẻ Linux, không phải OS X. Tôi không tin OS X sử dụng GNU ld. Những người Binutil đã vô hiệu hóa nó trong các tập lệnh xây dựng. Nó đã bị vô hiệu hóa trong nhiều năm.
jww
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.