動的リンクとは? ロード時にライブラリを解決する
動的リンクは、build時にライブラリのコードを実行可能ファイルにコピーするのではなく、プログラムの共有ライブラリへの参照をロード時または実行時に解決します。
プログラムをbuildするとき、ライブラリのコードは2つの方法のいずれかで含められます。静的リンクはそれをバイナリにコピーします。動的リンクは、プログラムがロードされるときにオペレーティングシステムが解決する参照を残し、多くのプログラムが同時に使える共有ライブラリ(.so、.dll、または .dylib)を取り込みます。これはバイナリを小さく保ちますが、実行時の依存関係を加えます。
動的リンクの仕組み
リンカは、プログラムがどの共有ライブラリを必要とし、どのシンボルを使うかを記録しますが、それらのコードは含めません。ロード時に、動的ローダがそれらのライブラリをシステム上で見つけ、メモリにマップし、実行が始まる前に参照を接続します。
動的リンク vs 静的リンク
静的リンクは、外部ライブラリへの依存を持たない、より大きく自己完結したバイナリを生み出します。動的リンクは、プログラム間でライブラリを共有し、再buildなしにライブラリの更新を取り込めるより小さいバイナリを生み出しますが、それらのライブラリが存在し互換性があることを必要とする代償を伴います。
動的リンクの利点
- ライブラリのコードが重複しないため、より小さい実行可能ファイル。
- 多数のプロセス間で共通ライブラリのメモリを共有。
- ライブラリのセキュリティおよびバグ修正が、すべてのプログラムに一度に届く。
- 実行時にオンデマンドでロードされるオプションのプラグイン。
欠点
動的リンクは古典的な依存関係の問題を持ち込みます。プログラムは実行時に正しいバージョンのライブラリを必要とします。共有ライブラリの欠如や不一致はロード時の障害(恐れられる "shared library not found")を引き起こし、互換性のないバージョンは微妙な不具合を引き起こします。
簡単な例
Linuxでは、ldd ./app がプログラムに必要な共有ライブラリを一覧表示します。ターゲットマシンでそのうち1つが欠けていると、buildは問題なくできたとしても、プログラムは起動に失敗します。
CIにおける動的リンク
あるrunnerで動くbuildが、共有ライブラリの欠如やバージョン違いによって別のrunnerで失敗することがあります。これはコードのバグではなく環境の不一致です。Latchkeyは一貫した再現可能なrunner環境を提供するため、動的リンクの依存関係が毎回同じように解決され、works-on-my-machine の驚きを回避します。
重要なポイント
- 動的リンクは、build時ではなくロード時に共有ライブラリの参照を解決します。
- バイナリを小さく保ちライブラリを共有しますが、実行時の依存関係を加えます。
- 共有ライブラリの欠如や不一致は、コードではなく環境固有の障害を引き起こします。