Cara mencetak jalur pencarian ld (linker)

153

Apa cara mencetak jalur pencarian yang di lihat oleh ld dalam urutan pencariannya.

Talespin_Kit
sumber

Jawaban:

95

Anda dapat melakukan ini dengan menjalankan perintah berikut:

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

gcc melewati beberapa jalur -L tambahan ke tautan, yang dapat Anda daftarkan dengan perintah berikut:

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

Jawaban yang menyarankan untuk menggunakan ld.so.conf dan ldconfig tidak benar karena mereka merujuk ke jalur yang dicari oleh runtime dynamic linker (yaitu setiap kali suatu program dijalankan), yang tidak sama dengan jalur yang dicari oleh ld (yaitu kapan saja sebuah program terhubung).

salah
sumber
2
Anda mencapai sasaran. Saya memiliki masalah penautan, selama proses penautan, linker menemukan pustaka yang diinstal secara manual /usr/local/..yang menyebabkan kesalahan pustaka yang hilang, dan penautan gagal. Saya harus mengganti nama /usr/localsetiap kali untuk mengecualikan jalur pencarian itu. Apakah ada cara sederhana untuk mengecualikan atau mengganti /usr/localjalur?
kenn
1
Anda dapat mencoba menentukan jalur pustaka secara manual dengan opsi -L ke GCC, yang saya pikir (tidak yakin) akan menggantikan jalur pustaka sistem. Anda juga dapat mencoba mengatur variabel env LIBRARY_PATH sebelum mengkompilasi: $ LIBRARY_PATH = / somedir / gcc ...
dipalsukan
1
Saya tahu bahwa menghubungkan di kompilasi baris perintah. Saya bermaksud cara global untuk mengesampingkan ldjalur pencarian. Sebagai contoh kadang-kadang saya harus mengkompilasi kode sumber dari makefileatau menghasilkan makefile dari configureskrip atau dari CMakeLists.txtatau bahkan yang lebih rumit seperti valaatau srt. Sulit bagi saya untuk memodifikasi ldjalur pencarian dalam kasus seperti itu
kenn
Saat menggunakan CMake, Anda dapat memilih perpustakaan yang tepat yang digunakan selama fase konfigurasi (beberapa entri ini hanya ditampilkan dalam mode lanjutan). Sedangkan untuk mengkonfigurasi skrip dari Autotools, lihat jawaban ini: stackoverflow.com/questions/7561509/… . Ini tidak menjawab pertanyaan Anda secara langsung, tetapi dapat membantu Anda melakukan apa yang Anda inginkan.
dipalsukan
81

Pada Linux, Anda dapat menggunakan ldconfig, yang mempertahankan konfigurasi ld.so dan cache, untuk mencetak direktori pencarian dengan ld.sodengan

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

ldconfig -vmencetak pencarian direktori oleh linker (tanpa tab utama) dan perpustakaan bersama yang ditemukan di direktori tersebut (dengan tab terkemuka); yang grepmendapat direktori. Di mesin saya, baris ini dicetak

/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)

hwcapPath pertama, tanpa di baris, adalah built-in atau dibaca dari /etc/ld.so.conf. Linker kemudian dapat mencari direktori tambahan di bawah jalur pencarian perpustakaan dasar, dengan nama-nama seperti yang sse2sesuai dengan kemampuan CPU tambahan. Jalur ini, dengan hwcapsejalan, dapat berisi pustaka tambahan yang dirancang untuk kemampuan CPU ini.

Satu catatan terakhir: menggunakan -palih-alih -vmencari ld.socache sebagai gantinya.

telotortium
sumber
51
Dia bertanya tentang linker (ld) dan bukan loader (ld.so)!
fons
3
Bagaimana mungkin jika saya atur export LD_LIBRARY_PATH=/some/other/dir, itu tidak akan mempengaruhi output dari perintah ini ?! Sepertinya tidak berfungsi 100%?
TMS
3
@fons Lucunya adalah saya sampai di sini mencari jawaban ini. :) tautan waktu atau jalur waktu berjalan? Saya kira itu pertanyaannya. LIBRAY_PATH (waktu tautan) vs LD_LIBRARY_PATH.
Daniel Santos
2
Saya telah menemukan pada beberapa platform (mis. Lengan dengan Linaro toolchain) bahwa ldconfig sebenarnya tidak mencari direktori yang sama dengan run time linker. Anda dapat memperolehnya untuk mengeluarkan jalur pencariannya, dan menyertakan jalurnya LD_LIBRARY_PATHdengan mengaktifkan debugging. Misalnya LD_DEBUG=libs /lib/ld-linux.so --list cat(Anda dapat menggunakan executable apa pun, saya memilih catsebagai hal pertama yang dapat saya pikirkan). Mungkin layak untuk dipahami " search path". Perhatikan bahwa jika Anda memiliki /etc/ld.so.cacheyang cocok dengan semua lib yang diperlukan, Anda tidak akan bisa melihat jalur pencarian sistem bawaan, karena itu tidak akan sejauh itu.
John O'M.
Apakah gccjalur pencarian sama dengan ini?
nn0p
67

Saya tidak yakin bahwa ada opsi untuk hanya mencetak jalur pencarian efektif penuh.

Tetapi: jalur pencarian terdiri dari direktori yang ditentukan oleh -Lopsi pada baris perintah, diikuti oleh direktori yang ditambahkan ke jalur pencarian oleh SEARCH_DIR("...")arahan dalam skrip linker. Jadi Anda bisa menyelesaikannya jika Anda dapat melihat keduanya, yang dapat Anda lakukan sebagai berikut:

Jika Anda memohon ldlangsung:

  • The -Lopsi apa pun yang Anda katakan mereka.
  • Untuk melihat skrip tautan, tambahkan --verboseopsi. Cari SEARCH_DIR("...")arahan, biasanya di dekat bagian atas output. (Perhatikan bahwa ini tidak selalu sama untuk setiap permintaan ld- penghubung memiliki sejumlah skrip tautan bawaan bawaan yang berbeda, dan memilih di antara mereka berdasarkan pada berbagai opsi penghubung lainnya.)

Jika Anda menautkan melalui gcc:

  • Anda dapat meneruskan -vopsi gccsehingga menunjukkan kepada Anda bagaimana cara memanggil tautan. Bahkan, biasanya tidak meminta ldsecara langsung, tetapi secara tidak langsung melalui alat yang disebut collect2(yang hidup di salah satu direktori internal), yang pada gilirannya meminta ld. Itu akan menunjukkan kepada Anda -Lopsi apa yang sedang digunakan.
  • Anda dapat menambahkan -Wl,--verboseke gccopsi untuk membuatnya melewati --verboseke linker, untuk melihat skrip linker seperti dijelaskan di atas.
Matthew Slattery
sumber
5
Opsi --verbose untuk penghubung berhasil. Sangat membantu!
Ari
Saya berusaha keras untuk mencari tahu di mana tautannya cari dan tidak menemukan SEARCH_DIR dalam output. Ternyata ketika saya menggunakan -T scriptskrip saya sepenuhnya menggantikan skrip default ld dan hanya melihat di mana saya menunjuk.
thomasa88
29

Perintah paling kompatibel yang saya temukan untuk gcc dan dentang di Linux (terima kasih kepada armando.sano):

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

jika Anda memberi -m32, itu akan menampilkan direktori perpustakaan yang benar.

Contoh di mesin saya:

untuk 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

untuk 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
Raphaël Londeix
sumber
Terima kasih! peningkatan kecil - singkirkan satu atau dua grep: sed -n 's / SEARCH_DIR ("= \? ([^"] \ +) "); * / \ 1 \ n / gp'
Bruce K
2
Mengapa ini membutuhkan metode yang tidak jelas?
bmacnaughton
Ini bekerja seperti pesona! bagaimana kita menambahkan direktori pada daftar ini, jalur pencarian tautan?
pari
6

Pertanyaannya diberi tag Linux, tetapi mungkin ini juga berfungsi di Linux?

gcc -Xlinker -v

Di bawah Mac OS X, ini mencetak:

@(#)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/
[...]

The -Xlinkerpilihan gccdi atas hanya lewat -vuntuk ld. Namun:

ld -v

tidak mencetak jalur pencarian.

armando.sano
sumber
Di Linux ia mencetak direktori juga, tetapi dalam bentuk -Lpath. Jadi @ Raphaël Londeix jawabannya lebih baik.
pevik
2

Versi Mac: $ ld -v 2, tidak tahu cara mendapatkan jalur terperinci. keluaran

Library search paths:
    /usr/lib
    /usr/local/lib
Framework search paths:
    /Library/Frameworks/
    /System/Library/Frameworks/
yfeleke
sumber
3
Saya mendapatkan "tidak dapat membuka 2: tidak ada file atau direktori". Berlarild -v 2
Jack
2
Pertanyaannya ditandai Linux, bukan OS X. Saya tidak percaya OS X menggunakan GNU ld. Orang-orang Binutil menonaktifkannya di skrip build. Telah dinonaktifkan selama bertahun-tahun.
jww