GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Kann .so nicht im selben Verzeichnis wie die ausführbare Datei finden?

Lösung 1:

Sie können LD_LIBRARY_PATH zwar so einstellen, dass der dynamische Linker weiß, wo er suchen soll, aber es gibt bessere Optionen. Sie können Ihre gemeinsam genutzte Bibliothek an einem der Standardorte ablegen, siehe /etc/ld.so.conf (unter Linux) und /usr/bin/crle (auf Solaris) für die Liste dieser Orte

Sie können -R <path> passieren zum Linker, wenn Sie Ihre Binärdatei erstellen, wodurch <path> hinzugefügt wird zur Liste der Verzeichnisse, die nach Ihrer gemeinsam genutzten Bibliothek durchsucht wurden. Hier ist ein Beispiel. Zuerst das Problem zeigen:

libtest.h:

void hello_world(void);

libtest.c:

#include <stdio.h>
void hello_world(void) {
  printf("Hello world, I'm a library!\n");
}

hallo.c:

#include "libtest.h"
int main(int argc, char **argv) {
  hello_world();
}

Makefile (Tabs müssen verwendet werden):

all: hello
hello: libtest.so.0
%.o: %.c
        $(CC) $(CFLAGS) -fPIC -c -o [email protected] $<
libtest.so.0.0.1: libtest.o
        $(CC) -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
libtest.so.0: libtest.so.0.0.1
        ln -s $< [email protected]
clean:
        rm -f hello libtest.o hello.o libtest.so.0.0.1 libtest.so.0

Lassen Sie es uns ausführen:

$ make
cc  -fPIC -c -o libtest.o libtest.c
cc -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
ln -s libtest.so.0.0.1 libtest.so.0
cc     hello.c libtest.so.0   -o hello
$ ./hello 
./hello: error while loading shared libraries: libtest.so.0: cannot open shared object file: No such file or directory

Wie man es repariert? Fügen Sie -R <path> hinzu zu den Linker-Flags (hier durch Setzen von LDFLAGS ).

$ make clean
(...)
$ make LDFLAGS="-Wl,-R -Wl,/home/maciej/src/tmp"
(...)
cc   -Wl,-R -Wl,/home/maciej/src/tmp  hello.c libtest.so.0   -o hello
$ ./hello 
Hello world, I'm a library!

Wenn Sie sich die Binärdatei ansehen, können Sie sehen, dass sie libtest.so.0 benötigt :

$ objdump -p hello | grep NEEDED
  NEEDED               libtest.so.0
  NEEDED               libc.so.6

Die Binärdatei sucht ihre Bibliotheken, abgesehen von den Standardorten, im angegebenen Verzeichnis:

$ objdump -p hello | grep RPATH
  RPATH                /home/maciej/src/tmp

Wenn Sie möchten, dass die Binärdatei im aktuellen Verzeichnis sucht, können Sie den RPATH auf $ORIGIN setzen . Das ist ein bisschen knifflig, weil Sie sicherstellen müssen, dass das Dollarzeichen nicht von make interpretiert wird. Hier ist eine Möglichkeit, dies zu tun:

$ make CFLAGS="-fPIC" LDFLAGS="-Wl,-rpath '-Wl,\$\$ORIGIN'"
$ objdump -p hello | grep RPATH
  RPATH                $ORIGIN
$ ./hello 
Hello world, I'm a library!

Lösung 2:

Der Loader überprüft niemals das aktuelle Verzeichnis auf gemeinsam genutzte Objekte, es sei denn, es wird ausdrücklich über $LD_LIBRARY_PATH darauf verwiesen . Siehe ld.so(8) Manpage für weitere Details.

Lösung 3:

Um die gemeinsam genutzten Objekte aus demselben Verzeichnis wie Ihre ausführbare Datei zu laden, führen Sie einfach Folgendes aus:

$ LD_LIBRARY_PATH=. ./binary

Hinweis:Die Variable LD_LIBRARY_PATH Ihres Systems wird dadurch nicht geändert. Die Änderung betrifft nur diese und nur diese Ausführung Ihres Programms.

Lösung 4:

Für alle, die CMake für ihren Build verwenden, können Sie den CMAKE_EXE_LINKER_FLAGS festlegen zu Folgendem:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'")

Dadurch werden die Linker-Flags für alle Build-Typen (z. B. Debug, Release usw.) ordnungsgemäß weitergegeben, um zuerst nach .so-Dateien im aktuellen Arbeitsverzeichnis zu suchen.

Lösung 5:

Für alle, die immer noch ohne Antwort kämpfen, habe ich selbst eine mit folgendem Vorschlag gefunden:

Sie könnten versuchen, den ld.so.cache zu aktualisieren mit:sudo ldconfig -v

Hat bei mir funktioniert.


Linux
  1. Was ist der beste Weg, um die Anzahl der Dateien in einem Verzeichnis zu zählen?

  2. Wie kann ich eine MD5-Prüfsumme eines Verzeichnisses berechnen?

  3. Wie finde ich die älteste Datei in einem Verzeichnisbaum?

  4. Wie kann ich den Ordner, in dem gesucht wird, von find ausschließen?

  5. Wie entferne ich alle Symlinks unter dem Verzeichnis?

So ermitteln Sie die Größe eines Verzeichnisses in Linux

So ermitteln Sie die Gesamtgröße eines Verzeichnisses in Linux

Beheben Sie den Fehler, dass der Befehl hwmatch auf Grub nicht gefunden werden kann

Der Linux-Befehl zum Suchen des Verzeichnisses:Erklärt

Wie finde ich den Speicherort der ausführbaren Datei in C?

Wo finde ich die erste Version des Linux-Betriebssystems?