PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Selbstgebaute Lib wird nicht gefunden



Surma
28.05.06, 16:13
Moin.
Ich wollt' mal anfangen, selbst Shared-Libraries zu entwickeln und hab' also zum Testen eine Library gebastelt, die "ja" auf dem Screen ausgeben kann, denn das brauch die Welt ;-)

Ich hab also im Endeffekt jetzt meine Lib "libcrockoutput.so.0.0.1" nach /usr/local/lib (aus Verzweiflung spaeter auch nach /usr/lib) kopiert, `ldconfig -n /usr/local/lib' durchlaufen lassen und per Hand noch einen Symlink names "libcrockoutput.so" in /usr/local/lib gesetzt.
Wenn ich jetzt linken will, passiert das:


$ gcc -g -o test test.o -lcrockoutput
/usr/local/bin/ld: cannot find -lcrockoutput
collect2: ld returned 1 exit status

wenn ich per Hand noch mit -L den Pfad /usr/local/bin (oder eben /usr/bin) angebe, kann ich kompilieren.

Starten geht aber trotzdem nicht:


/test: error while loading shared libraries: libcrockoutput.so.0: cannot open shared object file: No such file or directory


Wieso? Was mache ich falsch?

MfG Alexander "crock" Surma

xanlosch
28.05.06, 18:08
Wie hast du deine Bibliothek übersetzt ? Nicht, dass dort der Fehler liegt ?

Surma
28.05.06, 18:16
Ich wusste nicht, ob das hier angebracht waere zu posten. Aber nun ;-)
Also:

Das Object hab ich mit

$ gcc -fPIC -o crockoutput.o -c crockoutput.c
uebersetzt,
und dann schliesslich die Lib gepackt:

$ gcc -g --shared -Wl,-soname,libcrockoutput.so.0 -o libcrockoutput.so.0.1 crockoutput.o -lc

MfG Alexander "crock" Surma

traffic
28.05.06, 18:21
Als erstes mal musst Du wissen, dass auf Unix-Plattformen bei Bibliotheken immer zwischen zwei Dingen unterschieden wird:

1) Das Verhalten der Bibliotheken zur Bauzeit (d.h. wenn Programme gegen diese Bibliothek gelinkt werden),

2) Das Verhalten der Bibliotheken zur Laufzeit (d.h. wenn Programme, die schon gegen diese Bibliothek gelinkt sind, sie am Beginn der Programmausführung laden).

Das sind zwei völlig unterschiedliche Dinge.

Der erste Punkt ist der Name der Bibliotheken. Ein wirklich allgemeingültiges Gesetz gibt es hier nicht, aber die übliche Konvention für Linux ist:

- Zur Bauzeit wird die Bibliothek unter einem Namen ohne Versionsnummer gesucht (hier libcrockoutput.so)

- Zur Laufzeit wird die Bibliothek unter einem Namen mit einstelliger Versionsnummer gesucht (hier libcrockoutput.so.0)

- Der wirkliche Dateiname der Bibliothek hat eine dreistellige Versionsnummer (hier libcrockoutput.so.0.0.1)

- Die beiden alternativen Namen (ohne Versionsnummer und mit einstelliger Versionsnummer) sind Symlinks auf die wirkliche Datei mit dreistelliger Versionsnummer.

D.h. Du brauchst nicht einen Symlink, sondern gleich zwei.

Dann gibt es die Suchpfade.

- Der Suchpfad zur Bauzeit setzt sich zusammen aus den immer vorgegebenen Verzeichnissen /lib und /usr/lib, den Verzeichnissen, die über "-L"-Optionen angegeben wurden und den Verzeichnissen in der Umgebungsvariable LIBRARY_PATH.

- Der Suchpfad zur Laufzeit setzt sich zusammen aus den immer vorgegebenen Verzeichnissen /lib und /usr/lib, den Verzeichnissen in der Konfigurationsdatei /etc/ld.so.conf, den Verzeichnissen in der Umgebungsvariable LD_LIBRARY_PATH und eventuell hardkodierten Pfaden, die beim Linken eines Programms entweder über "-R"-Optionen oder über die Umgebungsvariable LD_RUN_PATH angegeben wurden.

Daraus folgt:

- Dir fehlt ein Symlink, nämlich der mit der einstelligen Versionsnummer.

- Diesen Symlink wie auch die wirkliche Bibliotheksdatei und den anderen Symlink ohne Versionsnummer kannst Du in /usr/lib installieren, damit sie garantiert immer gefunden werden, aber das ist nicht ratsam. Verwende lieber /usr/local/lib.

- Dass Du "aus Verzweiflung" /usr/lib statt /usr/local/lib verwendet hast, löst das Problem aufgrund des fehlenden Symlinks nicht vollständig und ist auch ansonsten nicht ratsam, weil dieses Verzeichnis eigentlich für Software gedacht ist, die mit dem Paketmanager Deiner Distribution installiert wurde. Trag stattdessen das Verzeichnis /usr/local/lib in die Konfigurationsdatei /etc/ld.so.conf ein und verwende beim Bauen von Anwendungen gegen diese Bibliothek konsequent "-L"-Optionen oder die Umgebungsvariable LIBRARY_PATH.

Surma
28.05.06, 18:52
Hi,
vielen Dank fuer due ausfuehrliche Beschreibung.
Zwar gehts im Moment nur, wenn ich die LD_LIBRARY_PATH setze, aber vermutlich wird die /etc/ld.so.conf erst beim naechsten Start neu geladen (es gibt bestimmt auch einen Befehl, aber den kenn ich nicht :) )

Vielen Dank :)

traffic
28.05.06, 19:13
Nein, /etc/ld.so.conf wird sofort wirksam, nachdem Du /sbin/ldconfig ausgeführt hast. Ein Reboot ist nicht notwendig (wird das Problem aber auch lösen, weil die meisten Distris beim Booten automatisch /sbin/ldconfig ausführen).