makefile の書き方 (2/2)

« 前の記事 [makefile とは?なぜ便利なのか?]

makefile の書き方

makefile の書き方はいろいろあり、ここでそれを全部説明することはできません。今後必要に応じて説明します。 ここでは、上記のビルドプロセスに対する makefile を記述します。

先に、出来上がりをみてください。解説はコメントとして記載しています。


TARGETNAME=test # 出来上がりの exe ファイル名を指定します
OUTDIR=.\chk # ビルドプロセスで生成される中間ファイル等の出力先
LINK32=link.exe # リンカコマンド

# $(OUTDIR) と $(TARGETNAME) は 上で指定した値に置き換えられます. 従って、
# $(OUTDIR)\$(TARGETNAME) は .\chk\test.exe になります。
# この makefile はこれを作るためのものであることを示しています。
 
ALL : $(OUTDIR)\$(TARGETNAME).exe 

# 次は clean というカスタムのオプションを作っています (後述)。
# nmake clean で -@erase の行が実行されます。


CLEAN :
	-@erase /Q $(OUTDIR)\*


# 次の行は $(OUTDIR) すなわち .\chk というディレクトリが無かった場合、
# そのディレクトリを作ります。

$(OUTDIR) :
	@if not exist $(OUTDIR)/$(NULL) mkdir $(OUTDIR)


# 以下はコンパイラオプションです。\ で改行しています。一行に書いてもかまいません。

CPPFLAGS=\
	/nologo\
	/W4\
	/Fo"$(OUTDIR)\\"\
	/Fd"$(OUTDIR)\\"\
	/c\
	/Zi\
	/D_WIN32_WINNT=0x0600\
	/DUNICODE\
	/D_UNICODE

# 次はリンカオプションです。\ で改行しています。一行に書いてもかまいません。

LINK32_FLAGS=\
	advapi32.lib\
	/nologo\
	/subsystem:console\
	/pdb:"$(OUTDIR)\$(TARGETNAME).pdb"\
	/machine:I386\
	/out:"$(OUTDIR)\$(TARGETNAME).exe"\
	/DEBUG
	
# リンクに使うオブジェクトファイル名を列挙します。
# ここでは test.cpp と username.cpp から test.obj と username.obj が
# 生成され、それらをリンクすることを考えています。

LINK32_OBJS=\
	$(OUTDIR)\$(TARGETNAME).obj\
	$(OUTDIR)\username.obj


# 次の行で、.\chk\test.exe が OUTDIR とオブジェクトファイルに依存していることを
# 記載しています。依存ファイルに変更があった場合には、その部分がコンパイルしなおされます。

$(OUTDIR)\$(TARGETNAME).exe : $(OUTDIR) $(LINK32_OBJS)
	$(LINK32) $(LINK32_FLAGS) $(LINK32_OBJS)

# .\chk にある .obj ファイルは .cpp から作られることを示しています。
# $< は「変更のあったファイル」をあらわします。
# もしコンパイルしなおす必要がある場合には、$(CPP) = cl.exe に $(CPPFLAGS) で指定した
# オプションを渡してコンパイルしなおされます。

.cpp{$(OUTDIR)}.obj:
	$(CPP) $(CPPFLAGS) $<

この内容を makefile という名前のファイルに保存してください。拡張子なしで makefile という名前のテキストファイルを作ればよいのです。

メイクファイルを makefile という名前で保存できない場合は、-f オプションを指定することによって、nmake にメイクファイルの内容を読み込ませることができます。

例えば foo.mak という名前でメイクファイルを作成した場合、 コマンドは nmake -f foo.mak というコマンドを実行すればよいです。

通常は makefile (拡張子なし) という名前で保存しましょう。

そして次のように nmake コマンドを実行します。

> nmake

Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        if not exist .\chk/ mkdir .\chk
        cl  /nologo /W4 /Fo".\chk\\" /Fd".\chk\\" /c /Zi /D_WIN32_WINNT=0x0600 
/DUNICODE /D_UNICODE test.cpp
test.cpp
test.cpp(6) : warning C4100: 'argv' : unreferenced formal parameter
test.cpp(6) : warning C4100: 'argc' : unreferenced formal parameter
        cl  /nologo /W4 /Fo".\chk\\" /Fd".\chk\\" /c /Zi /D_WIN32_WINNT=0x0600 
/DUNICODE /D_UNICODE username.cpp
username.cpp
        link.exe  advapi32.lib /nologo /subsystem:console /pdb:".\chk\test.pdb" 
/machine:I386 /out:".\chk\test.exe" /DEBUG  
.\chk\test.obj .\chk\username.obj

nmake コマンドは makefile を読み込み、その内容に従って、cl コマンドと link コマンドを実行します。 もしかしたら、以下のような出力だけが見え、何も実行されないかもしれません。

> nmake

Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.

これは前回ビルドしたときからソースファイルの内容が更新されておらず、 ビルドしなおす必要が無いためです。

強制的にリビルドする場合には /A オプションをつけて、nmake を実行します。 (nmake のオプションは / または - で指定します。従って /A は -A や -a でも構いません)

> nmake -a

ざっと makefile の書き方を見てきました。

当サイトでは基本的に、Visual Studio のプロジェクトファイルを使わずになるべく ソースコードと makefile を示し、 nmake でビルド可能にしています。

他のサンプルが欲しい方は、あちこち覗いてみてくださいね。
... ま、だいたい似たり寄ったりなのですが (苦笑)

« 前の記事 次の記事 »
よく使うコンパイル・リンカオプション 開発環境・ビルド編 - 目次

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。