Makefiles
Makefiles tutorial
ref: https://makefiletutorial.com/
Getting started
Makefiles 是用来帮助我们决定在一个项目里那些文件需要被 compiled 的。以如下的 cpp 项目为例,如果任何一个文件的依赖发生了变化,文件都会被重新编译。
除了 Makefiles 之外,其替代品还有还有流行的编译工具比如说 Bazel。
Syntax
一个 Makefile 会有一些规则,通常看起来是如下的样子。
1 | targets: prerequisites |
- targets : 文件名,使用空格进行分隔。通常,每个 rule 只有一个。
- commands:commands 是通常用来 make targets 的一系列操作。需要以 tab 开头,而不是 spaces
- prerequisites:是为了 make targets 所需要的文件。
Beginner Example
some_file 运行的时候会先 check dependencies。clean 常被用来清除 make 的文件,但是并不是是 Make 的保留字。
1 | some_file: other_file |
多 targets 的 make
1 | all: one two three |
Variables
Makefile 的变量只能是 string,可以使用 $(variable) 或者 ${variable} 引用
1 | iles = file1 file2 |
Automatic variables and Wildcards
wildcard。* 可以在用来搜索所有匹配的文件名。建议永远将 * 放在 wildcards function 中,否则很容易出问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18thing_wrong := *.o # Don't do this! '*' will not get expanded
thing_right := $(wildcard *.o)
all: one two three four
# * 不要用在变量定义里
# Fails, because $(thing_wrong) is the string "*.o"
one: $(thing_wrong)
# 如果没有匹配到,就会是 *.o 的状态
# Stays as *.o if there are no files that match this pattern :(
two: *.o
# Works as you would expect! In this case, it does nothing.
three: $(thing_right)
# Same as rule three
four: $(wildcard *.o)
% wildcard。% 有很多丰富的用法,之后碰到了可以看:
Automatic Variables
- automatic variables ref: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17hey: one two
# Outputs "hey", since this is the first target
echo $@
# Outputs all prerequisites newer than the target
echo $?
# Outputs all prerequisites
echo $^
touch hey
one:
touch one
two:
touch two
Commands and execution
Commands Echoing/Sliencing
在命令之前加 “@”,使得当前的命令不 print。也可以用 -s 在每一行之前加 @
1 | all: |
Go Makefile ref
Examples
ref: https://github.com/protocolbuffers/protobuf/tree/master/examples
Protobuf example 里的 Go Makefile 可以作为参考
1 | go: add_person_go list_people_go |
1 | # 清理文件并 build proto,生成 go 的定义 |