Tips No.3 - Saturday, 08-Jun-2002 23:01:27 JST
■back ■index
 


 

■Makefileの作成方法 - 基礎辺

 
   
 

■前置き

どうもMakefileを作る機会が着そうなのでMakefileの書き方について
復習をしておこうと思います。

Makefileといえば大昔のMS-DOS時代に
Cやアセンブラのプログラムを組んだ時に使って以来・・・、
そもそもなんでMakefileなのかといえばまたCやアセンブラとかいわないが
RADツールなしで、ゴリゴリプログラムを書くことになったためである

別に懐かしくなったからというわけではない。

■簡単なMakefile

簡単な例として、

test1.c test2.c test1.h test2.h common.h

というファイルをコンパイルしてext.exeという出力ファイルを作ろうとした場合
のMakefileを、とりあえず見たままの関係で簡単に書いてしまうと
以下のような感じになります。


000001| test.exe : test1.obj test2.obj
000002|     link test.exe test1.obj test2.obj
000003|     
000004| test1.obj : test1.c
000005|     cl test1.c
000006|     
000007| test2.obj : test2.c
000008|     cl test2.c
000009|     
000010| test1.c : test1.h common.h
000011| test2.c : test2.h common.h

といった感じになる。

意味としては存関係と生成コマンドから成り立っている

test.exe : test1.obj test2.obj の行は

test.exeはtest1.objとtest2.objに依存していて、生成するためのコマンドが

link test.exe test1.obj test2.obj

であることを表している。

以下それぞれのobjファイルも、ソースに依存していて
コンパイルはそれぞれ以下のようなコマンドで行うという感じである

cl test1.c
cl test2.c

これで、それぞれのobjファイルが生成される。

最後の2行はソースとヘッダファイルの依存関係の記述である、
このように記述しておくとヘッダファイルにだけ更新があった場合に
メイクを行うと、ソースファイルが再コンパイルされるわけである。

ターゲット : 依存ファイル
       生成コマンド

これがMakefileの基本である、Makeコマンドはファイルの上から順にターゲットを
処理していくが、このときに依存ファイルがなければ、さらに下のほうを参照し
必要なファイルを生成してから、ターゲットファイルの生成を行う

これが基本的な流れである。
仮に依存ファイルがなかったり生成時にエラーが起きた場合はそこで終了する。

今回はライブラリも無いしオプションも無いので簡単なもんだ。

 

 

 

■Makefileの作成方法 - 発展辺

 
   
 

■基本的には

正直、Makefileを書くだけなら実はこれでいいといえばいい
しかしたとえばファイル数が増えてきた場合や追加する場合大変面倒である

そこで「サフィックスルール」というものを使用すると
記述量を減らすことが可能である

■サフィックスルール

サフィックスルールとはサフィックスxのファイルはcommandというコマンドを使って
サフィックスyのファイルを生成するという命令を表す。
用語が謎かもしれないが、つまり拡張子のことだと考えてしまえばいい

書式 : x y : command

これではよくわからないので、わかりやすい例を書くと

@サフィックスルールの例


.c .obj :
	cl $<

$<というのはマクロで、コマンド実行時に対象としているファイル名を表す
つまり.cのファイルはcl fileコマンドで
.objのファイルにコンパイルすることを この場合は表している

たとえばjavaなら

@Javaの例


.java .class :
	javac $<

等と書くのだが、
このサフィックスは事前に何パターンか登録されていて たとえば
.javaや.classは自分で任意に登録してやる必要がある

その書式は

.SUFFIXES: .java .class

のような記述を事前に書いておく必要がある
これによりこの拡張子ははサフィックスとして処理しますよということになる

ちなみにサフィックスは依存関係は起こらないので、
ファイルの更新の依存関係は別個個別に書いておかなければならない。

だから、書く量を減らす程度の扱い

■マクロ

ほかにはMakefileでは簡単なマクロが使える

たとえばコンパイラやリンカの指定やターゲットファイル名の指定などに良く使われる
記述方法は

マクロ名 = 名前

というように書き、マクロの値を参照するときは

$(マクロ名)か${マクロ名}

と記述する

最初の例の場合に場合に適用させてみると

@マクロの例


CC = cl.exe
LINK = link.exe
TARGET = test.exe
OBJS = test1.obj test2.obj

TARGET : OBJS
	$(LINK) $(TARGET) $(OBJS)
	
.c.obj : 
	$(CC) $<

といった感じでしょうかね
書き忘れてましたが、名前の中で別のマクロをさらに参照することも可能です

OBJ2= $(OBJ) test3.obj test4.obj

といった感じ。

マクロには特殊なのがいくつかありまして

"$@" ターゲット名を表す
"$<" 生成コマンドで依存しているファイルの一つを示す
"$*" ターゲット名からサフィックスを除いたものを示す
"$?" 依存ファイルで更新があったものを示す

まあ、こんなところで大体普通のメイクファイルは書けるかな?
ほかにも高度な?というか、技巧的な手法がいろいろ在るけど
ふつうのMakeFileはこれで作れる。

配布を考えるようなMakefileは、直接手で書くより
Makefileを自動生成するための手法があってそっちを使う方がよい

 

 

色々メモ - 鴨屋敷 1999-2002 by 矢鴨 kamo@7cho-me.com
■back ■index