Version 15.01
ソースファイルのコンパイル
「今回から新章です」
『おおーっ。マルチスレッドのが長かったからなんか久しぶり』
「確かに……残念ながら、今回も長いと思います」
『げげ』
「さて、この Version 15 では、コンパイルとかリンクといった、 Exe
ファイルの作り方について説明します」
『前も言ったけど、やっぱマニアック』
「プログラミングがマニアックじゃないってだけでもうどっぷりはまってる
証拠じゃないかな……」
『なんかいった!?』
「う”、ごめん……話を戻して、そのコンパイルの話をするために、まずは
Version 8.01 ( No.143 ) で作った一番シンプルなプロジェクトを用意しま
す」
『ほい。あの時と同じでいいの?』
「うん。【ファイル】−【新規作成】で、【プロジェクト】のページの
【Win32 Application】を選んで」
『プロジェクト名は?』
「そうだね…… BuildTest で」
『ビルドのテストね。【OK】押して……』
・空のプロジェクト
・単純な Win32 アプリケーション
・標準的な "Hello World" アプリケーション
『やっぱ【空のプロジェクト】?』
「そう。今回も全部一から作りたいから」
『はいはい。【終了】ボタン押して、確認の OK ボタンも押してと。ん、空
のプロジェクトができたよ。 WinMain() 関数も作るの?』
「うん、同じようにソースファイル作って」
『メニューの【ファイル】−【新規作成】で【ファイル】ページを開いて、
【C++ ソースファイル】でファイル名は Main.cpp で』
「そうそう。そうやってファイルを作ると」
『何も書かれてない Main.cpp ファイルが開いた』
「この前と同じように」
#include <Windows.h>
int WINAPI WinMain
( HINSTANCE p_hInstance
, HINSTANCE p_hPrevInstance
, LPSTR p_pchCmdLine
, int p_iCmdShow
)
{
MessageBox( NULL, "テスト", "WinMain()", MB_OK );
return 0;
}
「ってして」
『コピペっと。ビルドして実行! ダイアログ出たよー』
「これで下準備は完了。では、これから、コンパイルってものについて
ゆっくり見ていきます」
『はーい』
「では復習。コンパイルって?」
『 Version 6.01 ( No.101 ) で出てきたね。ソースファイルに書かれた
プログラムをコンピューター用のに変換するんだよね』
「そう。これを実際に見てみましょう。まず、このプロジェクトの
フォルダにある Debug フォルダを開いて」
『 BuildTest\Debug フォルダっと。こんなファイルがあったよ』
BuildTest.exe
BuildTest.ilk
BuildTest.pch
BuildTest.pdb
Main.obj
vc60.idb
vc60.pdb
「これ全部削除して」
『……え? いいのそれって』
「大丈夫、ビルドしたらまた全部作られるから」
『あ、そうなんだ……ほい、削除したよ』
「じゃ、ビルドしてみて」
『ほい。あ、ホントに全部できた!』
「この中の BuildTest.exe をダブルクリックしてみて」
『実行しろってことねー。ん、【テスト】ダイアログ出たよ』
「というわけで、ビルドして作られた BuildTest.exe が、目的の実行
ファイルということです」
『そだね』
「さて、またこのファイル削除して」
『ほい』
「次は、ビルドじゃなく【コンパイル】してみます」
『へ? コンパイル……って、それだけでできるの?』
「できるんです。メニューの【ビルド】−【コンパイル】を選んで」
『うわ、ホントにあった。ほい……このファイルができたよ』
BuildTest.pch
Main.obj
vc60.idb
vc60.pdb
『さっきの7つのファイルのうち、4つだけだね……』
「しかも実は、重要なのは」
Main.obj
「このファイルだけです」
『え!?』
「このファイルが、 Main.cpp をコンパイルして作られた、【マシン語】と
いうコンピューターにも分かる言語に翻訳されたものです」
『これが……』
「この、拡張子が .obj のファイルを【オブジェクトファイル】って言って
コンパイルしたソースファイルの数だけ作られます」
『 Main.cpp のオブジェクトファイルだから Main.obj ってこと?』
「そういうこと」
Main.cpp → コンパイル → Main.obj
「という関係です。アウトプットにも」
--------------------構成: BuildTest - Win32 Debug--------------------
コンパイル中...
Main.cpp
Main.obj - エラー 0、警告 0
『おー、 Main.cpp がコンパイルされて Main.obj ができたわけだ。でも、
これだけじゃ動かないんだよね』
「そう。これはただ単に WinMain() があるだけだから」
『それだけで動きそうなもんだけど……』
「ちゃんとした Exe にしないと動かないんです。と、その前に Main.obj
以外のファイル、つまり」
BuildTest.pch
vc60.idb
vc60.pdb
「の3ファイルを削除しておいて」
『ほい』
「で、この状態でビルドしてみて」
『え? それだとやり直しなんじゃない?』
「ううん、オブジェクトファイルを作った後にソースファイルを修正してい
なければ、再コンパイルされないからオブジェクトファイルはそのまま」
『 Main.obj がそのまま使われるわけね。んじゃビルドっと……3ファイル
できた』
BuildTest.exe
BuildTest.ilk
BuildTest.pdb
『残りの3つで、 BuildTest.exe もできてるね』
「この最後にしてるのが【リンク】です」
『リンク? ネットのリンクとかっていうあれ?』
「そうそれ。 link 、〈継なげる〉っていう意味」
『あ、アウトプットにもそう出てる』
--------------------構成: BuildTest - Win32 Debug--------------------
リンク中...
BuildTest.exe - エラー 0、警告 0
「コンパイル後にできたオブジェクトファイルを最後にリンク、つまり繋ぎ
合わせることで、ちゃんとした Exe ファイルが作られるわけです」
『……くっつけてる?』
「この例だと Main.obj がひとつだけだからよく分からないけど、ソース
ファイルが複数あればわかるかな」
『ソースファイルが複数?』
「というわけでもうひとつ、 Sub.cpp ってファイル作って」
『方法同じでいいんだよね』
「うん、全く同じ方法で作って。そのファイルにとりあえず次の関数を
書いて」
// Sub.cpp
void Sub()
{
}
『ほい書いたよ』
「それじゃまず、 Debug フォルダの中のファイルを全部削除して」
『ほい』
「次にコンパイルして」
『ほい。……あれ?』
BuildTest.pch
Sub.obj
vc60.idb
vc60.pdb
『 Main.obj がない……』
「そう。実はコンパイルは、 VC++ で開いていて、一番手前に表示している
ソースファイルしかコンパイルしないんです」
『ええっ? 全ファイルじゃないの?』
「全ファイルコンパイルするのはビルド、ってこと」
『あ……』
「だからさっきの Main.cpp を手前に持ってくれば Main.cpp をコンパイル
できるよ」
『ん、 Ctrl + Tab っと……あ。このメニューの中』
コンパイル(C) Main.cpp
『って書いてあるけど、もしかしてこれがコンパイルするファイルってこ
と?』
「そう」
『ってことは、 Sub.cpp を手前にして……あれ、グレーになってる』
「さっきコンパイルしちゃったからね。 Sub.cpp に改行でも追加して修正
した状態にしてから保存すれば」
コンパイル(C) Sub.cpp
『おー。ここに出てるファイルがコンパイルされるってことね』
「そして、コンパイルしたソースファイルのオブジェクトファイルが作られ
る、というわけです」
『さっきできた Sub.obj ね』
「というわけで次回に続く!」
/*
Preview Next Story!
*/
『これだけやってきて初めて1ファイルずつコンパイルしたね』
「ビルドだけでたいがい間に合うからね」
『それを今さら教わる理由は?』
「トラブルに対処できるようにするため」
『トラブル?』
「コンパイルエラーとかリンクエラーとか」
『げげ』
「というわけで次回」
< Version 15.02 関数とリンク >
『につづく!』
「そういう問題に対処する能力こそが求められてるって事」
『なんかそう聞くとかなり難しそう……』