2016-04-19 4 views
1

So habe ich mehrere gemeinsame Bibliotheken, die ich versuche, auf meinem Ubuntu-System dauerhaft zu installieren, aber ich habe einige Schwierigkeiten damit.shared library nicht während der Kompilierung gefunden

Ich mag die Bibliotheken und die Header in einem separaten Ordner unter /usr/local/lib und /usr/local/include (zum Beispiel eines Ordner agony genannt) installieren, so wäre es sauber sein und sie würde das Entfernen nur verlangen, dass ich diese Ordner löscht. so sieht es etwa so aus:

/usr/local/lib/agony/libbtiGPIO.so 
/usr/local/lib/agony/libbtiDSP.so 
... 

/usr/local/include/agony/GPIO.h 
/usr/local/include/agony/DSP.h 
... 

Und fügte ich eine Datei hier /etc/ld.so.conf.d/agony.conf, welche umfassen eine Linie beschreibt den Pfad zum Bibliotheksordner:

$ cat /etc/ld.so.conf.d/agony.conf 
/usr/local/lib/agony 

und ich führen sudo ldconfig die Bibliothek Datenbank zu aktualisieren. So zu überprüfen, ob die Bibliothek gefunden wird, ich ldconfig -p | grep bti* und sehe ich folgendes Ergebnis:

$ ldconfig -p | grep bti 
    ... 

    libbtiGPIO.so (libc6,x86-64) => /usr/local/lib/agony/libbtiGPIO.so 
    libbtiDSP.so (libc6,x86-64) => /usr/local/lib/agony/libbtiDSP.so 
    ... 

An dieser Stelle sollte ich in der Lage sein, die Bibliotheken zu verwenden, ohne den Bibliothekspfad angeben. Wenn ich jedoch versuche, eine Anwendung zu kompilieren, ohne den Bibliothekspfad (-L) anzugeben, schlägt sie fehl. Allerdings, wenn ich gcc mit dem Bibliothekspfad ex liefern:

gcc source.c -L /usr/local/lib/agony output -lbtiGPIO -lbtiDSP 

es funktioniert !!

Ich möchte nicht LD_LIBRARY_PATH Umgebungsvariable verwenden, weil diese Bibliothek überall auf dem System verwendet werden soll und ich möchte nicht, dass andere Compiler sich Sorgen um die Bereitstellung LD_LIBRARY_PATH.

Was mache ich hier falsch?

Antwort

1

An dieser Stelle sollte ich

Hier liegt die Verwirrung den Bibliothekspfad ohne Angabe der Bibliotheken verwenden können.

Sie haben die gemeinsame Bibliothek gebaut libbtiGPIO.so (nur mit, dass ein Festhalten), platziert es in /usr/local/lib/agony und aktualisiert, um die ldconfig Datenbank entsprechend.

Der Effekt davon ist, wenn Sie Lauf ein Programm, das mit libbtiGPIO verknüpft war dann der dynamische Linker (/lib/x86_64-linux-gnu/ld-2.21.so, oder ähnliches) wird wissen, wo zu suchen, die Bibliothek in den Prozess zu laden und Sie muss es nicht sagen, indem Sie LD_LIBRARY_PATH in der Umgebung einstellen.

Sie haben aber nichts getan, dass die Liste der Standardbibliothek Suchverzeichnisse beeinflusst, die in Ihre Build von gcc fest verdrahtet werden, dass es zu gibt den Linker (/usr/bin/ld), wenn Sie Link ein Programm mit libbtiGPIO an erster Stelle.

Diese Liste der Standardsuchverzeichnissen ist, was Sie finden, wenn Ihr eine ausführliche Build des Programms zu tun - gcc -v ... - und dann von LIBRARY_PATH den Wert auswählen von dem Ausgang, z.B.

LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:\ 
     /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:\ 
     /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:\ 
     /lib/x86_64-linux-gnu/:\ 
     /lib/../lib/:\ 
     /usr/lib/x86_64-linux-gnu/:\ 
     /usr/lib/../lib/:\ 
     /usr/lib/gcc/x86_64-linux-gnu/5/../../../:\ 
     /lib/:\ 
     /usr/lib 

/usr/local/lib/agony ist nicht einer von denen, und es zu einer von denen, machen Sie haben würden sich gcc von der Quelle zu bauen. Um also Ihr Programm mit libbtiGPIO zu verknüpfen, müssen Sie noch ld mitteilen, wo es mit -L/usr/local/lib/agony -lbtiGPIO zu finden ist.

+0

Danke für das Aufräumen Mike. Wenn ich zum Beispiel eine 3rd-Party-Bibliothek mit apt-get installiere, muss sie die shared libraries und irgendwo wie '/ usr/lib' installieren, da ich den Bibliothekspfad nicht angeben, wenn ich diese Bibliotheken verwende. Was ist, wenn der Name der Drittanbieterbibliotheken mit dem eines anderen auf dem System identisch ist? Dies scheint vom ersten Eindruck an ein wirklich schlechtes Design zu sein. – ArmenB

+0

@ Bloody-Band-Aid Ein Paket kann nicht in die Paket-Feeds der Distro mit dem gleichen Namen wie der vorherige gelangen. Die Distribution steuert ihren Paketnamespace. Wenn ich ein Quellpaket außerhalb der Kontrolle des Paketmanagers installiere, wird es standardmäßig unter '/ usr/local', außerhalb des Bereichs der Distribution installiert. Jedes Problem, das ich bei nicht verwalteten Installationen habe, ist mein eigener Kopfschmerz. Die Installation von zwei Bibliotheken mit demselben Namen im selben Installationspräfix kann nicht durchgeführt werden. Ich könnte sie auf verschiedene Installationspräfixe installieren, '/ usr/local/fooA','/usr/local/fooB', aber das wäre verrückt. –

0

Mann, Sie missverstehen das Verfahren von Complier und Link.

Erstens, libbtiGPIO.so ist eine gemeinsame Link-Bibliothek nicht eine statische Link-Bibliothek. Es ist wichtig, diese Unterschiede zu kennen.

Dann müssen Sie etwas anderes wissen. Ändern ld.so.conf.d/*. conf und run sudo ldconfig, es wirkt sich auf den Vorgang der Verbindung. Mit anderen Worten, wenn Sie keine Agony.conf und sudo ldconfig hinzufügen, erhalten Sie einen Fehler, wenn Sie ./a.out statt gcc source.c -L .... ausführen gcc-Befehl kann erfolgreich ausgeführt werden, obwohl Sie nicht ldconfig.

Wenn Sie schließlich die Umgebungsvariable LD_LIBRARY_PATH nicht verschmutzen, müssen Sie in Ihrem gcc-Befehl die Optionen -L ... hinzufügen. Wenn Sie nicht häufig zu viele Wörter in Ihre Shell eingeben möchten, können Sie Makefile verwenden.

+0

Ich habe nie gesagt, dass es statisch ist, lies die erste Zeile, in der ich "shared" geschrieben habe, aber der Kern dessen, was du gesagt hast, synchronisiert sich mit dem, was Mike gerade gesagt hat. Vielen Dank – ArmenB