16.6. GCC での静的および動的ライブラリーの両方の使用
場合によっては、ライブラリーを静的にリンクする場合と動的にリンクする場合とを分ける必要があります。
前提条件
はじめに
GCC は、動的ライブラリーと静的ライブラリーの両方を認識します。-lfoo
オプションがあると、gcc はまず、動的にリンクされたバージョンの foo ライブラリーを含む共有オブジェクト (.so
ファイル) を検索し、静的ライブラリーを含むアーカイブファイル (.a
) を検索します。これにより、この検索の後に以下の状況が発生する可能性があります。
- 共有オブジェクトのみが見つかり、gcc がそのオブジェクトに動的にリンクする
- アーカイブファイルのみが見つかり、gcc がそのファイルに静的にリンクする
- 共有オブジェクトとアーカイブファイルの両方が見つかり、gcc はデフォルト設定の通りに共有オブジェクトに動的にリンクする
- 共有オブジェクトもアーカイブファイルも見つからず、リンクに失敗する
このようなルールがあるため、リンクするために、静的ライブラリーまたは動的ライブラリーを選択する場合は、gcc が検索可能なバージョンのみを指定するようにします。これにより、-Lpath
オプションで指定する場合に、静的ライブラリーまたは動的ライブラリーを含むディレクトリーを追加するか、追加しないかで、ある程度制御が可能になります。
また、動的リンクがデフォルトの設定であるため、明示的にリンクを指定する必要があるのは、どちらのバージョンも含むライブラリーを静的にリンクする必要がある場合のみです。考えられる解決方法は以下の 2 つです。
-
-l
オプションではなく、ファイルパスで静的ライブラリーを指定する -
-Wl
オプションを使用して、オプションをリンカーに渡す
ファイルで静的ライブラリーを指定する方法
通常、gcc は、-lfoo
オプションを指定して foo ライブラリーにリンクするように指示されます。ただし、代わりに、ライブラリーを含む libfoo.a
ファイルの完全パスは指定できます。
$ gcc ... path/to/libfoo.a ...
ファイルの拡張子 .a
から、gcc は、このファイルがプログラムとリンクするためのライブラリーであることを理解します。ただし、ライブラリーファイルの完全パスを指定するのは柔軟な方法ではありません。
-Wl
オプションの使用
gcc オプションの -Wl
は、基盤のリンカーにオプションを渡す特別なオプションです。このオプションの構文は、他の gcc オプションとは異なります。-Wl オプションの後に、リンカーのオプションをコンマ区切りのリストにして入力します。ただし、他の gcc オプションには、スペース区切りのリストにしてオプションを指定する必要があります。gcc が使用する ld リンカーには、-Bstatic
と -Bdynamic
のオプションがあり、このオプションの後に来るライブラリーを静的または動的にリンクすべきかどうかを指定します。-Bstatic
とライブラリーをリンカーに渡した後、後続のライブラリーを -Bdynamic
オプションで動的にリンクするには、デフォルトの動的リンクの動作を手動で復元する必要があります。
プログラムをリンクするには、まず 静的に (libfirst.a
) ライブラリーをリンクして、次に 動的に (libsecond.so
) リンクして、以下を実行します。
$ gcc ... -Wl,-Bstatic -lfirst -Wl,-Bdynamic -lsecond ...
gcc は、デフォルトの ld 以外のリンカーを使用するように設定できます。-Wl
オプションは、gold リンカーにも適用されます。
関連資料
- GNU コンパイラーコレクション (GCC) の使用: 3.15 Options for Linking
- binutils 2.32 のドキュメント: 2.1 Command Line Options