Das Verständnis, wie die dynamische Verknüpfung funktioniert auf UNIX
Betrachten wir die folgende situation:
- ein Programm mit dem Namen
program
welcher von dynamisch auflibfoo.so
libfoo.so
das hängt davon ab, nichts (gut, es hängt davon ablibstdc++
und so, aber ich denke, wir können weglassen, die)
program
läuft perfekt.
Plötzlich libfoo
codes ändert, und eine Funktion verwendet jetzt intern func_bar()
eine Funktion, die von einer anderen Bibliothek libbar.so
.
libfoo.so
ist neu kompiliert und jetzt hängt libbar.so
. program
bleibt unverändert, es hängt immer noch nur auf libfoo.so
.
Wenn ich jetzt ausführen program
es beklagt, dass er nicht finden können func_bar()
.
Hier sind meine Fragen:
libfoo.so
Schnittstelle nicht ändern, nur deren Umsetzung. Warumprogram
müssen ausdrücklich link mitlibbar.so
?- Ist nicht die Abhängigkeit, Baum-rekursiv ? Ich würde denken, dass da
libfoo.so
hängtlibbar.so
,libbar.so
würde wurden automatisch Hinzugefügt, um die Abhängigkeit Liste derprogram
, ohne Neukompilierung. Allerdingsldd program
zeigt, dass es nicht der Fall ist.
Scheint es seltsam, dass man neu kompilieren ("erneut verknüpfen") jeder binäre das hängt davon ab, einige Bibliothek-everytime, die Bibliothek, die Abhängigkeiten ändern. Welche Lösungen habe ich hier um dies zu verhindern ?
- Kannst du eine minimale Konfiguration, die das problem reproduziert? vitaut ' s Kommentare nach seinem post scheinen zu beschreiben, den gleichen Prozess und kommt nicht an das gleiche problem. Vielleicht, wenn Sie einfache Schritte, dass wir helfen konnten mit der Beantwortung der Frage?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem entsteht, wenn Sie nicht mit
libfoo.so
gegenlibbar
. Wenn Sie kompilieren eine ausführbare Datei, die standardmäßig den linker wird dich nicht verlassen Undefinierte Referenzen. Jedoch, wenn Sie kompilieren eine gemeinsame Bibliothek, die es wird - und er wird erwarten, dass Sie zufrieden sein werden zur link-Zeit. Dies ist so, dasslibfoo
Funktionen können exportiertprogram
selbst - wenn Sie versuchen, Sie auszuführen, der dynamische linker wird erwartetfunc_bar()
versorgtprogram
. Das problem ist, dargestellt etwa so:(
foo.c
ist in sich geschlossen)Zu diesem Zeitpunkt
./p
korrekt läuft, wie man es erwarten würde. Wir erstellen dannlibbar.so
und ändernfoo.c
um es zu nutzen:Zu diesem Zeitpunkt
./p
gibt die Fehlermeldung, die Sie beschreiben. Wenn wir überprüfenldd libfoo.so
sind, merken wir, dass es nicht nicht eine Abhängigkeitlibbar.so
- das ist der Fehler. Um den Fehler zu korrigieren, müssen wir den linklibfoo.so
richtig:Zu diesem Zeitpunkt
./p
wieder korrekt läuft, undldd libfoo.so
zeigt eine Abhängigkeit vonlibbar.so
.libbar.so
. Funktioniert wie ein Charme jetzt ! Vielen Dank !Fedora-dynamische Verknüpfung erfolgt durch die ld-linux.so.2.
Der dynamische linker mit /etc/ld.so.cache und /etc/ld.so.Vorspannung zu finden library-Dateien.
Führen Sie ldconfig auf dem system mitteilen, wo libfoo suchen sollten libbar.
ldconfig sucht in /lib, /usr/lib und alle directory-Einträge in /etc/ld.so.conf.
Sie können überprüfen, welche Bibliotheken ein Programm verwendet, mit ldd.
Weitere details sind der manual-pages zu den einzelnen Befehlen.
Hier ist ein Beispiel für eine Anwendung, die shared-libraries.
Program.cc
foo.h
foo.cc
bar.h
bar.cc
Bauen mit libfoo.also wie eine shared-library.
g++ -Wall -Wextra -fPIC -shared foo.cc -o libfoo.so
g++ -lfoo -L./-Wall -Wextra program.cc foo.h -o-Programm
ldd-Programm
...
libfoo.so => nicht gefunden
Update /etc/ld.so.cache
sudo ldconfig /home/tobias/Projekte/stubs/also/
ldd zeigt, dass der dynamische linker findet libfoo.so
ldd-Programm
...
libfoo.so => /home/tobias/Projekte/stubs/so/libfoo.so (0x00007f0bb9f15000)
Rufen Sie libbar.so in libfoo.so
Neue foo.cc
Bauen libbar.so und wieder aufzubauen libfoo.so
g++ -Wall -Wextra -fPIC -shared bar.cc -o libbar.so
g++ -Wall -Wextra -fPIC -shared libbar.so foo.cc -o libfoo.so
ldd libfoo.so
...
libbar.so => nicht gefunden
ldd Programm
...
libfoo.so => /home/tobias/Projekte/stubs/so/libfoo.so (0x00007f49236c7000)
libbar.so => nicht gefunden
Dies zeigt, dass der dynamische linker finds immer noch libfoo.so aber nicht libbar.so
Wieder update /etc/ld.so.cache und versuchen Sie es erneut.
sudo ldconfig /home/tobias/Projekte/stubs/also/
ldd libfoo.so
...
libbar.so => /home/tobias/Projekte/stubs/so/libbar.so (0x00007f935e0bd000)
ldd Programm
...
libfoo.so => /home/tobias/Projekte/stubs/so/libfoo.so (0x00007f2be4f11000)
libbar.so => /home/tobias/Projekte/stubs/so/libbar.so (0x00007f2be4d0e000)
Beide libfoo.so und libbar.so zu finden sind.
Beachten Sie diesen letzten Schritt habe keine Auswirkungen auf die Anwendung.
Wenn Sie wirklich streng ausführen von ldconfig ist die Art von verbinden.
Seltsam oder nicht der linker wissen müssen die Abhängigkeiten der Bibliotheken, die diese links verweisen.
Es gibt eine Menge von anderen Möglichkeiten, um dies zu implementieren, aber diese wurde gewählt.
Hast du keine Angaben zum system, sind Sie mit glibc? Wenn ja, was ist die Ausgabe dieses Befehls:
LD_DEBUG=Dateien Programm
Überprüfen Sie auch "Wie schreibt geteilt (ELF) Bibliotheken"(pdf) (egal, ob Sie mit glibc oder nicht)
Ihr Programm nicht haben, um die Verknüpfung mit libbar.so.
Ich denke, dass das problem dadurch verursacht wird, andernfalls geben Sie
libbar.so
als eine Abhängigkeit vonlibfoo.so
beim Bau des später.Ich bin nicht sicher, mit welchem build-system verwenden Sie aber in der CMake-es kann wie folgt erledigt werden:
Wie Sie sehen können
program
verknüpft ist nur mitfoo
(libfoo.so
) undfoo
nur mitbar
(libbar.so
).Oder kann es sein, dass
libbar.so
kann nicht gefunden werden. Versuchen Sie, geben Sie den Pfad zum Verzeichnis, inLD_LIBRARY_PATH
Umgebungsvariable.program
währendfoo
habe nicht einen link zubar
, dann Baufoo
undbar
, aber nichtprogram
) und es funktionierte. Also die Magie von cmake Seite scheint unwahrscheinlich in diesem Fall, obwohl es ist schlau, in der Tat =).libbar
mitlibfoo
und dann Verknüpfung mitprogram
funktionieren wird, unabhängig von der build-system. Allerdings, wennprogram
ist verbunden mitlibfoo
und dannlibfoo
aktualisiert wird, um die Verknüpfung mitlibbar
dies könnte nicht der Fall sein. Wenn Ihr CMake-Skript, es ist klar, dassprogram
verknüpft mitlibfoo
wennlibfoo
änderungen, in Verbindung mitlibbar
ohne Magie.program
durch Verknüpfung mitlibfoo
und man bautlibfoo
. Gehen Sie wie OP gefragt: bauenlibfoo
, dann bauenprogram
und führen Sie den test. Ändern Sie dannlibfoo
link mitlibbar
, re-buildlibfoo
aber nicht neu erstellenprogram
. Versuchen Sie, um zu sehen, ob es noch funktioniert.Sollte dies nicht der Fall sein, es sei denn, etwas über die bar_func symbol geändert. Verwenden Sie die "nm" - Befehl, um ein dump der Symbole in Ihrem Programm, und die shared-object - sehen, wenn es ein Ungleichgewicht gibt und warum.
bar_func()
ist, dass es vorher nicht verwendet wurde, aber jetzt ist es verwendet.