-
Notifications
You must be signed in to change notification settings - Fork 2
/
makefile1.txt
188 lines (121 loc) · 4.57 KB
/
makefile1.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
makefile是一种作为脚本来运行的存在 设定一些编译的规则和方法
preprocessing预编译:
1.头文件的包含
2.扩展宏定义
3.条件编译的选择
gcc -E name.c -o name.i/gcc -E name.c
cpp
Compilation编译:
1.词法分析语法分析
2.代码优化 存储分配 代码生成
.c/.h ---> .s汇编语言
gcc -S name.i -o name.s
cc -S
Assembly汇编:
1.代码段code存放程序指令
2.数据段data存放程序要用的各种全局变量和静态数据
.s ---> .o机器指令
gcc -c name.s -o name.o
as
Linking链接:
将相关文件相连形成一个可执行的统一整体
.o ---> .exe
gcc name.o -o name
ld
ONE_SHOT_MAKEFILE=$M make -C $T all_modules $@,
ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS all_modules $ARGS
makefile规则:
TARGET...:Prerequisites...
command
...
...
target:object file/.exe/label
prerequisites:生成target所需的依赖文件或目标
command:make要执行的命令/shell指令
在非android源码的环境下,就一般的linux普通文件目录中,编译了一个makefile,想执行输出,文件名必须为Makefile,类型也必须是mk,然后在该目录下执行make命令即可。
e.g.
obj = main.o kdb.o ... utils.o
edit: $(obj)
cc -o edit $(obj)
main.o: main.c defs.h
cc -c main.c
…
…
utils.o: utils.c defs.h
cc -c utils.c
clean: #clean目标被定义为伪目标 当make clean时 执行rm edit $(obj)的操作
rm edit $(obj)
变量:
1.递归展开变量:obj=main.o kbd.o ... utils.o
引用:edit:$(obj)
2.直接展开变量:obj:=..... 被定义时即直接使用
3.条件赋值:x?= bar 若x为未定义的则x=bar 否则x值不变
4.追加赋值:x+= goo 根据x的定义来确定是递归展开还是直接展开
自动化的变量:$< 规则中的第一个依赖文件, $@ 规则中的target名, $? 比目标文件新的依赖文件列表,
$* 在模式规则和静态模式规则中代表‘茎’, $^ 规则依赖文件列表不含重复文件, $+ 规则依赖文件列表包含重复的,
$% 目标是一个静态库文件时,代表静态库的一个成员名
($引用makefile内变量 $$引用shell内变量)
条件判断:
ifeq用于判断两值是否相等,ifdef判断变量是否定义
if() 第一种
~
endif
if() 第二种
~
else
~
endif
e.g.
~
foo:$(obj)
ifeq($(hx),gcc) 判断变量$(hx)是否是gcc eq代表后面条件判断是两个数值是否相等 eq==equal
$(hx) -o foo $(obj) $(libs)
else
$(hx) -o foo $(obj) $(other_libs)
endif
函数:
定义:
define <func_name>
...
endef
调用:
$(function_name arg1,arg2...)
$(subst from,to,text) 把字符串test中的‘from’字符换成‘to’字符
$(subst ,*,my name is stan) ---> output: my*name*is*stan
常见的内置函数:
make的自动推导
例如找到一个.o文件会自动把.c文件添加到依赖关系中,相应的编译命令也会被推导出来
make规则的e.g.可以改为如下:标记的部分因为make可以自动推导的方式所以可以删掉
e.g.
obj = main.o kdb.o ... utils.o
edit: $(obj)
cc -o edit $(obj)
main.o: main.c defs.h
cc -c main.c
…
…
utils.o: utils.c defs.h
cc -c utils.c
clean:
rm edit $(obj)
引用其他的makefile
include<filename>
filename可以使当前系统shell的文件模式或者包含路径和通配符
<<<<<<< HEAD:makefile1.txt
makefile常见的伪目标定义:
=======
makefile常见的为目标定义:
.PHONY 本身就是伪的意思
规则所定义的命令不是去创建目标文件而是去执行一个特定的命令,例如clean,讲一个target定义为伪目标后,make在执行规则时不会去试图查找隐含的规则来创建它。
也不用担心target和某一个文件重名而发生不能运行的情况。一般情况下,一个伪目标不作为另一个目标的依赖。当一个伪目标没有作为任何目标的依赖时,
我们只能通过make命令来明确指定它为make的终极目标,来执行它所在规则所定义的命令。
all:p1 p2 p3 #一般作为将所有程序重建而存在
p1:p1.c
p2:p2.c
p3:p3.c
>>>>>>> week3:makefile1.txt
make -jN make的并发执行,N代表并发执行的数量
makefile里的@符号:
在cmd前面的@表示取消回显,不显示源命令,加多个@和一个@效果都是一样的
$@ 是代表:左边的目标文件
$(Q)@ 表示什么都不做,等同于注释掉