Як надрукувати шлях пошуку ld (linker)


153

Який спосіб друкувати шляхи пошуку, які переглянули ld у порядку пошуку.

Відповіді:


96

Це можна зробити, виконавши таку команду:

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

gcc проходить кілька додаткових шляхів до лінкера, який ви можете перелічити за допомогою наступної команди:

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

Відповіді, які пропонують використовувати ld.so.conf та ldconfig, не є правильними, оскільки вони посилаються на шляхи, що шукаються динамічним лінкером виконання (тобто щоразу, коли виконується програма), який не є таким, як шлях, який шукав ld (тобто коли програма пов'язана).


2
Ви потрапили на місце. У мене проблема з зв’язуванням, під час зв’язування процес лінкер знаходить встановлені вручну бібліотеки, в /usr/local/..яких виникає відсутня помилка бібліотеки, а посилання не вдається. Мені потрібно /usr/localкожного разу перейменовувати, щоб виключити цей шлях пошуку. Чи існує простий спосіб виключити або переосмислити /usr/localшлях?
kenn

1
Ви можете спробувати вручну вказати шляхи до бібліотеки за допомогою параметра -L до GCC, що, на мою думку (не впевнений), перекриє шлях до системної бібліотеки. Ви також можете спробувати встановити змінну LIBRARY_PATH env перед компілюванням: $ LIBRARY_PATH = / somedir / gcc ...
підроблено

1
Я знаю, що посилання в компіляції командного рядка. Я мав на увазі глобальний спосіб перекрити ldшлях пошуку. Наприклад, іноді мені доводиться компілювати вихідний код із makefileабо створювати makefile з configureскрипту або з, CMakeLists.txtабо навіть більш складних, таких як valaабо srt. Мені важко змінити ldшлях пошуку в таких випадках
kenn

Під час використання CMake ви можете вибрати точні бібліотеки, які використовуються під час фази конфігурації (деякі з цих записів відображаються лише в розширеному режимі). Що стосується налаштування сценаріїв з Autotools, дивіться цю відповідь: stackoverflow.com/questions/7561509/… . Це не відповідає безпосередньо на ваше запитання, але може допомогти вам зробити те, що ви хочете.
фальшиво

82

В Linux ви можете використовувати ldconfig, що підтримує конфігурацію ld.so та кеш, для друку пошуку каталогів за ld.soдопомогою

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

ldconfig -vдрукує пошук каталогів за допомогою лінкера (без провідної вкладки) та спільних бібліотек, знайдених у цих каталогах (із провідною вкладкою); grepотримує каталоги. На моїй машині ця лінія роздруковується

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

Перші шляхи, без hwcapрядка, або вбудовані, або прочитані з /etc/ld.so.conf. Потім лінкер може шукати додаткові каталоги під основним шляхом пошуку бібліотеки з іменами, такими як sse2відповідні додаткові можливості ЦП. Ці шляхи, hwcapв рядку, можуть містити додаткові бібліотеки, підібрані під ці можливості ЦП.

Останнє зауваження: -pзамість -vвищезазначеного використовується пошук ld.soкешу.


51
Він запитує про лінкер (ld), а не про навантажувач (ld.so)!
fons

3
Як можливо, що якщо я встановив export LD_LIBRARY_PATH=/some/other/dir, це не вплине на вихід цієї команди ?! Здається, це не працює на 100%?
TMS

3
@fons Funnything - це те, що я сюди шукав цю відповідь. :) Час посилання або час виконання? Я думаю, це питання. LIBRAY_PATH (час зв’язку) проти LD_LIBRARY_PATH.
Даніель Сантос

2
Я виявив, що на деяких платформах (наприклад, рука з ланцюжком інструментів Linaro) ldconfig насправді не шукає тих самих каталогів, що і лінкер часу запуску. Ви можете змусити його виводити його шлях пошуку та включати шляхи LD_LIBRARY_PATH, увімкнувши налагодження. Наприклад LD_DEBUG=libs /lib/ld-linux.so --list cat(ви можете використовувати будь-який виконуваний файл, який я вибрав catяк перше, що я міг придумати). Можливо, варто привітатись за " search path". Зауважте, що якщо у вас є /etc/ld.so.cacheвідповідність усім потрібним вкладкам, ви не побачите вбудований шлях пошуку системи, оскільки він не зайде так далеко.
Джон О'М.

Чи gccоднаковий шлях пошуку з цими?
nn0p

68

Я не впевнений, що є якийсь варіант просто надрукувати повний ефективний шлях пошуку.

Але: шлях пошуку складається з каталогів, визначених -Lпараметрами в командному рядку, а потім каталогів, доданих до шляху пошуку SEARCH_DIR("...")директивами в скриптах (іх) посилання. Таким чином, ви можете розробити це, якщо зможете побачити те, що ви можете зробити так:

Якщо ви звертаєтесь ldбезпосередньо:

  • Ці -Lваріанти , що ви сказали вони.
  • Щоб побачити сценарій посилання, додайте --verboseпараметр. Шукайте SEARCH_DIR("...")директиви, як правило, у верхній частині висновку. (Зауважте, що вони необов'язково однакові для кожного виклику ld- у лінкера є кілька різних вбудованих сценаріїв посилання за замовчуванням, і він вибирається між ними, грунтуючись на різних інших параметрах лінкера.)

Якщо ви зв’язуєтесь через gcc:

  • Ви можете передати -vпараметр gccтак, щоб він показав, як він викликає посилання. Насправді він, як правило, не звертається ldбезпосередньо, а опосередковано за допомогою інструменту, який називається collect2(який знаходиться в одному з його внутрішніх каталогів), який, у свою чергу, посилається ld. Це покаже вам, які -Lваріанти використовуються.
  • Ви можете додати -Wl,--verboseдо gccпараметрів, щоб перейти --verboseдо лінкера, щоб побачити сценарій посилання, як описано вище.

5
Варіант --verbose для лінкера зробив свою справу. Дуже корисний!
Арі

Я дуже намагався зрозуміти, де шукає лінкер, і не знайшов SEARCH_DIR у висновку. Виявляється, коли я використовував -T scriptсвій скрипт, повністю замінив скрипт за замовчуванням ld і дивився лише там, де я вказував.
thomasa88

30

Найбільш сумісна команда, яку я знайшов для gcc та clang в Linux (завдяки armando.sano):

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

якщо ви дасте -m32, він виведе правильні каталоги бібліотеки.

Приклади на моїй машині:

для 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

для 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

Дякую! підлітковий підсилення - позбудься від греп-двох: sed -n 's / SEARCH_DIR ("= \? ([^"] \ +) "); * / \ 1 \ n / gp'
Брюс К

2
Чому для цього потрібен такий незрозумілий метод?
bmacnaughton

Це спрацювало як шарм! як ми додаємо каталоги до цього списку, шлях пошуку лінкера?
pari

6

Питання позначене Linux, але, можливо, це працює добре під Linux?

gcc -Xlinker -v

У Mac OS X цей друкується:

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

-XlinkerВаріант gccвище просто переходить -vдо ld. Однак:

ld -v

не друкує шлях пошуку.


У Linux він також друкує каталоги, але у формі -Lpath. Тож відповідь @ Raphaël Londeix краща.
pevik

2

Версія для Mac: $ ld -v 2, не знаю, як отримати детальні шляхи. вихід

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

3
Я отримую "не можу відкрити 2: немає такого файлу чи каталогу". Бігld -v 2
Джек

2
Питання позначене Linux, а не OS X. Я не вірю, що OS X використовує GNU ld. Люди Binutil відключили його в сценаріях збирання. Його роками відключили.
jww
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.