[解決済み] 依存関係のある動的ライブラリとリンクする
質問
次のようなシナリオを考えてみましょう。
- 共有ライブラリ libA.so ,依存関係なし。
- 共有ライブラリ libB.so、依存関係にあるのはlibA.soです。
libBとリンクするバイナリをコンパイルしたい。 libBのみとリンクするのか、libAともリンクするのかどちらでしょうか?
直接の依存関係にあるものだけをリンクし、依存関係から未解決のシンボルの解決を実行時にさせる方法はありますか?
ライブラリ libB の実装が将来変更され、他の依存関係 (たとえば libC、libD、libE) を導入する可能性があるという事実が心配です。私はそれについて問題を抱えることになるのでしょうか?
言い換えれば
- libAファイル:a.cpp a.h
- libBファイル:b.cpp b.h
- メインプログラムファイル:main.cpp
もちろん、b.cppはa.hを含み、main.cppはb.hを含んでいます。
コンパイルコマンドです。
g++ -fPIC a.cpp -c
g++ -shared -o libA.so a.o
g++ -fPIC b.cpp -c -I.
g++ -shared -o libB.so b.o -L. -lA
以下のオプションのうち、どれを使用すればよいですか?
g++ main.cpp -o main -I. -L. -lB
または
g++ main.cpp -o main -I. -L. -lB -lA
最初のオプションは使えませんでした。リンカはライブラリlibAからの未解決のシンボルについて文句を言います。しかし、それは私には少し奇妙に聞こえます。
どうもありがとうございました。
-- コメントを更新しました。
バイナリをリンクする際、リンカーはmainとlibBからすべてのシンボルを解決しようとします。しかし、libB は libA から未定義のシンボルを持っています。そのため、リンカはそのことについて文句を言うのです。
というわけで、libAも一緒にリンクする必要があります。 しかし、私は共有ライブラリからの未解決シンボルを無視する方法を見つけました。 次のコマンドラインを使用する必要があるようです。
g++ main.cpp -o main -I. -L. -lB -Wl,-unresolved-symbols=ignore-in-shared-libs
見た目はまだ
-rpath
オプションの使用は可能なようです。
しかし、私はそれをもう少し理解する必要があります。
を使用する際に起こりうる落とし穴をご存知の方はいらっしゃいますか?
-Wl,-unresolved-symbols=ignore-in-shared-libs
オプションを使用する際の落とし穴をご存知の方はいらっしゃいますか?
-- コメント2を更新しました。
-rpath
は、この目的のために使用すべきではありません。指定されたディレクトリにあるライブラリを強制的に見つけるのに便利です。そのため
-unresolved-symbol
のアプローチの方がずっと良さそうです。
本当にありがとうございます。
どのように解決するのですか?
もうほとんど解決しているようですね。よく調べましたね。その背後にある「理由」を明らかにする手助けができるかどうか見てみましょう。
リンカーが行っていることは次のとおりです。実行ファイル (上記の 'main') をリンクするとき、未解決のシンボル (関数やその他のもの) がいくつか存在します。リンカーは未解決のシンボルを解決しようと、その後に続くライブラリのリストを調べます。その過程で、いくつかのシンボルが libB.so によって提供されていることがわかり、現在ではこのライブラリによって解決されていることを記録します。
しかし、これらのシンボルのいくつかは、実行ファイルでまだ解決されていない他のシンボルを使用していることも発見されたので、それらも解決する必要があります。libA.so に対してリンクしなければ、アプリケーションは不完全なものになります。libA.so に対してリンクすると、すべてのシンボルが解決され、リンクが完了します。
ご覧のように
-unresolved-symbols-in-shared-libs
を使用しても問題は解決されません。それは、それらのシンボルが実行時に解決されるように、問題を延期するだけです。それが
-rpath
は、実行時に検索するライブラリを指定するためのものです。実行時にシンボルを解決できない場合、アプリは起動に失敗します。
シンボルは複数のライブラリで提供され、それらのいずれかに対してリンクすることで満たされる可能性があるため、ライブラリの依存関係を把握するのは簡単なことではありません。
このプロセスについては、こちらにも記述があります。 なぜ、ライブラリがリンクされる順序は、ときどきGCCでエラーを引き起こすのですか?
関連
-
[解決済み] g++ 出力: ファイルが認識されません。ファイル形式が認識されない
-
[解決済み] gcc/g++とcc1/cc1plusの違いは何ですか?
-
[解決済み] プリプロセッサー出力
-
[解決済み] gccやldで位置非依存の実行ファイルを作成するための-fPIEオプションとは何ですか?
-
[解決済み] cygwinにgccをインストールするにはどうしたらいいですか?
-
[解決済み] npm package.jsonファイルのdependencies, devDependencies, peerDependenciesの違いは何ですか?
-
[解決済み】-Wl,-rpath -Wlがわかりません。
-
[解決済み] 変更されたヘッダーファイルを含むソースファイルをMakefileが自動的にリビルドするにはどうしたらいいですか?(C/C++の場合)
-
[解決済み] 2つのGCCコンパイルされた.oオブジェクトファイルを3つ目の.oファイルに結合する。
-
[解決済み] GCCのビルドにはGMP 4.2+、MPFR 2.3.1+、MPC 0.8.0+が必要です。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】valgrindエラーの解釈 サイズ4の無効な書き込み
-
[解決済み】g++ output: file not recognized: ファイル形式が認識されない
-
[解決済み] gcc エラー : `itoa' への未定義の参照
-
[解決済み] 自作のmakefileを作成する【エラー255】。
-
C++コンパイルエラー:型に名前がない
-
[解決済み] LD_LIBRARY_PATH と LIBRARY_PATH の比較
-
[解決済み] CFLAGS, CCFLAGS, CXXFLAGS - これらの変数はいったい何を制御しているのでしょうか?
-
[解決済み] 一部のライブラリのみを静的にリンクする
-
[解決済み] gcc -ggdbとgcc -gの違いは何ですか?
-
[解決済み] 変更されたヘッダーファイルを含むソースファイルをMakefileが自動的にリビルドするにはどうしたらいいですか?(C/C++の場合)