Ich versuche, eine C-Anwendung dazu zu bringen, gemeinsam genutzte Objekte aus einem relativen Verzeichnis zu laden, unabhängig davon, von wo aus ich sie aufrufe. Bisher funktioniert das nur, wenn ich mich beim Aufruf im selben Verzeichnis wie die ausführbare Datei befinde:
~/prog$ ./my_program
Success
~/prog$ cd ..
~$ ./prog/my_program
./prog/my_program: error while loading shared libraries: libs/libmysharedobject.so: cannot open shared object file: No such file or directory
Wie Sie aus der obigen Ausgabe erraten können, ist das gemeinsam genutzte Objekt im ~/prog/libs/
Verzeichnis gespeichert. So sehen die relevanten gcc-Aufrufe aus:
gcc -std=c99 -ggdb -Wall -pedantic -Isrc
-fPIC -shared -Wl,-soname,libs/libmysharedogbject.so
-o libs/libmysharedobject.so libs/mysharedobject.c
[...]
gcc [CFLAGS omitted] -o my_program main.c
build/src/my_program.o build/src/common.o
-lm -Llibs -lmysharedobject
Hier ist der Anfang der Ausgabe von readelf -d my_program
:
Dynamic section at offset 0x6660 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libs/libmysharedobject.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Ich habe versucht, hinzuzufügen , wodurch in der Ausgabe von -Wl,-z,origin,-rpath='$ORIGIN'
die folgenden Zeilen angezeigt werden :readelf
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
[...]
0x000000006ffffffb (FLAGS_1) Flags: ORIGIN
Aber es scheint mein Problem nicht zu lösen. Ich habe auch versucht , , , und rpath
einzustellen , alles ohne Erfolg. (UPDATE: hat auch keine Wirkung. Das überrascht mich, da es zu einem absoluten Pfad erweitert wird.)$ORIGIN/libs
.
./libs
$(CURDIR)
Gibt es eine Möglichkeit, meine ausführbare Datei dazu zu bringen, ihre gemeinsam genutzten Objekte unabhängig vom Verzeichnis zu finden, aus dem sie aufgerufen wird, vorzugsweise ohne jedes Mal den Endbenutzer festlegen zu müssen LD_LIBRARY_PATH
? Oder versuche ich etwas zu tun, was Linux nicht unterstützt?
Antwort1
Setzen Sie rpath auf $ORIGIN/libs und setzen Sie soname auf libsharedobject statt libs/libsharedobject. Mein Makefile sieht wie folgt aus.
all: my_program
libs/libmysharedobject.so: Makefile success.c
gcc -fPIC -shared -Wl,-soname,libmysharedobject.so \
-o libs/libmysharedobject.so success.c
my_program: Makefile libs/libmysharedobject.so
gcc -o my_program main.c -Llibs -lmysharedobject -Wl,-R,'$$ORIGIN/libs'