makeコマンドの使い方(Makefile)

makeコマンドの使い方を解説します。makeコマンドは、主にソースファイルのコンパイルで活用されます。Makefileというファイルにビルドの依存関係を記述して利用します。

Hello World

まずは、簡単な例で動作確認します。

Makefile というファイルを作成して以下内容を記述します。

xxx:
	echo 'Hello World'

yyy:
	echo 'Good Bye'

xxx yyyターゲットと言います。makeコマンドを実行するときにターゲットを指定して実行します。ターゲットを指定せずに実行した場合、一番上にあるターゲットが実行されます。

$ ls
Makefile
$ 
$ make
echo 'Hello World'
Hello World
$ 
$ make xxx
echo 'Hello World'
Hello World
$ 
$ make yyy
echo 'Good Bye'
Good Bye
$ 
$ make xxx yyy
echo 'Hello World'
Hello World
echo 'Good Bye'
Good Bye

Makefileの書き方

基本書式

# コメント
ターゲット: 前提条件
	レシピ
	…
	…
  • 通常、ターゲットには、生成したいファイルを指定します。
  • 前提条件にはターゲットが依存するファイルを指定します。
  • レシピにはターゲットで指定したファイルを生成するためのコマンドを記述します。
    • レシピを記述するときは、コマンド前に タブ文字 を入れる必要があります。
    • もし、Makefile:xx: *** missing separator. Stop. といったエラーが発生した場合、タブ文字 になってない可能性があります。タブ文字 になっているか確認してください。
  • コメントは # の後に記述します。

動作確認

さきほどよりも少し複雑な例で動作確認します。Makefile に以下の内容を記述します。

# コメント
app.txt: sub1.txt sub2.txt
	cat sub1.txt sub2.txt > app.txt

sub1.txt: src1.txt
	cp -f src1.txt sub1.txt
	echo "hello sub1" >> sub1.txt
	@echo "wakuwaku" >> sub1.txt

sub2.txt: src2.txt
	cp -f src2.txt sub2.txt
	echo "hello sub2" >> sub2.txt
	@echo "bank" >> sub2.txt

.PHONY: clean
clean:
	rm -f app.txt sub1.txt sub2.txt
  • @echo "wakuwaku" >> sub1.txt のように先頭に @ をつけると、make実行時にコマンドが表示されなくなります。
  • cleanのようにファイルを生成せず、タスクだけ実行するターゲットも存在します。
    • .PHONY: clean と記述することにより、ターゲットがファイルを生成しないことを表しています。

makeコマンド実行前に、src1.txtsrc2.txt を作成しておいてください。

$ cat src1.txt 
hello src1
$ 
$ cat src2.txt 
hello src2
$ 
$ ls
Makefile        src1.txt        src2.txt

makeを実行します。

$ make
cp -f src1.txt sub1.txt
echo "hello sub1" >> sub1.txt
cp -f src2.txt sub2.txt
echo "hello sub2" >> sub2.txt
cat sub1.txt sub2.txt > app.txt

生成されたファイルを確認します。

$ ls
Makefile        app.txt         src1.txt        src2.txt        sub1.txt        sub2.txt
$ 
$ cat sub1.txt 
hello src1
hello sub1
wakuwaku
$ 
$ cat sub2.txt 
hello src2
hello sub2
bank
$ 
$ cat app.txt 
hello src1
hello sub1
wakuwaku
hello src2
hello sub2
bank

もう一度makeを実行します。

$ make
make: `app.txt' is up to date.

何も実行されません。makeは、依存ファイルとのファイル更新日時を比較することで、必要のないビルドを無駄にしないようになっています。

以下コマンドを実行して、src1.txt を更新します。

$ echo "hello src1 updated" > src1.txt 
$
$ cat src1.txt 
hello src1 updated

もう一度makeを実行します。

 $ make
cp -f src1.txt sub1.txt
echo "hello sub1" >> sub1.txt
cat sub1.txt sub2.txt > app.txt
$ 
$ cat app.txt 
hello src1 updated
hello sub1
wakuwaku
hello src2
hello sub2
bank

更新したファイル( src1.txt )に依存したビルドのみ行われました。

参考