コンテンツにスキップ

Makefile

基本的な文法

インデントは必ずタブ文字で行う。さもないとエラーが出て動かない。

1
2
3
4
{ターゲット}: {依存ターゲット1} {依存ターゲット2} ...
    {ターゲットのコマンド1}
    {ターゲットのコマンド2}
    ...

以下は例である。

1
2
3
4
5
6
7
.PHONY: write

bin/main.hex: src/main.asm  # bin/main.hexを作成するにはsrc/main.asmが必要
    avra -o bin/main.hex src/main.asm   # bin/main.hexを作成するコマンド

write: bin/main.hex # writeを実行するにはbin/main.hexが必要
    avrdude -c usbasp -p m328p -P usb -U flash:w:"bin/main.hex":i   # writeの具体的なコマンド

上記の Makefile があるディレクトリ上でmake writeを実行すると以下のような流れで動作する

  1. ターゲットwriteを確認する
  2. ターゲットwriteにはターゲットbin/main.hexが必要であると分かる
  3. ターゲットbin/main.hexを確認する
  4. ターゲットbin/main.hexにはターゲットsrc/main.asmが必要であると分かる
  5. ターゲットsrc/main.asmの記述は Makefile にないので、ファイルを確認する
  6. ファイルsrc/main.asmのタイムスタンプが更新されている場合、ターゲットbin/main.hexのコマンド(avra ...)を実行する
  7. ターゲットbin/main.hexが用意できたのでターゲットwriteのコマンド(avrdude ...)を実行する

.PHONY

ファイル名でないターゲットは.PHONYを記述すること。

.PHONYで定義したターゲットは疑似ターゲットとなる。通常のターゲットはタイムスタンプにより作成をスキップされることがあるが、疑似ターゲットは常に実行される。

マクロ

マクロ 説明
$@ ターゲット名
$^ 依存ファイルのリスト
$< 最初の依存ファイル
Makefile
1
2
3
4
obj/%.o: src/%.c
    echo $< # 例: src/main.c
    echo $@ # 例: src/main.o
    gcc -c $< -o $@

ソースファイル一覧・オブジェクトファイル一覧を得る

Makefile
1
2
3
4
5
6
7
8
9
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
SRC_FILES = $(shell echo ${SRC_DIR}/*.c)
OBJ_FILES = $(shell echo ${OBJ_DIR}/*.o)

run:
    echo ${SRC_FILES}
    echo ${OBJ_FILES}
1
2
3
4
5
$ make run
echo src/main.c
src/main.c
echo obj/main.o
obj/main.o

応用例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
bin/$(TARGET).hex: src/$(TARGET).asm
    avra -o $@ -e bin/$(TARGET).eep.hex -d obj/$(TARGET).obj $^

build: bin/$(TARGET).hex

write: bin/$(TARGET).hex
    avrdude -c usbasp -p m328p -P usb -U flash:w:"$^":i

dev: build write

clear:
    avrdude -c usbasp -p m328p -e

clean:
    rm obj/*.obj
    rm bin/*.hex

参考

Makefile の解説

Makefile でワイルドカードを使う方法 - nao-bamboo の日記