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 を使用する必要はありません (自分が何をしているのか本当に理解していない限り、使用しないでください。間違って使用すると、ひどいランタイム エラーが発生してロックアウトされることになります)。
2番目に、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 情報を渡す必要がある場合は、32 ビットまたは 64 ビットのどちらをコンパイルするかに応じて、それぞれ g++ -Wl,-R/path/to/lib または g++ -m64 -Wl,-R/path/to/lib/64 (GNU/Linux の "lib64" とは異なります) を実行するのが正しい方法です。Solaris の GCC コンパイラはマルチアーキテクチャです。