リンカとは?コンパイルされた断片を1つのプログラムに結合する
リンカとは、別々にコンパイルされたコードの断片とライブラリを1つの実行可能なプログラムに結合し、それらの間の参照を解決するbuildツールです。
コンパイラは通常、各ソースファイルを別々のオブジェクトファイルへ翻訳します。そのどれも完全なプログラムではなく、他のファイルやライブラリで定義された関数や変数を参照します。リンカはそれらを縫い合わせるものです。あらゆる参照を解決し、最終的なレイアウトを定め、1つの実行ファイルまたはライブラリを生み出します。多くのbuildの失敗は実はリンクエラーです。
リンカがすること
コンパイルがオブジェクトファイルを生み出した後、リンカは各参照(関数の呼び出し、グローバルの使用)を、すべてのオブジェクトとライブラリのどこかにあるその定義と照合します。それからすべてを、あらゆるアドレスが解決された1つの成果物に結合します。
コンパイラ vs リンカ
コンパイラは一度に1つのソースファイルを扱い、他のファイルについて知りません。リンカはそれらすべてをまたいで働きます。だからこそ一部のエラー(未定義または重複したシンボル)は、個々のファイルが問題なくコンパイルされた後の、リンク時にのみ現れるのです。
よくあるリンクエラー
- 未定義のシンボル: 参照された関数や変数に定義がない。
- 重複したシンボル: 同じものが2箇所で定義されている。
- 欠けたライブラリ: 依存関係がリンカに提供されなかった。
- アーキテクチャの不一致: 非互換なターゲット向けにビルドされたオブジェクト。
静的リンク vs 動的リンク
リンカはライブラリのコードを実行ファイルに直接コピーする(静的リンク)ことも、ロード時に共有ライブラリから解決される参照を残す(動的リンク)こともできます。それぞれサイズ、起動、更新の伝播の仕方にトレードオフがあります。
手短な例
宣言されたが決して定義されていない関数を呼ぶプログラムは、ファイルごとには綺麗にコンパイルされ、その後、すべてを結合しようとするときにリンカから "undefined reference" エラーでfailします。
CIにおけるリンカ
リンクエラーは決定論的なbuildの失敗、すなわち欠けたシンボルやライブラリであり、毎回同一にfailするため、リトライは決して役立ちません。たいていはbuildの設定ミスや依存関係の欠落を意味します。Latchkeyは一時的なインフラ障害のみをリトライし、本物のリンクエラーは修正のため見えたままにします。
重要なポイント
- リンカはコンパイルされたオブジェクトファイルとライブラリを1つのプログラムに結合する。
- リンクエラー(未定義または重複したシンボル、欠けたライブラリ)はコンパイル成功の後に現れる。
- それらは修正すべき決定論的なbuildの失敗であり、リトライすべき一時的な失敗ではない。