CPU+コンパイラ自作キャンプ/make入門
makeとMakefileを説明する
makeは英語で「作る」という意味
ソースコードから目的のファイルを「作る」
Makefileの例
code:verilog_practice/led_pattern/Makefile
SRCS = main.sv port.cst
TESTBENCH = main_tb.sv
include ../../scripts/common.mk
最初の2行は変数定義
SRCSとTESTBENCH
SRCSはSourcesのつもり。ソースコードを指定する。
TESTBENCHはシミュレーション用ファイル
最後の1行は、他のファイルをここに読み込むよ、という意味
「include ~」は「~を読み取ってここに貼り付けよ」という命令
多くの処理はcommon.mkに書いてある
led_pattern以外の回路についても使う共通の処理なので、何度も書かなくて済むようにしている。
common.mkの中身
common.mkの最初は変数定義
code:common.mkの最初
# Verilog のビルドで共通に用いる機能を定義する
commonmk_dir = $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
scripts_dir = $(commonmk_dir)
include $(scripts_dir)/user.env
GWSH = $(GWIDE_BINDIR)/gw_sh.exe
GWPROG = $(scripts_dir)/gw_prog.sh
MAKE_BUILD_TCL = $(scripts_dir)/make_build_tcl.sh
SRCS_HDL = $(filter %.v %.sv,$(SRCS))
後の処理で使う変数を定義
table:それぞれの変数の内容の例と意味
変数名 内容の例 意味
commonmk_dir ../../scripts includeされたファイルから見た、common.mkが置いてあるディレクトリへのパス
scripts_dir ../../scripts includeされたファイルから見た、cccamp/scriptsへのパス
GWSH /mnt/c/Gowin/Gowin_V1.9.10.02_x64/IDE/bin/gw_sh.exe gw_sh.exeへのパス
GWPROG ../../scripts/gw_prog.sh includeされたファイルから見た、gw_prog.shへのパス
common.mkの中盤はファイル生成ルール
code:common.mkの中盤
all: impl/pnr/project.fs
impl/pnr/project.fs: build.tcl Makefile
$(GWSH) build.tcl
build.tcl: $(SRCS) Makefile
$(MAKE_BUILD_TCL) $(SRCS) > build.tcl
sim.exe: $(TESTBENCH) $(SRCS_HDL) Makefile
iverilog -g2012 -o $@ $(TESTBENCH) $(SRCS_HDL)
4つの「ファイル生成ルール」
all、impl/pnr/project.fs、build.tcl、sim.exeを作るための手順が書かれている
allはちょっと特別で、allを作るための手順は何も書いてないけど。
料理で理解するMakefile
code:ルールの書き方
作りたいもの: 材料
レシピ
料理を作るのにたとえて理解しよう
卵焼きは、卵、だし、塩で作る
code:卵焼きのルール
卵焼き: 卵 だし 塩 手順書
卵を溶いて、だしと塩を混ぜる
フライパンを火にかけ、油をしく
フライパンに卵を入れて焼く
卵焼きを作れと言われたら、まずは材料を集める
もし冷蔵庫にあればいいけど、無かったら買いに行ったり、作ったりしないといけない
卵は、普通は買いに行くけど、鶏を飼って産ませるという方法もある
だしは、お店でも買えるし、昆布や鰹節を煮てもいい
塩は、普通は買いに行くけど、海水を煮詰めて手に入れることもできる
Makefileに卵やだし、塩を手に入れる方法が書いてあれば、それを実行する
code:だしを買う場合のルール
だし: お金 手順書
お店に行ってだしを買う
code:だしを作る場合のルール
だし: 鰹節 手順書
鍋に鰹節と水を入れる
火にかけて煮る
布で鰹節をこす
手に入れる方法が書いてないし冷蔵庫にもなければ、卵焼きを作ることはできない
makeの動作
makeコマンドはMakefileを読み、指示されたファイルを作っていく
単に$ makeとしたときは、一番最初に書いてあるファイルを作る
common.mkなら「all」が一番最初に書いてあるファイルだ!
makeの気持ちになって「all」を作る流れを考える
1. all: impl/pnr/project.fsなので、「all」を作るためには「impl/pnr/project.fs」が必要だ。
2. impl/pnr/project.fsは無いので、作らないといけないぞ!
3. impl/pnr/project.fs: build.tcl Makefileなので、「impl/pnr/project.fs」を作るためには「build.tcl」と「Makefile」が必要だ。
Makefileはもうある。だって、今読んでる手順書そのものだからね。
4. build.tclはないので、作らないといけないぞ!
5. build.tcl: $(SRCS) Makefileなので、「build.tcl」を作るためには「$(SRCS)」と「Makefile」が必要だ。
$(SRCS)は変数
SRCS = main.sv port.cstだ!
main.svとport.cstは作らなくてもあるぞ。よかった~
6. build.tclの材料が揃ったので、レシピ通りに作る。レシピは $(MAKE_BUILD_TCL) $(SRCS) > build.tcl だ。
7. build.tclが完成したのでimpl/pnr/project.fsも作れる。レシピは $(GWSH) build.tcl だ。
8. impl/pnr/project.fsが完成したのでallも作れる。レシピは空っぽ。何もしなくても完成だ!
common.mkの最後はファイル生成ルール
code:common.mkの最後
.PHONY: flash sram clean sim
flash: impl/pnr/project.fs Makefile
$(GWPROG) flash impl/pnr/project.fs
sram: impl/pnr/project.fs Makefile
$(GWPROG) sram impl/pnr/project.fs
clean: Makefile
rm -rf build.tcl impl sim.exe
sim: sim.exe Makefile
./sim.exe
ファイル生成ルールと書き方は同じだけど、実際のファイル名ではなくてコマンド名になっている
コマンド名:flash、sram、clean、sim
.PHONYに指定した名前は、ファイル名ではなくコマンド名ということになる