Wo suchen ausführbare Dateien zur Laufzeit nach gemeinsam genutzten Objekten?

102

Ich verstehe, wie man gemeinsame Objekte beim Verknüpfen / Kompilieren definiert. Ich frage mich jedoch immer noch, wie ausführbare Dateien zur *.soAusführungszeit nach dem freigegebenen Objekt (den Bibliotheken) aussehen .

Zum Beispiel a.outruft meine App Funktionen auf, die in der lib.soBibliothek definiert sind . Nach dem Kompilieren gehe ich lib.soin ein neues Verzeichnis in meinem $HOME.

Wie kann ich sagen a.out, dass ich dort danach suchen soll?

rahmu
quelle

Antworten:

102

In der HOWTO der Shared Library werden die meisten Mechanismen erläutert, und das Handbuch zum dynamischen Laden wird ausführlicher beschrieben. Jede Unix-Variante hat ihren eigenen Weg, aber die meisten verwenden dasselbe ausführbare Format ( ELF ) und haben ähnliche dynamische Linker (von Solaris abgeleitet). Im Folgenden fasse ich das allgemeine Verhalten mit einem Schwerpunkt auf Linux zusammen. In den Handbüchern Ihres Systems finden Sie die vollständige Story.

Kurz gesagt, wenn nach einer dynamischen Bibliothek ( .soDatei) gesucht wird, versucht der Linker Folgendes:

  • Verzeichnisse, die in der LD_LIBRARY_PATHUmgebungsvariablen aufgelistet sind ( DYLD_LIBRARY_PATHunter OSX);
  • Verzeichnisse, die im Pfad der ausführbaren Datei aufgeführt sind ;
  • Verzeichnisse im Systemsuchpfad, der (mindestens unter Linux) aus den Einträgen in /etc/ld.so.confplus /libund besteht /usr/lib.

Der Pfad wird in der ausführbaren Datei gespeichert (es ist das DT_RPATHoder DT_RUNPATHdynamische Attribut). Es kann absolute Pfade oder Pfade enthalten, die mit $ORIGINeinem Pfad relativ zum Speicherort der ausführbaren Datei beginnen (z. B. wenn sich die ausführbare Datei in /opt/myapp/binund ihr Pfad in befindet, sucht $ORIGIN/../lib:$ORIGIN/../pluginsder dynamische Linker in /opt/myapp/libund /opt/myapp/plugins). Der Pfad wird normalerweise festgelegt, wenn die ausführbare Datei kompiliert wird, mit der -rpathOption to ld, aber Sie können ihn anschließend mit ändern chrpath.

Im Szenario beschreiben Sie, wenn Sie sich an den Entwickler oder Verpacker der Anwendung sind und beabsichtigen , sie in einem installiert werden …/bin, …/libStruktur, dann verbinden mit -rpath='$ORIGIN/../lib'. Wenn Sie eine vorgefertigte Binärdatei auf Ihrem System installieren, legen Sie die Bibliothek entweder in einem Verzeichnis im Suchpfad ab ( /usr/local/libwenn Sie der Systemadministrator sind, andernfalls in einem Verzeichnis, das Sie hinzufügen $LD_LIBRARY_PATH), oder versuchen Sie es chrpath.

Gilles
quelle
3
Auf einigen Systemen werden /lib64und /usr/lib64für 64-Bit-Binärdateien und /libund /usr/libfür 32-Bit-Binärdateien verwendet.
Mark Lakata
Warum spricht diese richtige Antwort nicht über ldconfig ?
Liebt Wahrscheinlichkeit
1
@ LovesProbability Da es sich um die Frage handelte, wo ausführbare Dateien nach Bibliotheken suchen, ist dies nicht erforderlich ldconfig. ldconfigwird eingebunden, wenn Sie eine Bibliothek installieren.
Gilles
1
Beachten Sie, dass der "System-Suchpfad" für *.soBibliotheken nicht identisch ist mit $PATH. Der Suchpfad wird von @enzotib in der Antwort angegeben. Führen Sie den folgenden Befehl aus, um die zu durchsuchenden Pfade auszudrucken ldconfig -v 2>/dev/null | grep -v ^$'\t'.
Andrew Bate
Für mich, um ldconfig auszuführen, brauchte ich /sbin/ldconfigund die andere Magie von Andrew Bate, damit es ohne Rootberechtigung ausgeführt wird
Robert Lugg,
16

Unter Linux wird das Verhalten in der ld(1)Manpage erläutert

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.
Enzotib
quelle
1
"Die Standardverzeichnisse, normalerweise / lib und / usr / lib." -> wie kann ich herausfinden, ob mein system normal ist?
Thorsten Staerk
2
Die Frage ist über die Laufzeit und nicht die Verbindungszeit
Talespin_Kit
2

Ich bin mir ziemlich sicher, dass die Antwort hier ist ldconfig.

ldconfig erstellt die erforderlichen Links und den Cache zu den neuesten gemeinsam genutzten Bibliotheken, die sich in den in der Befehlszeile angegebenen Verzeichnissen, in der Datei /etc/ld.so.conf und in den vertrauenswürdigen Verzeichnissen (/ lib und / usr / lib) befinden. Der Cache wird vom Laufzeit-Linker ld.so oder ld-linux.so verwendet. ldconfig überprüft den Header und die Dateinamen der Bibliotheken, auf die es stößt, um festzustellen, bei welchen Versionen die Links aktualisiert werden sollen.

http://linux.die.net/man/8/ldconfig

Sean C.
quelle
0

Für laufende Anwendungen /proc/1234/mapsenthält die Datei alle aktuell dynamisch verknüpften Bibliotheken.

Wo 1234ist die pid der laufenden ausführbaren Datei.

Linux folgt LD_LIBRARY_PATH und anderen Variablen, wie in der Antwort von Gilles ausgeführt.

user138692
quelle
4
Schön, dass Sie in Ihrem zweiten Satz bestätigen, dass Gilles Antwort hilft. Der erste Teil trägt jedoch überhaupt nicht dazu bei, zu erklären, wie man erkennt, wo sich die Dateien befinden, sondern nur, woher sie stammen, wenn sie bereits gefunden wurden. Alles in allem sollte dies nur ein Kommentar sein, keine Antwort.
Anthon