So drucken Sie den ld-Suchpfad (Linker)

153

Wie werden die Suchpfade, die von ld gesucht wurden, in der Reihenfolge gedruckt, in der sie gesucht werden ?

Talespin_Kit
quelle

Antworten:

95

Sie können dies tun, indem Sie den folgenden Befehl ausführen:

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

gcc übergibt dem Linker einige zusätzliche -L-Pfade, die Sie mit dem folgenden Befehl auflisten können:

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

Die Antworten, die die Verwendung von ld.so.conf und ldconfig vorschlagen, sind nicht korrekt, da sie sich auf die Pfade beziehen, die vom dynamischen Laufzeitlinker durchsucht werden (dh wann immer ein Programm ausgeführt wird), was nicht mit dem von ld gesuchten Pfad (dh wann immer) identisch ist ein Programm ist verlinkt).

gefälscht
quelle
2
Du hast den Punkt getroffen. Ich habe ein Verknüpfungsproblem. Während des Verknüpfungsprozesses findet der Linker manuell installierte Bibliotheken, /usr/local/..die einen fehlenden Bibliotheksfehler verursachen, und die Verknüpfung schlägt fehl. Ich muss /usr/localjedes Mal umbenennen , um diesen Suchpfad auszuschließen. Gibt es eine einfache Möglichkeit, einen /usr/localPfad auszuschließen oder zu überschreiben ?
Kenn
1
Sie können versuchen, Bibliothekspfade manuell mit der Option -L zu GCC anzugeben, was meiner Meinung nach (nicht sicher) die Systembibliothekspfade überschreibt. Sie können auch versuchen, die LIBRARY_PATH-Umgebungsvariable vor dem Kompilieren festzulegen: $ LIBRARY_PATH = / somedir / gcc ...
gefälscht
1
Ich kenne das Verknüpfen beim Kompilieren von Kommandozeilen. Ich meinte einen globalen Weg, um den ldSuchpfad zu überschreiben . Zum Beispiel manchmal muß ich einen Quellcode kompiliert makefileaus oder Erzeugen Makefile - configureSkript oder aus CMakeLists.txtoder auch komplizierteren wie valaoder srt. ldIn solchen Fällen
fällt es
Bei Verwendung von CMake können Sie die genauen Bibliotheken auswählen, die während der Konfigurationsphase verwendet werden (einige dieser Einträge werden nur im erweiterten Modus angezeigt). Informationen zum Konfigurieren von Skripten aus Autotools finden Sie in dieser Antwort: stackoverflow.com/questions/7561509/… . Dies beantwortet Ihre Frage nicht direkt, kann Ihnen aber dabei helfen, das zu tun, was Sie wollen.
Gefälschte
81

Unter Linux können Sie verwenden ldconfig, die die ld.so Konfiguration und Cache hält, suchen die Verzeichnisse auszudrucken durch ld.somit

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

ldconfig -vdruckt die Verzeichnissuche durch den Linker (ohne führenden Tab) und die in diesen Verzeichnissen gefundenen gemeinsam genutzten Bibliotheken (mit einem führenden Tab) aus; das grepbekommt die Verzeichnisse. Auf meinem Computer wird diese Zeile ausgedruckt

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

Die ersten Pfade ohne hwcapin der Zeile sind entweder integriert oder werden aus /etc/ld.so.conf gelesen. Der Linker kann dann zusätzliche Verzeichnisse unter dem Suchpfad der Basisbibliothek durchsuchen, deren Namen sse2zusätzlichen CPU-Funktionen entsprechen. Diese Pfade hwcapin der Zeile können zusätzliche Bibliotheken enthalten, die auf diese CPU-Funktionen zugeschnitten sind.

Ein letzter Hinweis: Verwenden von -panstelle von -voben durchsucht ld.sostattdessen den Cache.

Telotortium
quelle
50
Er fragt nach dem Linker (ld) und nicht nach dem Lader (ld.so)!
fons
3
Wie ist es möglich, dass die Einstellung export LD_LIBRARY_PATH=/some/other/dirdieses Befehls nicht beeinflusst wird , wenn ich sie einstelle?! Scheint es nicht 100% zu funktionieren?
TMS
3
@fons Lustig ist, dass ich hier nach dieser Antwort gesucht habe. :) Link- oder Laufzeitpfad? Ich denke das ist die Frage. LIBRAY_PATH (Verbindungszeit) vs LD_LIBRARY_PATH.
Daniel Santos
2
Ich habe auf einigen Plattformen (z. B. Arm mit Linaro-Toolchain) festgestellt, dass ldconfig nicht dieselben Verzeichnisse wie der Laufzeit-Linker durchsucht. Sie können ihn dazu bringen, seinen Suchpfad auszugeben und die Pfade von einzuschließen, LD_LIBRARY_PATHindem Sie das Debuggen aktivieren. ZB LD_DEBUG=libs /lib/ld-linux.so --list cat(Sie können jede ausführbare Datei verwenden, die ich catals erstes ausgewählt habe). Könnte es wert sein, nach " search path" zu greifen . Beachten Sie, /etc/ld.so.cachedass Sie den integrierten System-Suchpfad nicht sehen können , wenn Sie eine haben , die allen benötigten Bibliotheken entspricht, da diese nicht so weit kommt.
John O'M.
Ist der gccSuchpfad bei diesen gleich?
nn0p
67

Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, einfach den vollständigen effektiven Suchpfad zu drucken.

Aber: Der Suchpfad besteht aus Verzeichnissen, die durch -LOptionen in der Befehlszeile angegeben werden, gefolgt von Verzeichnissen, die dem Suchpfad durch SEARCH_DIR("...")Anweisungen in den Linkerskripten hinzugefügt werden . Sie können es also herausfinden, wenn Sie beide sehen, was Sie wie folgt tun können:

Wenn Sie lddirekt aufrufen :

  • Die -LOptionen sind alles, was Sie gesagt haben.
  • Fügen Sie die --verboseOption hinzu, um das Linker-Skript anzuzeigen. Suchen Sie nach den SEARCH_DIR("...")Anweisungen, normalerweise oben in der Ausgabe. (Beachten Sie, dass diese nicht unbedingt für jeden Aufruf von gleich sind ld- der Linker verfügt über eine Reihe verschiedener integrierter Standard-Linker-Skripte und wählt basierend auf verschiedenen anderen Linker-Optionen zwischen diesen aus.)

Wenn Sie über Folgendes verlinken gcc:

  • Sie können die -vOption an übergeben, gccdamit sie Ihnen zeigt, wie der Linker aufgerufen wird. Tatsächlich wird es normalerweise nicht lddirekt, sondern indirekt über ein Tool namens collect2(das sich in einem seiner internen Verzeichnisse befindet) aufgerufen , das wiederum aufruft ld. Das zeigt Ihnen, welche -LOptionen verwendet werden.
  • Sie können -Wl,--verbosedie gccOptionen hinzufügen , damit sie --verbosean den Linker weitergeleitet werden, um das Linkerskript wie oben beschrieben anzuzeigen.
Matthew Slattery
quelle
5
Die Option --verbose für den Linker hat es geschafft. Sehr hilfreich!
Ari
Ich habe mich sehr bemüht herauszufinden, wo der Linker sucht, und SEARCH_DIR in der Ausgabe nicht gefunden. Es stellte sich heraus, dass ich mit -T scriptmeinem Skript das Standard-Skript von ld vollständig ersetzt und nur dort gesucht habe, wo ich darauf hingewiesen habe.
Thomasa88
29

Der kompatibelste Befehl, den ich für gcc und clang unter Linux gefunden habe (dank armando.sano):

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

Wenn Sie angeben -m32, werden die richtigen Bibliotheksverzeichnisse ausgegeben.

Beispiele auf meiner Maschine:

für 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

für 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
quelle
Danke dir! Teeny-Verbesserung - ein oder zwei Grep loswerden: sed -n 's / SEARCH_DIR ("= \? ([^"] \ +) "); * / \ 1 \ n / gp'
Bruce K
2
Warum erfordert dies eine so dunkle Methode?
Bmacnaughton
Das hat wie ein Zauber gewirkt! Wie fügen wir die Verzeichnisse in dieser Liste hinzu, Linker-Suchpfad?
Pari
6

Die Frage lautet Linux, aber vielleicht funktioniert das auch unter Linux?

gcc -Xlinker -v

Unter Mac OS X wird Folgendes gedruckt:

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

Die -XlinkerOption von gccoben geht nur -vauf über ld. Jedoch:

ld -v

druckt den Suchpfad nicht aus.

armando.sano
quelle
Unter Linux werden auch Verzeichnisse gedruckt, jedoch in Form von -Lpath. Also @ Raphaël Londeix Antwort ist besser.
Pevik
2

Mac-Version: $ ld -v 2, weiß nicht, wie man detaillierte Pfade erhält. Ausgabe

Library search paths:
    /usr/lib
    /usr/local/lib
Framework search paths:
    /Library/Frameworks/
    /System/Library/Frameworks/
yfeleke
quelle
3
Ich bekomme "kann nicht öffnen 2: keine solche Datei oder Verzeichnis". Laufenld -v 2
Jack
2
Die Frage lautet Linux, nicht OS X. Ich glaube nicht, dass OS X GNUs verwendet ld. Die Binutil-Leute haben es in den Build-Skripten deaktiviert. Es ist seit Jahren deaktiviert.
JWW