Ich versuche, mein erstes C++-Programm unter Solaris auszuführen. Nur ein einfaches „Hello World“-Programm. Beim Versuch, es auszuführen, erhalte ich die Fehlermeldung libstdc++.so.6:open failed:No such file or directory
. Natürlich habe ich ein bisschen gegoogelt und herausgefunden, dass ich das Problem lösen kann, indem ich die Umgebungsvariable einstelle:
export LD_LIBRARY_PATH=/usr/local/lib
Nach dem erneuten Anmelden stellte ich fest, dass dies keine dauerhafte Lösung war. Ich vermute, dass dies etwas mit der Verknüpfung von libstdc++.so.6 während der Kompilierung zu tun hat. Hier sind die Schritte, die ich von Anfang an ausgeführt habe:
bash-3.2# gcc -c test.cpp
bash-3.2# gcc -o test test.o -lstdc++
bash-3.2# ./test
libstdc++.so.6:open failed:No such file or directory
bash-3.2# ldd test | grep not
libstdc++.so.6 => (file not found)
bash-3.2# /usr/ccs/bin/elfdump test | grep RUNPA
bash-3.2# find /usr -name libstdc++.so.6
/usr/local/lib/libstdc++.so.6
Habe ich beim Kompilieren ein Flag oder etwas anderes übersehen? Wie erstelle ich einen Softlink, damit er weiß, wo er beim Ausführen des Programms suchen muss?
Dies ist die Plattform, die ich verwende:
bash-3.2# uname -a
SunOS ms-sparc8 5.8 Generic_108528-13 sun4u sparc SUNW,Sun-Blade-100
bash-3.2# gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls --disable-libgcj --enable-languages=c,c++
Thread model: posix
gcc version 3.3.2
Antwort1
Der einfachste Weg, den Suchpfad des Solaris-Runtime-Linkers festzulegen, ist die Verwendung von . crle
Dabei müssen Sie jedoch sehr vorsichtig sein, da Ihr System ganz leicht unbrauchbar werden kann, wenn Sie es beschädigen! So fügen Sie /usr/local/bin
den Linker-Pfad hinzu:
# crle -u -l /usr/local/lib
Sobald Sie dies getan haben, rufen Sie crle
es selbstständig auf, um den neuen Suchpfad zu überprüfen.
Eine Alternative besteht darin, den Pfad in die Binärdatei selbst zu kompilieren:
$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++
Die obige Option ist besser, da die Binärdatei auf anderen Systemen funktioniert, ohne dass der Linkerpfad angepasst werden muss.
Antwort2
Das Problem ist, dass dieSolarisLoader kann die Bibliothek nicht finden.
Am besten setzen Sie die LD_RUN_PATH
Umgebungsvariable während der Kompilierung auf das Verzeichnis, in demlibstdc++.so.xxxx(Ihre Versionsnummer) lebt. Dies weist den Linker an, dieses Verzeichnis zur Laufzeit zu durchsuchen.
Beachten Sie, dass dies
LD_RUN_PATH
nicht mit zu verwechseln istLD_LIBRARY_PATH
. Letzteres wird zur Laufzeit analysiert, währendLD_RUN_PATH
im Wesentlichen ein Bibliothekspfad in die ausführbare Datei kompiliert wird, sodass keineLD_LIBRARY_PATH
Einstellung zum Auffinden der Bibliotheken erforderlich ist.
Wenn alles andere fehlschlägt, können Sie Ihre Programme immer über Wrapper-Shell-Skripte ausführen, die die LD_LIBRARY_PATH
Umgebungsvariable entsprechend festlegen.
Das ist im Wesentlichen,
Stellen Sie denLD_LIBRARY_PATH, wenn es nicht enthalten ist in
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
gccDateien werden normalerweise in installiert
/usr/lib/gcc/
.
Verknüpfen Sie dann die libstdc++.so.6 aus dem installierten Verzeichnis mit /usr/lib
oder /usr/local/lib
verwenden Sie Softlinking
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
Antwort3
Erstens besteht keine Notwendigkeit, crle zu verwenden (und wenn Sie nicht wirklich verstehen, was Sie tun, lassen Sie die Finger davon; glauben Sie mir, Sie werden sich selbst mit verrückten Laufzeitfehlern aussperren, wenn Sie es falsch verwenden).
Zweitens ist es nicht nötig, LD_LIBRARY_PATH festzulegen (meistens jedenfalls). Außerdem ist es nicht nötig, symbolische Links zu Drittanbieter-Bibliotheken in /usr zu erstellen.
Machen Sie einfach, was mjturner vorschlägt und geben Sie gcc den richtigen Laufzeitpfad beim Kompilieren
PS: C++-Code sollte mit g++ kompiliert werden
Links:
http://notes.theorbis.net/2010/01/wie-man-solaris-mit-crle-vermasselt.html http://prefetch.net/articles/linkers.badldlibrary.html
Antwort4
Wenn Sie das G++-Frontend verwenden, weiß es, wie C++-Code korrekt mit der libstdc++-Bibliothek verknüpft wird. Dies gilt insbesondere für Solaris.
Was auch immer Sie tun, verwenden Sie unter keinen Umständen LD_RUN_PATH oder LD_LIBRARY_PATH, da diese Variablen für Entwickler von gemeinsam genutzten Objektbibliotheken zur Unterstützung beim Debuggen und nicht für die endgültige Verknüpfung gedacht sind. Ihre Verwendung führt zum Zwischenfügen von Symbolen aus verschiedenen Versionen gemeinsam genutzter Objektbibliotheken und kann zu heimtückischen Abstürzen führen, die äußerst schwer zu debuggen sind, da man aufgrund der besagten Zwischenfügung nicht weiß, welche Symbole zur Laufzeit verwendet werden.
Verlinken Sie immer über das g++-Frontend. Wenn Sie zusätzliche RPATH-Informationen an den Link-Editor übergeben müssen, verwenden Sie am besten g++ -Wl,-R/path/to/lib oder g++ -m64 -Wl,-R/path/to/lib/64 (im Gegensatz zu „lib64“ unter GNU/Linux), je nachdem, ob Sie 32- oder 64-Bit kompilieren. GCC-Compiler unter Solaris sind Multi-Arch.