VisualC++ Toolkit 2003
 によるDXライブラリの使い方


 VisualC++ Toolkit 2003 を使用してDXライブラリを使ったソフトを制作するには
以下のような手順を踏みます。


1.DXライブラリを使ったソフトの開発に必要なものを揃える

2.プログラムをコンパイルするための下準備をする

3.作成するソフト用のフォルダを作成する

4.プログラムを組む

5.コンパイルを行うバッチファイルの作成、実行


番外.Make ファイル



1.でDXライブラリを使ったソフトの開発に必要なものを揃える

 VisualC++ Toolkit 2003 とDXライブラリを使用して、実際にPC上で動作する Windows
アプリケーションを制作する環境を揃える為には以下のものが必要です。


  ・VisualC++ Toolkit 2003
  ・Microsoft Platform SDK
  ・DXライブラリ Windows版 VisualStudio( C++ )用


  まず一つ目の VisualC++ Toolkit 2003 はプログラムをコンパイルして実行可能なソフトを
 作成する為に無くてはならない物です。

  二つ目の Microsoft Platform SDK は WindowsOS 専用の機能を用いたアプリケーション
 を作成するために必要なもので、こちらも WindowsOS 上で動作するアプリケーションを作成
 するためには無くてはならないものです。
 (因みに SDKSoftware Development Kit の略称です)

  三つ目の DXライブラリ Windows版 VisualStudio( C++ )用 は、DXライブラリを使用して
 DirectX を使ったソフトを作成するために必要なものです。こちらからダウンロードしておいて下さい。


 DXライブラリ以外の2つは、Microsoft のウェブサイトから無料でダウンロードすることが出来ます。
 容量が数百MBあるので高速な回線とそれなりの時間が必要ですが、順番にダウンロードしていきましょう。

 まず VisualC++ Toolkit 2003こちらからダウンロード出来ます。
 『Download』を押してインストーラーをダウンロードして、VisualC++ Toolkit 2003 を
インストールして下さい。(インストール時の設定は特に変更する必要はありません)

 次に Microsoft Platform SDK ですが、こちらはまずこのページの下の方にある 『PSDK-x86.exe』
ダウンロードして実行してください。色々訊かれると思いますが、特に設定を変更する必要はありません。
 インストールが開始するとインストーラが必要なファイルを逐次ネット上からダウンロードしますので、
インストールが終了するまではネットワーク環境を維持し続ける必要があります。
 インストール完了までには通信速度にもよりますが、かなり時間も掛かりますので従量制の
インターネットサービスをご利用されている方は通信料金に注意して下さい。(汗)

 これが全て終われば、DirectX のアプリケーションを作成するために必要なものは揃ったことになります。



2.プログラムをコンパイルするための下準備をする

 必要なものが揃ったところで早速プログラムを組んで見たいところですが、まだちょっとやることがあります。
 それは、作成したプログラムを楽にコンパイルするための準備です。

 というのも。
 まず、VisualC++ Toolkit 2003 (のコンパイラ)『コマンドプロンプト』上で動作する
『コンソールアプリケーション』
なのですが、普通の Windowsアプリケーションと違い、ソフトを
起動してから各種の『設定』コンパイルなどの作業を行うタイプのソフトではなく、ソフトを
起動するときにコンパイルすべきファイルやコンパイルに必要なファイルの在りか等の
諸々の情報を渡す必要があるのです。
例:プログラムファイル test.c を警告レベル3、『実行速度優先』でコンパイルする cl /W3 /O2 test.c
 上記の例では cl はコンパイラのアプリケーション名、/W3 はコンパイラが出力する
『警告』をどの程度詳細に行うかという度合いを『3』とするオプション、/O2
プログラムをなるべく高速に動作するようにコンパイルするように指示するための
オプション、と、こんな具合に起動する時に必要な情報は全部渡してやる必要があるわけです。

 これがプログラムファイルが1つくらいでしたら『コマンドプロンプト』を起動して、その
都度コマンドを直接入力しても良いかもしれませんが、後々ソースファイルを幾つも扱う
ようになったら一回のコンパイルで入力しなければならないコマンドが長くなって大変です。

 なので、ここではその作業を少しでも楽にするための作業をしようというわけです。
 ここではコンパイルするに当たって必要な『環境変数』の設定をする『バッチファイル』を作成します。
 『バッチファイル』とは『コマンドプロンプト』上で効果があるコマンドの羅列が書かれた
テキスト形式のファイルで、 後から好きな時にその『バッチファイル』に書かれている
コマンドを実行することが出来るという便利な代物です。

 つまり毎回入力する必要がある『決まり文句』的なコマンドを『バッチファイル』にして
おくことで、コンパイルする際に必要な手間を減らそうという訳です。

 コンパイルするに当たって必要な『環境変数』の設定、この『環境変数』とは、
『環境変数』よりは知られているもので例えるなら『レジストリ』みたいなものです。

 VisualC++ Toolkit 2003 では、この環境変数から『VisualC++ Toolkit 2003 は何処に
インストールされているか』
『コンパイルに必要なファイルはどのフォルダにあるか』等の
所謂『位置情報』を得ていますので、利用する側はコンパイラを起動する前にそれらの
『環境変数』に必要な位置情報を設定しておく必要があるのです。

 で、この『位置情報』は早々変わる事のないものばかりなので、『環境変数』
位置情報を設定するコマンド『バッチファイル』に予め書いておこう、というわけです。

 前置きが長くなりましたが、早速 VisualC++ Toolkit 2003 が必要とする『位置情報』
『環境変数』の設定を行う『バッチファイル』を作成してみましょう。
(ちなみに『コマンドプロンプト』『バッチファイル』をキーワードに調べると、もっと詳しい
情報を得ることが出来ます)

 まずメモ帳を開いて以下のような内容を打ち込んで下さい。


SET PFSDK=C:\Program Files\Microsoft Platform SDK SET VCTK=C:\Program Files\Microsoft Visual C++ Toolkit 2003 SET DXLIB=C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用 SET PATH=%VCTK%\bin;%PFSDK%\Bin;%PFSDK%\Bin\Win64;%PATH% SET INCLUDE=%VCTK%\include;%PFSDK%\Include;%DXLIB% SET LIB=%VCTK%\lib;%PFSDK%\Lib;%DXLIB%


 ここで、上半分の


C:\Program Files\Microsoft Platform SDK C:\Program Files\Microsoft Visual C++ Toolkit 2003 C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用


 については、それぞれ上から『Microsoft Platform SDK』をインストールしたフォルダの位置
『Visual C++ Toolkit 2003』をインストールしたフォルダの位置、DXライブラリのアーカイブの中にある
『プロジェクトに追加すべきファイル_VC用』フォルダの位置、となりますので、上記通りではない場合は修正して下さい。
(恐らく必ず修正することになるのはDXライブラリのフォルダだと思います)

 というわけで、なんとなく分かると思いますが、『SET』というコマンドが『環境変数』に情報を
格納するコマンドで、『SET』の右側にある『PATH』『VCTK』等が『環境変数』の名前です。
 実際に VisualC++ Toolkit 2003 が必要とする『環境変数』『INCLUDE』『LIB』の二つで、
それぞれプログラムのコンパイルに必要なファイルが何処にあるか、という情報を格納するように
なっています。

 尚、『PATH』OSが使用している環境変数で、OS『コマンドプロンプト』上でコマンドを
実行した際に『カレントディレクトリ(カレントフォルダ)』指定のファイルが無かった場合
この『PATH』という環境変数格納されているフォルダ位置からコマンドで指定されたファイルを探す
という動作をします。

 ここでは VisualC++ Toolkit 2003 のソフトウエアが格納されているフォルダと Microsoft Platform SDK
のソフトウエアが格納されているフォルダを追加することで、どのフォルダが『カレントディレクトリ
(カレントフォルダ)』
になっていても VisualC++ Toolkit 2003Microsoft Platform SDK
ソフトウエアを実行できるようにしていると言う訳です。

 因みにその上にある『VCTK』『PFSDK』環境変数なのですが、ここではこのバッチファイル内で
何回も同じフォルダパスを書くのを楽にするためだけに使っています。(つまり誰でも『環境変数』
使うことが出来るのです)
 環境変数に格納した文字列は、バッチファイル内で『%環境変数名%』とすることでそこに環境変数
の内容が在ることと同じ
になるので、上記のバッチファイルは次の様に書いても同じということになります。


SET PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;C:\Program Files\Microsoft Platform SDK\Bin;C:\Program Files\Microsoft Platform SDK\Bin\Win64;%PATH% SET INCLUDE=C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;C:\Program Files\Microsoft Platform SDK\Include;C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用 SET LIB=C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;C:\Program Files\Microsoft Platform SDK\Lib;C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用


 というわけで3行で済みますが、とても一行が長くなってしまいます。(しかもフォルダ位置が
変わったら何箇所も修正しなくてはいけません)というわけで、環境変数を利用して利便性を
高めているわけです。

 ともあれ、これで『下準備』の為のバッチファイルは完成ですので、適当なフォルダに
"setvctk.bat"』というファイル名(必ずダブルコーテーション(")でファイル名を囲って
ください
)で何処か分かりやすい所に保存しておいてください。
(間違って上記の3行版の方を保存しないように注意して下さい(汗))

 因みに拡張子(ファイル名の『.』以降の3・4文字の部分)が『bat』ではないと WindowsOS
『バッチファイル』だと認識してもらえないので、『バッチファイル』拡張子は必ず『bat』になります。

 尚、『setvctk.bat』というファイル名で保存したはずなのにエクスプローラ(普段何気なく使って
いるフォルダの中身を見たりファイルを開いたりする作業を行う際に使用しているソフトの名称です
)
上では『setvctk』と表示されて拡張子の部分である『.bat』表示されていない、という方は、
エクスプローラメニューから『ツール』→『フォルダオプション』『フォルダオプション』ダイアログ
を開き、その中の『表示』タグの中の沢山のチェックボックスのリストの中から『登録されている
拡張子は表示しない』
チェックを外し『すべてのフォルダに適用』ボタンを押した上で『OK』
押して下さい、そうすればエクスプローラ上でも『setvctk.bat』とファイル名の全体が表示される
ようになると思います。




3.作成するソフト用のフォルダを作成する

 作成するソフトのプログラムなどのファイルは別に何処にあってもいいのですが、最終的に
幾つかのファイルが生成されますので、やはり専用のフォルダを一つ作っておいた方がいい
だろう、的な、ただそれだけのことです。(^^;

 というわけで、別に一つのソフトに一つの専用フォルダが無ければコンパイルが出来ない
とかそういうことは全く在りませんが、これから説明する上でも専用のフォルダがあった方が
何かと都合が良いので、とりあえず新しく一つフォルダを作っておいて下さい。

 そして、作成したフォルダの中に先程作成した『setvctk.bat』をコピーしておいて下さい。



4.プログラムを組む

 では、いよいよDXライブラリを使ったプログラムを組んでみましょう。
 まずメモ帳を開いて、次のプログラムを入力してみて下さい。


#include "DxLib.h" // プログラムは WinMain から始まります int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { if( DxLib_Init() == -1 ) // DXライブラリ初期化処理 return -1 ; // エラーが起きたら直ちに終了 DrawPixel( 320 , 240 , GetColor( 255,255,255 ) ) ; // 点を打つ WaitKey() ; // キー入力待ち DxLib_End() ; // DXライブラリの後始末 return 0 ; // ソフトの終了 }



 どの部分が何をしているのか簡単に説明します。

 まず最初の1行はDXライブラリを使用するために必要なファイルをインクルードしています。

 次の『int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )』
はウインドウズのプログラムのスタート地点となる
関数の宣言です。それぞれの単語が何を意味しているかは特に考える必要はありません。
ウインドウ環境のスタート関数はすべてこの形の宣言をとります。

 中括弧内の最初の文『if( !DxLib_Init() ) return -1;』DXライブラリを初期化して
使える状態にするために必要な関数『DxLib_Init』を呼んでいます。
 この関数はDXライブラリを使うプログラムを組む際には一部の例外を除いて必ず
最初に呼び出す必要があります。因みに『if(...』と書かれているのは初期化に
失敗したらその時点でソフトを終了させるという処理を行うための物です。

 『DrawPixel』はそのまま点を描画するための関数です。

 その次の『WaitKey』はキーが押されるまで処理を止める関数です。

 最後の『DxLib_End() ;』は注釈にも書いてある通りDXライブラリの後始末を行う
関数を呼んでいる文です。DXライブラリを使用しているプログラムは最後に必ず
この関数を呼ばなくてはなりません。
 これを呼ばないでソフトを終了するとメモリリーク等の不具合が起こる原因となりますので注意してください。


 とまあ、プログラム自体はこんな感じです。
 とりあえずこちらを打ち込んだら、『"pixel.cpp"』というファイル名で先程作った専用フォルダに
保存して下さい。(ダブルコーテーション(")で必ずファイル名を囲ってください、そうしないとメモ帳の
場合『pixel.cpp.txt』 というファイル名で保存されてしまいます(汗)
)
 これでプログラムの打ち込みは完了です。



5.コンパイルを行うバッチファイルの作成、実行

 プログラムが完成したらコンパイルをします。
 コンパイルも『コマンドプロンプト』上で動作するソフトウエアを使用して行うので、コンパイルが
失敗した際に何度も同じコマンドを書かなくても良いようにコンパイルの作業も『バッチファイル』
してしまいましょう。

 というわけで、とりあえず再度メモ帳を開き、次のように入力して『"compile.bat"』というファイル名で
工程3で作成した専用フォルダに保存してください。(ダブルコーテーション(")で必ずファイル名を囲ってください)


call setvctk.bat cl /c /W3 /O2 pixel.cpp link /SUBSYSTEM:WINDOWS /OUT:pixel.exe pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib pause


 このバッチファイルで行っていることを説明します。

 まず最初の行では工程2で作成した『コンパイルに必要な位置情報を環境変数に設定する
バッチファイル』
を実行しています。『バッチファイル』上で他の『バッチファイル』を実行する時は、
大抵その前に『call』を書きます。これを書かないと『他のバッチファイル』(つまりここでは
『setvctk.bat』)の実行が終わると残りの『cl ~~』『link ~~』『pause』の3行を実行せずに
終了してしまうからです。

 2行目ではプログラムファイル『pixel.cpp』をコンパイルしています。

 『cl』コンパイラのファイル名、『/c』『オブジェクトファイル』だけを生成してくれ、というオプション
(『オブジェクトファイル』とは、拡張子『exe』の実行可能ファイルにする一つ前の状態、
みたいなもので、拡張子『obj』のファイルです)
 『/W3』警告レベル(大した事ない警告は出力しないでくれ、レベル)にするオプション
 『/O2』がコンパイルして出来るネイティブコード(PCが直接理解できるプログラム、『マシン語』
『機械語』等とも言います)を出来るだけ高速に動作するものにしてくれ、というオプション
 そして最後の『pixel.cpp』がコンパイルしたいプログラムのファイル名です。

 ここでは『/c』のオプションを指定して、『オブジェクトファイル』だけを生成する指定に
なっているので、このコマンドが成功すると、pixel.cpp拡張子『obj』になった『pixel.obj』
という『オブジェクトファイル』pixel.cpp があるフォルダに作成されます。

 3行目では2行目で作成した『オブジェクトファイル』とアプリケーションを形成する為に
必要なその他のライブラリを合体させて、実際にPCで動作させることが出来る
拡張子が『exe』実行可能ファイルの生成を行っています。

 『link』が、2行目で作成した『オブジェクトファイル』Windowsアプリケーションの動作に
必須ライブラリファイルDirectXの機能を使うために必要なライブラリファイル等を
融合させる機能を持つアプリケーションのファイル名です。(cl『コンパイラ』link『リンカ』)

 『/SUBYSYTEM:WINDOWS』『Windows上で動くアプリケーションを作りますよ~』というオプション
 『OUT:pixel.exe』『作成する実行可能ファイルの名前は「pixel.exe」にして下さい』というオプション
 そしてその後ろにある沢山のファイル名は、全部実行可能ファイルを作成するために合体させるファイルです。
pixel.obj は2行目で作成した『オブジェクトファイル』で、その後ろの『kernel32.lib user32.lib gdi32.lib
shell32.lib ole32.lib advapi32.lib』
は、Windows上で動作するアプリケーションで必要な機能を
提供する『ライブラリファイル』です。
(『LIB』という名前の『環境変数』設定したフォルダ(『Microsoft Platform SDK』の中)にあります)
 リンクするこれ等のファイルは、作成する アプリケーションの内容によって若干数が変わったり
ファイルが変わったり
しますが、DXライブラリを使う時は必ず上記の6つとなります。
 そして、この行のコマンドが無事実行されれば実行可能ファイルが生成されます。

 4行目の『pause』はキー入力が行われるまで待つというコマンドです。
 『バッチファイル』は、そこに書かれたコマンドがすべて終了するといきなり実行結果を示す
ウインドウが閉じてしまうので、ここでキー入力が行われるまで処理をストップしてじっくり
実行結果を見れるようにしているわけです。


 説明が長くなってしまいましたが、早速このバッチファイルを実行してみましょう。
 バッチファイルの実行は普通のソフトのようにダブルクリックで行います。
 というわけで、『compile.bat』をダブルクリックで起動してみてください。

 ・・・どうでしょう?上手くいけば真っ黒のウインドウに次のような出力がされると思います。


C:\test>call setvctk.bat C:\test>SET PFSDK=C:\Program Files\Microsoft Platform SDK C:\test>SET VCTK=C:\Program Files\Microsoft Visual C++ Toolkit 2003 C:\test>SET DXLIB=C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用 C:\test>SET PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;C:\Program Files\Microsoft Platform SDK\Bin;C:\Program Files\Microsoft Platform SDK\Bin\Win64;C:\WINDOWS\system32;C:\WINDOWS; C:\test>SET INCLUDE=C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;C:\Program Files\Microsoft Platform SDK\Include;C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用 C:\test>SET LIB=C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;C:\Program Files\Microsoft Platform SDK\Lib;C:\DxLib_VC\プロジェクトに追加すべきファイル_VC用 C:\test>cl /c /W3 /O2 pixel.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 Copyright (C) Microsoft Corporation 1984-2002. All rights reserved. pixel.cpp C:\test>link /SUBSYSTEM:WINDOWS /OUT:pixel.exe pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib Microsoft (R) Incremental Linker Version 7.10.3077 Copyright (C) Microsoft Corporation. All rights reserved. LINK : warning LNK4089: all references to 'ADVAPI32.dll' discarded by /OPT:REF C:\test>pause 続行するには何かキーを押してください . . .



 上記の表示には、『setvctk.bat』による『環境変数』の設定、cl コマンドによる pixel.cpp
コンパイル、link によるコンパイルされたオブジェクトファイルとアプリケーション生成に
必要なライブラリファイルとのリンク等、アプリケーション構築の全ての過程の結果が
出力されています。

 プログラムに異常があったり、リンクに必要な情報が足りなかったりと何らかのエラーが
発生した場合もここにその旨が出力されます。(『○○のファイルの何行目にエラーがある』等。英語ですが(汗))
 そしてこの表示が消えないのは『pause』コマンドの効果、と言うわけです。(何かキーを押すとウインドウは閉じます)

 さて、コンパイルが完了したわけですが、もし上記と同じような表示がされていれば
コンパイルは成功です。

 コンパイルが成功していれば工程3で作成したフォルダの中に『pixel.obj』『pixel.exe』
が作成されているはずです。(『pixel.obj』『pixel.exe』を作るために生成されたものですので、
削除してしまっても問題ありません)
 そして、『pixel.exe』を実行すると、プログラムの通り画面の中心に点が一個描画されると思います。
 尚、もし『pixel.exe』が出来ていない場合は、何かしらのエラーが発生し、コンパイルが
正常に処理が終了しなかったということになりますので、その時は黒いウインドウに出力
されたエラー報告に従って原因を修正していくことになります。
(この解説に誤りがある可能性もありますので、上手く行かなかった方は掲示板までご連絡下さい。m(_ _)m)

 というわけで、プログラムを組み、実行する所まで出来ました。
 出来上がった『pixel.exe』は当然他のPCでも実行できる立派なアプリケーションです。
 尚、新しくアプリケーションを作成する場合は工程3から始める事になります。
(工程2までは2度行う必要はないので)

 さて、ここではまだDXライブラリの機能は初期化と後始末と、点を1個描画するくらいのもの
しか使っていません。
 このほかの関数はDXライブラリ関数リファレンスのページで解説されていますので、是非
そこに解説されている関数達を駆使して、頭に思い描くソフトウエアを具現化してみて下さい。






番外.Makeファイル

 プログラムに慣れてくると、自然とプログラムを複数のファイルに分けて組むようになります。
 複数のプログラムを工程5の方法でコンパイルする場合は、次のようなバッチファイルを
作成するわけですが・・・

例:pixel.cpp と box.cpp と main.cpp と global.h の4つのプログラムファイルで   ひとつのアプリケーション『graph.exe』を生成するバッチファイル
call setvctk.bat cl /c /W3 /O2 pixel.cpp cl /c /W3 /O2 box.cpp cl /c /W3 /O2 main.cpp link /SUBSYSTEM:WINDOWS /OUT:graph.exe box.obj main.obj pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib pause
(因みに cl する順序、link で書く obj ファイルの順番は何でも大丈夫です)  尚、プログラム自体は以下のようになっているとします。
// global.h #ifndef __GLOBAL__ #define __GLOBAL__ #include "DxLib.h" extern void DPixel( void ) ; // 点を描画する関数 extern void DBox( void ) ; // 四角形を描画する関数 #endif

// main.cpp #include "global.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { if( DxLib_Init() == -1 ) return -1 ; DPixel() ; // pixel.cpp の関数を呼ぶ DBox() ; // box.cpp の関数を呼ぶ WaitKey() ; DxLib_End() ; return 0 ; }

// pixel.cpp #include "global.h" // 点を打つ関数 void DPixel( void ) { DrawPixel( 320, 240, 0xffff ) ; }

// box.cpp #include "global.h" // 四角形を描画する関数 void DBox( void ) { DrawBox( 50, 50, 100, 100, 0xffff, FALSE ) ; }
 まず、『link』必要なファイルは拡張子が『obj』『オブジェクトファイル』です。
 そしてオブジェクトファイルは一回 cl でコンパイルして作成すれば何回も作る必要ありません

 そんな状況の中で、pixel.cppbox.cpp は正常にコンパイルが終了し、main.cpp
コンパイルエラーが発生したとします。(いえ、上記のプログラムにエラーはありませんが)

 当然 main.cpp で起きたエラーの原因を潰す訳ですが・・・というわけで、潰せたとします。

 main.cpp の修正が完了したのでもう一度このバッチファイルを起動します。

 すると既に正常にコンパイルが完了している pixel.cppbox.cpp のコンパイルが再度行われます。

 一つのプログラムのコンパイルは一瞬では終わりません。場合によっては数秒かかるでしょう。

 ・・・・。

 あ、修正できたと思った main.cpp でまたコンパイルエラーが起きました。また修正しなくてはなりません。

 修正が完了しました。というわけで再度このバッチファイルを実行。

 またコンパイルが完了している pixel.cppbox.cpp のコンパイルが始まります。

 ・・・・。

 そんな状況を目の当たりにして、きっと「ああ、pixel.cpp と box.cpp のコンパイルは
もう終わっているのに、無駄だ」と感じると思います。

 ですが、だからと言って修正したファイルだけをコンパイルするように一々バッチファイルを
書き換えてはこの作業をバッチファイルにした意味がありません。


 というわけで、そんな状況を打破するために存在するのが『Makeファイル』『Makeファイル』
を実行する為のソフトウエア『nmake』なのです。

 Makeファイルとは、バッチファイルのように実行したいコマンドを書き込んだテキスト形式
ファイルで、後から好きな時に『nmake』というソフトウエアで実行することが出来ます。(因みに拡張子は『mak』)
 一見バッチファイルのようですが、バッチファイルには出来なかった『必要の無いコンパイルはしない』
を実現することが出来ます。

 と、盛り上げた所でなんですが、『Makeファイル』はバッチファイルの様にダブルクリック
実行することは出来ませんので、使い時はやはりバッチファイルの力も借ります。

 ともあれ、早速『Makeファイル』見てみましょう。
 ここでは上記のバッチファイルの


cl /c /W3 /O2 pixel.cpp cl /c /W3 /O2 box.cpp cl /c /W3 /O2 main.cpp link /SUBSYSTEM:WINDOWS /OUT:graph.exe box.obj main.obj pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib


 この部分を『Makeファイル』化したいと思います。

 で、以下が『Makeファイル』で同様の処理を行うようにしたものです。


graph.exe: pixel.obj box.obj main.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib link /SUBSYSTEM:WINDOWS /OUT:graph.exe box.obj main.obj pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib pixel.obj: pixel.cpp cl /c /W3 /O2 pixel.cpp box.obj: box.cpp cl /c /W3 /O2 box.cpp main.obj: main.cpp cl /c /W3 /O2 main.cpp pixel.cpp: global.h box.cpp: global.h main.cpp: global.h global.h: DxLib.h


 とりあえずこれを『"graph.mak"』というファイル名で保存しておいてください。(尚、必ずダブル
コーテーション(")で囲ってください
)

 さて、これを『nmake』で実行すると、先程のように pixel.cppbox.cpp がコンパイルに
成功して、main.cpp だけがコンパイルに失敗して、再度コンパイルする羽目になったとしても、
『バッチファイル』の時のようにまた pixel.cppbox.cpp までコンパイルしてしまう
と言うことは無く、main.cpp だけをコンパイルしてくれます。

 その仕組みですが、まず Makeファイルの中身は、基本的には次のような書式ブロック
何個もあるような形態になっています。

目標(のファイル): 目標に依存するファイル1 [目標に依存するファイル2] ... [目標に依存するファイルn] [目標の達成に必要なコマンド]
 []で囲われているところは別に無くても問題が無い部分です。
 なんとなく、意味が分かると思います。

 とりあえず上記の Makeファイルを一番上から見ていきましょう


graph.exe: pixel.obj box.obj main.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib link /SUBSYSTEM:WINDOWS /OUT:graph.exe box.obj main.obj pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib


 いきなりすごいファイル数ですが。(汗)
 このブロックでは『目標』『graph.exe』『目標の依存するファイル』『pixel.obj』『box.obj』
『main.obj』
その他『~~.lib』『目標の達成に必要なコマンド』は下行の『link ~~』となっています。

 『graph.exe』を作成(達成)する為には『link~~』のコマンドを実行しなければいけません。
 そして『link~~』を実行するためには『pixel.obj』『box.obj』『main.obj』『~~.lib』の存在は不可欠。
つまり『pixel.obj』『box.obj』『main.obj』『~~.lib』『graph.exe』『依存』しているわけです。

 なんとなく、意味が分かると思います。


pixel.obj: pixel.cpp cl /c /W3 /O2 pixel.cpp box.obj: box.cpp cl /c /W3 /O2 box.cpp main.obj: main.cpp cl /c /W3 /O2 main.cpp


 このブロックでは『目標』『pixel.obj』『目標に依存するファイル』『pixel.cpp』
『目標の達成に必要なコマンド』は下の行の『cl /c /W3 /O2 pixel.cpp』になっています。
 この後の2ブロックも同じような感じです。


pixel.cpp: global.h box.cpp: global.h main.cpp: global.h global.h: DxLib.h


 『pixel.cpp』『global.h』『#include』しているので、『global.h』『依存』しています。
 後も同様にそれぞれ『#include』している関係として『依存』していると言えます。

 言えます、が、これらの『目標』達成(作成)するのはプログラマです。
 作成に何かコマンドが必要なわけではありません。必要なのはプログラマの能力です。
 コマンドが必要ないのでここでは依存関係が書かれているだけで、当然の如く
『目標の達成に必要なコマンド』は何も書かれていません。

 ではこれに一体何の意味があるのか、と言いますと、その答えは

   『nmake』が『目標の達成に必要なコマンド』を実行する条件

 の中にあります。


 まず『nmake』は起動すると、最初に Makeファイル一番上のブロックを見ます。
 そして、先程示した Makeファイル書式

目標(のファイル): 目標に依存するファイル1 [目標に依存するファイル2] ... [目標に依存するファイルn] [目標の達成に必要なコマンド]
 の、『目標の達成に必要なコマンド』を、次の条件のどれかが当てはまる場合だけ実行します。


   1. 『目標』(のファイル)が存在しない場合

   2. 『目標』より『更新日時』が新しい『目標に依存するファイル』が存在する場合

   3. 『目標に依存するファイル』以外の、『目標』に少しでも依存関係があるファイルの中に
     『目標』より『更新日時』が新しいファイルがあった場合

       その詳細は、『目標に依存するファイル』(①)『目標』として存在するブロックが存在し、
      且つそのブロック内の『目標に依存するファイル』の何れか一つでも『目標(そのブロックでの
      『目標』ではなく、①が『目標に依存するファイル』として存在するブロックの『目標』)
より
      『更新日時』が新しい場合。

       又はそのブロックに存在する『目標に依存するファイル』『目標』として存在する
      ブロックが存在し、且つそのブロック内の『目標に依存するファイル』の何れか一つでも『目標
      (そのブロックの『目標』ではなく、①が『目標に依存するファイル』として存在するブロックの
      『目標』
)』
より『更新日時』が新しい場合。

      (更にそのブロックで『目標に依存するファイル』『目標』として存在するブロックが存在する
      場合は、そのブロックの『目標に依存するファイル』とも『更新日時』の比較を行う、この調子で
      『目標に依存するファイル』『目標』として存在するブロックが一つもなくなって始めてこの判断
      は終了する)


 条件は最初に判定出来ますが、条件を判定するには一番上のブロック
『目標に依存するファイル』として書かれているファイルが『目標』として存在するブロックが
在るかどうかを調べる必要があります。

 そして一番上のブロック『目標に依存するファイル』だったファイルが『目標』として
存在するブロックが在った場合は、そこでも上記の条件でそのブロックにおける
『目標の達成に必要なコマンド』を実行するかどうかを判断し、条件が当てはまる場合は実行します。
(更にそのブロックの『目標に依存するファイル』『目標』として存在するブロックが在った
場合は、そのブロックについても同様の処理が行われます)

 という条件を前提に『目標達成に必要なコマンド』が存在しないブロックの存在意義を
考えてみると、『目標の達成に必要なコマンド』がないブロックでも、そのブロックで『目標』
としているファイルが何処か別のブロックで『目標に依存するファイル』として使われていれば、
そのブロックがコンパイルするかどうかの判定に影響を与えているということが分かります。

 例えば、『DxLib.h』が一文字でも更新されると、すべてのプログラムファイルが再度コンパイルされ、
『graph.exe』も作成され直されます。
 逆に、『global.h: DxLib.h』と書かれたブロックが無いと 『DxLib.h』が書き換えられても『nmake』
『再コンパイルが必要』という判断をどのブロックにも下しません。
(なので、『#include』を増やしたらMakeファイルも忘れずに更新する必要があります)


 さて、長くなってしまいましたが、この Makeファイルを使った方法にバッチファイルを書き換えて見ましょう。
 バッチファイルの中身は Makeファイルを使う前は


call setvctk.bat cl /c /W3 /O2 pixel.cpp cl /c /W3 /O2 box.cpp cl /c /W3 /O2 main.cpp link /SUBSYSTEM:WINDOWS /OUT:graph.exe box.obj main.obj pixel.obj kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib advapi32.lib pause


 でしたが、これを Makeファイルを使ったものに書き直すと
 
call setvctk.bat nmake -f graph.mak pause


 となります。(『nmake -f graph.mak』Makeファイル『graph.mak』を実行しているところです)
 実行してみると、一番最初は変更前と変わらずすべてのプログラムファイルをコンパイル
すると思いますが、後から3つあるプログラムファイルの内の一つを書き直したからと言って、
変更前のバッチファイルの様に3つのプログラム全部を再度コンパイルしてしまう、なんてことは
なくなります。

 まあ、3つ程度でしたらその都度コンパイルしてもいいかもしれませんが、後々数十個の
プログラムファイル扱うようになったりすると、一部のプログラムを書き換えただけで全部の
プログラムが再度コンパイルされる位だったら、ちょっと苦労してでも Makeファイル
書いた方が良い、と言う風になります。(^^;

 さて、ここでは Makeファイルの書き方の本当に基礎的なことしか書いていません。
 ここに書かれていない機能を利用すれば、もっと少ないテキスト量でも同様の効果が
得られる Makeファイルを作ることが出来ますので、興味がありましたら是非調べてみてください。



戻る