Как напечатать путь поиска ld (linker)

154

Как распечатать пути поиска, которые просматривал ld в порядке поиска.

Talespin_Kit
источник

Ответы:

96

Вы можете сделать это, выполнив следующую команду:

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

gcc передает компоновщику несколько дополнительных путей -L, которые вы можете перечислить с помощью следующей команды:

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

Ответы, предлагающие использовать ld.so.conf и ldconfig, не являются правильными, потому что они ссылаются на пути, которые ищет динамический компоновщик времени выполнения (т. Е. Всякий раз, когда выполняется программа), который не совпадает с путем, ищущим ld (т. Е. Всякий раз, когда программа связана).

faken
источник
2
Вы попали в точку. У меня проблема с линковкой, во время компоновки компоновщик процесса находит библиотеки, установленные вручную, в результате /usr/local/..чего отсутствует ошибка библиотеки, и при линковке происходит сбой. Я должен переименовывать /usr/localкаждый раз, чтобы исключить этот путь поиска. Есть ли простой способ исключить или переопределить /usr/localпуть?
Кенн
1
Вы можете попытаться вручную указать пути к библиотекам с параметром -L для GCC, который, я думаю (не уверен), переопределит пути к системным библиотекам. Вы также можете попытаться установить переменную LIBRARY_PATH env перед компиляцией: $ LIBRARY_PATH = / somedir / gcc ...
faken
1
Я знаю, что ссылки в компиляции командной строки. Я имел в виду глобальный способ переопределения ldпути поиска. Например, иногда мне приходится компилировать исходный код из makefileили генерировать make-файл из configureскрипта или из CMakeLists.txtили даже более сложных, таких как valaили srt. В ldтаких случаях мне сложно изменить путь поиска
Kenn
При использовании CMake вы можете выбрать точные библиотеки, которые используются на этапе настройки (некоторые из этих записей отображаются только в расширенном режиме). Что касается сценариев настройки из Autotools, см. Следующий ответ: stackoverflow.com/questions/7561509/… . Это не отвечает на ваш вопрос напрямую, но может помочь вам сделать то, что вы хотите.
сфотографировано
83

В 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кеше.

telotortium
источник
52
Он спрашивает о компоновщике (ld), а не о загрузчике (ld.so)!
фоны
3
Как это возможно, что если я установлю export LD_LIBRARY_PATH=/some/other/dir, это не повлияет на вывод этой команды ?! Кажется, это не работает на 100%?
TMS
3
@fons Забавно, что я пришел сюда в поисках этого ответа. :) время соединения или время выполнения? Я думаю, это вопрос. 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
Raphaël Londeix
источник
Спасибо! Небольшое улучшение - избавьтесь от одного или двух grep: 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

не печатает путь поиска.

armando.sano
источник
В Linux он также печатает каталоги, но в виде -Lpath. Так что @ Raphaël Londeix ответ лучше.
Певик
2

Версия для Mac: $ ld -v 2, не знаю, как получить подробные пути. вывод

Library search paths:
    /usr/lib
    /usr/local/lib
Framework search paths:
    /Library/Frameworks/
    /System/Library/Frameworks/
yfeleke
источник
3
Я получаю «не могу открыть 2: нет такого файла или каталога». Бегld -v 2
Джек,
2
Вопрос помечен Linux, а не OS X. Я не верю, что OS X использует GNU ld. Люди Binutil отключили его в сценариях сборки. Это было отключено в течение многих лет.
17