FE EXAM

リンカ(Linker)

複数のオブジェクトファイルやライブラリを結合して1つの実行ファイルを生成するプログラム。

INTERACTIVE VISUALIZATION
オブジェクト
ライブラリ
実行ファイル
フェーズ
idle
解決済み参照
0 / 3
実行ファイル
未完成
シナリオ
ステップ1 / 6
STEP 1/6結合前 — 部品がバラバラに存在するプログラムを書いてコンパイル(=ソースコードを機械語に翻訳すること)すると、ファイルごとに「オブジェクトファイル」という機械語の断片ができます。今は main.o・calc.o という2つの断片と、よく使う処理をまとめた libmath・libio というライブラリが、まだバラバラに置かれている状態です。
リンカmain.oオブジェクトファイル提供: main呼ぶ: calc,printMsgcalc.oオブジェクトファイル提供: calc呼ぶ: sqrtlibmathライブラリ提供: sqrtlibioライブラリ提供: printMsg実行ファイルapp.exe(結合の完了を待っています)
外部参照の解決状況
呼ぶ側呼ぶ関数提供する側状態
main.ocalccalc.o未解決
main.oprintMsglibio未解決
calc.osqrtlibmath未解決
解説

📌
リンカとは

main.ocalc.olibmathリンカ実行ファイル

リンカ(連携編集プログラム)とは、コンパイルで生成された複数のオブジェクトファイルやライブラリを結合し、1つの実行ファイルを作るプログラムです。コンパイル(=ソースコードを機械語に翻訳すること)は、ファイルごとにバラバラの機械語の断片(オブジェクトファイル)を作るだけなので、それらをつなぐリンカが必要になります。

身近な例で考えると、プラモデルの組み立てに似ています。胴体・腕・脚といった部品(オブジェクトファイル)を別々に作っただけでは動くロボットになりません。すべてを正しく組み付けて1体にする工程が、リンカの仕事にあたります。

上のツールで▶ボタンを押すと、バラバラのオブジェクトファイルとライブラリが集められ、参照がつながり、最後に1つの実行ファイルが完成するまでの流れを確認できます。

🔗
結合の仕組み

結合の中心となる作業が外部参照の解決です。外部参照とは、別ファイルにある関数や変数を呼び出している箇所のことです。

たとえば main.o の中に「calc という関数を呼ぶ」と書いてあっても、その calc 本体は別の calc.o の中にあります。リンカはこの呼び出しを成立させるために次のことを行います。
関数の所在を探す:呼びたい関数がどのファイルのどこにあるかを特定する
アドレスを書き込む:呼び出し先のアドレス(=メモリ上の番地)を呼び出し箇所に埋め込む
1つにまとめる:各ファイルの機械語を並べ直し、ずれた位置に合わせてアドレスを調整する

これは電話帳で相手の番号を調べてつなぐ作業に似ています。「田中さんに電話したい」と思っても番号を知らなければかけられません。リンカが全員の番号を調べ終えることで、はじめてプログラム全体が正しく連携できるようになります。

⚖️
静的/動的リンク

ライブラリの結びつけ方には、静的リンク動的リンクの2種類があります。タイミングと組み込み方が違います。
静的リンク:ビルド時にライブラリを実行ファイルへ組み込む
動的リンク:実行時にライブラリを読み込む

項目静的リンク動的リンク
組み込む時点ビルド時実行時
実行ファイルの大きさ大きい(中に含む)小さい(外部にある)
ライブラリ更新作り直しが必要差し替えだけで反映

静的リンクはお弁当を全部詰めて持ち歩くイメージです。1つで完結して動きますが、荷物(実行ファイル)は重くなります。動的リンクは現地の食堂を使うイメージです。荷物は軽い反面、その食堂(共有ライブラリ)が現地になければ動きません。多くのOSでは、よく使うライブラリを動的リンクで共有して、メモリやディスクを節約しています。

📌
言語処理の流れとリンカの役割

ソース.c / .pyコンパイラmain.ocalc.olibmathリンカ実行app.exeバラバラの部品 → リンカ → 1つにまとめる

プログラムが動くまでには、「コンパイラ → リンカ → ローダ」という3段階があります。リンカは、その中の2段階目で活躍します。

なぜリンカが必要なのか、を順を追って理解しましょう。
コンパイラ(=ソースコードを機械語に翻訳するプログラム)は、ファイル1つずつをバラバラに翻訳します。たとえば main.c だけを翻訳して main.o(=オブジェクトファイル)を作ります。
・でも main.o の中に「別ファイルにある関数を呼ぶ」と書いてあっても、コンパイル時点ではその関数の場所が分かりません。
・そこでリンカが登場します。すべての .o ファイルとライブラリを集め、呼び出し先を特定してひとつにつなぎ、動かせる実行ファイルを完成させます。

上の図のように、リンカはプログラム製造の「組み立て工程」にあたります。部品(オブジェクトファイル)が完成していても組み立てなければ動かない──リンカはその「組み立て役」です。

📌
ライブラリとは

ライブラリsqrt()printf()sin()strlen()リンカ自分のプログラム+ライブラリの部品必要な関数だけ取り出してつなぐ

ライブラリとは、よく使う関数や処理をまとめておいた「部品集」です。たとえば「平方根を計算したい」とき、その計算式を自分で書く必要はなく、数学ライブラリの sqrt() という関数を呼び出せば済みます。

なぜライブラリとリンカがセットで語られるのか。ライブラリは別ファイルとして存在するため、コンパイルの段階では「どこにあるか」が分かりません。リンカが実行ファイルを作るときに、必要なライブラリを探し出し、自分のプログラムに組み込む(リンク)というのがリンカの重要な仕事の一つです。
静的ライブラリ(=あらかじめ作られた部品集ファイル):ビルド時にリンカが実行ファイルへ組み込む
共有ライブラリ(動的ライブラリ):実行ファイルには含めず、実行時に読み込む

身近な例では、料理レシピ集(ライブラリ)に似ています。オムライスを作るとき「卵の溶き方」を毎回考えずにレシピ集から参照します。リンカは「どのレシピを使うか」を確認し、必要なページだけ料理の手順書(実行ファイル)に貼り付ける係です。

練習問題

🎯
基本情報技術者 練習問題

Q1.リンカ(リンケージエディタ)の役割として最も適切なものはどれか。
A.ソースコードを機械語に翻訳する
B.複数のオブジェクトファイルやライブラリを結合して1つの実行ファイルを生成する
C.実行ファイルを主記憶へ読み込む
D.プログラムの誤りを検出する
Q2.リンカが行う「外部参照の解決」とはどのような処理か。
A.変数の値を計算して確定する
B.別ファイルにある関数や変数の呼び出し先アドレスを特定して結びつける
C.ソースコードの文法エラーを修正する
D.実行ファイルを圧縮する
Q3.静的リンクと動的リンクの違いとして正しいものはどれか。
A.静的リンクは実行時、動的リンクはビルド時にライブラリを組み込む
B.静的リンクはビルド時にライブラリを実行ファイルへ組み込み、動的リンクは実行時にライブラリを読み込む
C.両者に違いはない
D.静的リンクではライブラリを使えない

関連コンテンツ