私はSolarisで最初のC ++プログラムを実行しようとしています。単純なHello Worldプログラムです。私が走ろうとしているとき。エラーが発生しましたlibstdc++.so.6:open failed:No such file or directory
。もちろん、インターネット検索をしてみると、環境変数を設定するとこの問題を解決できることがわかりました。
export LD_LIBRARY_PATH=/usr/local/lib
再度ログインした後、これが永続的な解決策ではないことがわかりました。私はこれがコンパイル中にlibstdc ++.so.6をリンクすることに関連していると思います。最初から私が行ったステップは次のとおりです。
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
コンパイル中にフラグなどを見逃しましたか?プログラムの実行時にどこを見るのかを知るためにソフトリンクを作成するにはどうすればよいですか?
私が使用しているプラットフォームは次のとおりです。
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
答え1
Solarisランタイムリンカ検索パスを設定する最も簡単な方法はを使用することですcrle
。ただし、システムがハングアップするとシステムを簡単に使用できなくなる可能性があるため、これを行うときは非常に注意する必要があります。/usr/local/bin
リンカーパスに追加:
# crle -u -l /usr/local/lib
これを完了したら、直接ダイヤルcrle
して新しい検索パスを確認してください。
別のアプローチは、パスをバイナリ自体にコンパイルすることです。
$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++
リンカパスを調整しなくてもバイナリは他のシステムで動作するため、上記のオプションはより良いオプションです。
答え2
問題はソラリスローダーがライブラリーを見つけることができません。
最善の方法は、LD_RUN_PATH
コンパイル中に環境変数を次のディレクトリに設定することです。libstdc++.so.xxxx(あなたのバージョン番号)はまだ生きています。これは、リンカーに実行時にこのディレクトリを検索するように指示します。
LD_RUN_PATH
と混同しないでくださいLD_LIBRARY_PATH
。後者は実行時に解析され、デフォルトでLD_RUN_PATH
ライブラリパスの実行可能ファイルにコンパイルされるため、そのLD_LIBRARY_PATH
ライブラリを検索するための設定は不要です。
他のすべての方法が失敗した場合は、いつでも環境変数を適切に設定するラッパーシェルスクリプトでプログラムを実行できますLD_LIBRARY_PATH
。
これが重要なポイントです。
設定LD_LIBRARY_PATH、含まれていない場合
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
湾岸協力協議会ファイルは通常
/usr/lib/gcc/
。
次に、インストールディレクトリのlibstdc ++.so.6をリンクするか、/usr/lib
ソフト/usr/local/lib
リンクを使用します。
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
答え3
まず、crleを使用する必要はありません。 (あなたがしていることを本当に理解していない限り、それを遠ざけてください。私を信じてください。crleを使用すると膨大なランタイムエラーが発生します。)
第二に、LD_LIBRARY_PATH(ほとんどの場合)を設定したり、/ usrのサードパーティライブラリをシンボリックリンクする必要はありません。
mjturnerの提案に従い、コンパイルするときにgccに正しいランタイムパスを指定してください。
PS:C ++コードはg ++でコンパイルする必要があります。
リンク:
http://notes.theorbis.net/2010/01/how-to-screw-up-solaris-with-crle.html http://prefetch.net/articles/linkers.badldlibrary.html
答え4
g++ フロントエンドを使用すると、C++ コードを libstdc++ ライブラリに正しく関連付ける方法がわかります。これは、特にSolarisの場合に当てはまります。
何をしても、どんな状況でもLD_RUN_PATHまたはLD_LIBRARY_PATHを使用しないでください。これらの変数は、共有オブジェクトライブラリ開発者が最終リンクではなくデバッグを支援するために使用するためのものです。これを使用すると、共有オブジェクトライブラリの他のバージョンにシンボルが挿入され、上記の挿入によって実行時にどのシンボルが使用されるかがわからなくなるため、デバッグが困難な潜在的な競合が発生する可能性があります。
常に g++ フロントエンド経由で接続してください。追加の RPATH 情報をリンクエディタに渡す必要がある場合、正しいアプローチは g++ -Wl、-R/path/to/lib または g++ -m64 -Wl,-R/path/to/lib/64 です (次のように) 。 GNU/ "lib64"はLinuxで異なります。 32ビット用または64ビット用にコンパイルするかによって異なります。 SolarisのGCCコンパイラはマルチアーキテクチャです。