「先輩,前から疑問に思ってたんですが,これ何のエラーですか」
「ああ,これはリンクのときのエラー・メッセージだよ」
「リンクって,何ですか」
「え?知らないの。最近のツールは,コンパイルだリンクだって言わないからなぁ・・・。リンクってのは,コンパイルしてできたものを全部つなげることだよ。ビルドすると,コンパイルの後にリンクまでやってるんだ」
「???。全然わかんないです。大体,ビルドとコンパイルって,やってること同じに見えるんですけど。違うんですか?」
「よし,じゃぁちょっと,本腰をいれて説明しようか」
Visual StudioやDelphiなどのツールを利用してプログラムを作っていると,見えてこないのが実行モジュールができるまでのプロセスである。当たり前のことだが,ソース・コードは人間が理解できる形でプログラムを表現したものであり,コンピュータは理解できない。だからコンピュータが理解できる形に変換する作業が必要である注1)。しばしばこの作業を「コンパイル」の一言で片づけることが多いが,実際にはもうちょっと複雑な処理をしている(図1[拡大表示])。
コンパイルは確かに,コンピュータが理解できる形に変換する作業である。しかしこれだけではまだ,「.exe」形式のファイルなど実行モジュールはできていない。まずたいていのプログラムは,複数のソース・コードを記述したファイル(ソース・ファイル)から成る。これらをつなげる必要がある。それに,個々のOSに合わせた初期化の処理が必要である。これを「スタートアップ・ルーチン」と呼び,実行モジュールには組み込まなければならない。このように複数のファイルをまとめて,一つの実行可能な形態にまとめあげる作業を「リンク」と呼ぶ。
一方,「ビルド」という言い方は,開発ツールが統合開発環境(IDE:Integrated Development Environment)という呼び方をするようになってから出てきた言葉だ(図2[拡大表示])。IDEとは,プログラミングに必要なツールを一つの操作環境ですべて実行できるようにしたものである。ソース・ファイルの編集や,コンパイラの起動,デバグ作業などを実行できる。
|
|
複数のファイルにソース・コードを分けたとき,それらをまとめて取り扱う単位としてIDEでは「プロジェクト」という考え方が導入された。プロジェクト全体をコンパイルして実行モジュールを生成する操作を「ビルド」と呼ぶ。個別のファイルをコンパイルする操作と,アプリケーション全体を作り上げる操作を区別するために使われる。したがって「ビルド」を実行すると,必要なソース・コードをすべてコンパイルして,リンクする。だからソース・コードにエラーがあれば,ビルドでもコンパイルでも同じエラー・メッセージを表示する。複数のファイルに分割していなければ,「ビルド」と「コンパイル」はほぼ同じ作業に見えるだろう注2)。
リンク作業は常に発生する
![]() |
リスト1●C言語で書いた「Hello World!」プログラム。 Cの解説書であれば,たいてい最初に紹介されるプログラムである |
ではもう少しリンクについて見てみよう。CやC++といったプログラミング言語を使っていれば,リンク作業が必ず発生する。例えば有名な「Hello World!」プログラム(リスト1[拡大表示])でさえ,リンクしないと実行できない。前述のスタートアップ・ルーチンだけの問題ではない。
多くのコンパイラは,ソース・ファイルに1対1に対応したファイルを生成する。この時点で,プログラムとしてはコンピュータが理解できるマシン語に変換されている。しかしこのファイルには,元になったソース・ファイルに存在する情報しか入っていない。「他のファイルに分割されたソース・コード」の情報は入っていない。だからファイルを分割していればリンクは必須である。
ファイルを分割しなくてもリンクが必要な最大の理由は,「ライブラリ」にある。事実上プログラムは分割されているのだ。例えばHello Worldプログラムでは,4行目の“printf”で始まる文が,ライブラリを呼び出している。ライブラリは,頻繁に使う処理を再利用できる形にまとめたものである。前述のprintfなどがその代表例で,サブルーチンまたはクラスの形で実装されている。サブルーチンは一定の処理をすると,呼び出し元に処理が帰ってくる(図3[拡大表示])。この特性を利用して,キーボードから文字を入力したり,画面に文字列を表示するといった頻繁に使う処理をまとめたものがライブラリである。printf文のように,規格化されて標準で用意されているものもあるし,企業やプログラマなどが自分で作った処理ルーチンをまとめたライブラリもある。リンクという作業の一つの目的は,この便利なライブラリを使えるようにすることだ(図4[拡大表示])。