Aufbau eines einfachen Hallo-Welt-esque) Beispiel für die Verwendung von ld-option -rpath mit $ORIGIN
Hinweis: Vollständige Beispiel unten. Original-Frage folgt:
Ich Probleme mit ld ' s -rpath
parameter mit $ORIGIN
.
So konnte ich nicht finden ein vollständiges Beispiel, ich dachte, ich würde versuchen eins selbst zu schreiben, so dass ich und andere Sie später benutzen können. Sobald ich es funktioniert werde ich ordentlich es.
Ich fragte über diese vor, aber ich denke, mein post war ein bisschen verwirrend.
Beispiel-Projekt erstellt eine freigegebene Bibliothek und eine ausführbare Datei, die links auf diese Bibliothek.
Es ist sehr klein (3 Dateien, 22 Zeilen incl buildscripts).
Herunterladen können Sie das Projekt aus hier
Aufbau der Datei (vor dem Gebäude):
project/
src/
foo.cpp
main.cpp
make.sh
project/src/foo.cpp
int foo()
{ return 3; }
project/src/main.cpp
int foo();
#include <iostream>
int main()
{
std::cout << foo() << std::endl;
return 0;
}
project/make.sh
# Make directories:
mkdir -p -v obj
mkdir -p -v lib
mkdir -p -v run
# Build the library:
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.sh obj/foo.o
# Build the executable:
g++ -c -o obj/main.o src/main.cpp
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../../lib' -Llib -l:foo.sh
Aus der project
Verzeichnis, führen Sie make.sh
(stellen Sie sicher, es ist ausführbar).
Datei-Struktur (nach dem Aufbau):
project/
src/
foo.cpp
main.cpp
obj/
foo.o
main.o
lib/
foo.so
run/
main.run
make.sh
run/main.run
sollte jetzt laden lib/foo.sh
auf Ausführung, von überall.
Probleme
Derzeit ist dies nur teilweise funktioniert.
Die Dateien kompilieren und verknüpfen-OK, aber es nicht link, wenn Sie von jedem Verzeichnis außer project
(das ist der Sinn der übung).
Inspektion main.run
mit readelf -d
zeigt:
0x0000000000000001 (NEEDED) Shared library: [lib/foo.sh]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../../lib]
Das sieht in der Nähe (ich würde lieber [foo.sh]
als [lib/foo.sh]
aber ich Mach dazu später).
AFAICT die $ORIGIN
im -Wl,-rpath,'$ORIGIN/../../lib'
bedeutet project/run/main.run
so dass diese rpath werden sollte project/lib
.
Habe ich versucht $ORIGIN/..
, $ORIGIN/../lib
, $ORIGIN/../..
, $ORIGIN/../../lib
ohne Erfolg.
Hinweis: ich bin mit -l:
erfordert die vollständige Bibliothek mit dem Namen (unter anderen Gründen, ist es einfacher script mit Variablen, wenn alle Funktionen haben den gleichen Namen-format).
Weiß jemand, warum dies nicht funktioniert?
Oder alternativ, hat jemand oder weiß ein funktionsfähiges Beispiel?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da die meisten Ihr problem: die
/
im Namen hält der dynamische linker zu tun, das rpath Magie.(Ihr rpath ist falsch zu. Denken Sie daran: aus der Schale, wenn Sie gerade in das Verzeichnis, wo die ausführbare Datei ist, wie würden Sie sich zu dem Verzeichnis, in dem Ihre Bibliothek? Hier müssten Sie
cd ../lib
. So Ihr rpath sollte$ORIGIN/../lib
.)Wenn Sie Ihr Objekt als
libfoo.so
und verbunden mit-Llib -lfoo
, der linker würde herausfinden, was Sie beabsichtigten, und das richtige zu tun. Aber wenn du gehst zu verwenden ungewöhnliche Namenskonventionen, die Sie haben zu helfen, ihn heraus:Ändern Sie die link-Zeile für die Bibliothek explizit den SONAME für Ihre Bibliothek, um nur
foo.sh
:g++ -shared -Wl,-soname,foo.sh -o lib/foo.sh obj/foo.o
Fix die rpath:
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib' -Llib -l:foo.sh
Ist es nützlich zu laufen
ldd main/main.run
um zu sehen, was Los ist. In Ihrer ursprünglichen fehlerhaften Fall, Sie sehen etwas wie:(das fehlen jeglicher
=> /some/resolved/path
zeigen, dass es nicht getan ist jeder Pfad, Auflösung). Im festen Fall, Sie sehen etwas wie:/
vermasselt der dynamische linker. Ich hoffe, ich werde in der Lage sein zu setzenfoo.so
improject/lib/dir
und verwendendir/foo.so
. Werde jetzt versuchen.Dies ist ein Beispiel für relativen Pfad verknüpfen (mit ld) mit
$ORIGIN
in einemrpath
.rpath ist ein Pfad (oder eine Menge von Pfaden) eingebettet in binären Dateien (shared-libraries (.so) und ausführbare Dateien).
Diese Pfade sind die wichtigsten Suchpfade für die shared-libraries, die Binär verknüpft werden müssen mit zur Laufzeit.
$ORIGIN ist ein potenzielles start-Verzeichnis für eine rpath Weg.
Es behebt das Verzeichnis mit der Datei ausführen. (zB:
$ORIGIN/lib
)Beispiel-Projekt erstellt eine freigegebene Bibliothek und eine ausführbare Datei, die links auf diese Bibliothek, die mit
rpath
und$ORIGIN
.Herunterladen können Sie das Projekt aus hier.
Aufbau der Datei (vor dem Gebäude):
project/
src/
foo.cpp
main.cpp
make.sh
project/src/foo.cpp
project/src/main.cpp
project/make.sh
Aus der
project
Verzeichnis, führen Siemake.sh
(wenn es nicht ausgeführt werden, gewährleistenmake.sh
Berechtigungen ausgeführt hat).Wenn alles gut geht,
main.run
sollte jetzt ladenlib/dir/foo.so
auf die Ausführung, unabhängig von den absoluten Pfad zuproject
(Sie können verschieben Sie es überall), und unabhängig von der aktuellen working-directory (Sie können es überall ausführen).Hinweise:
-fPIC
weist der compiler die relocatable object-Dateien (Objekt-Dateien, die in freigegebenen Bibliotheken müssen relocatable).-Wl,-soname,<NAME>
bettet<NAME>
in die generierte Bibliothek. Dieser sollte mit dem Namen, die Sie liefern, für die-l
oder-l:
Optionen, wenn die Verknüpfung zu dieser Bibliothek.-Wl,-rpath,'<PATH>'
bettet<PATH>
in die generierte Bibliothek und als runtime-library search path (oder rpath - siehe oben).-L
fügt einen Pfad hinzu, der build-Zeit library search path " - Liste. (Hinweis:rpath
ist irrelevant zur build-time-L
ist irrelevant zur Laufzeit).-l:
fügt den Dateinamen (ohne Pfad) der Bibliothek zu linken. (Ähnlich-l
außer-l:
erfordert den kompletten Dateinamen.Datei-Struktur (nach dem Aufbau):
project/
src/
foo.cpp
main.cpp
obj/
foo.o
main.o
lib/
dir/
foo.so
run/
main.run
make.sh
Hinweis: ich bin mit
-l:
erfordert die vollständige Bibliothek mit dem Namen (unter anderen Gründen, ist es einfacher script mit Variablen, wenn alle Funktionen haben den gleichen Namen-format).Es ist häufiger zu verwenden
-l
, wobei-l<NAME>
bezeichnet lib.so.Einschränkungen
Soweit ich weiß (korrigiert mich, wenn ich falsch Liege) es gibt keine Möglichkeit zum hinzufügen einer Bibliothek innerhalb eines Unterverzeichnisses im Suchpfad (mit Ausnahme hinzufügen, dass als Verzeichnis-sub-path). Dies gilt für beide build-Zeit (
-L
) und run-time (-rpath
) Suchpfade.Also, wenn Sie zwei Bibliotheken mit dem gleichen Namen, aber verschiedenen Standorten, werden Sie nicht in der Lage, Ihnen sowohl. (Ich hoffe, ich bin falsch, oder diese wird fixiert).