153 lines
5.6 KiB
Plaintext
153 lines
5.6 KiB
Plaintext
规则:
|
||
1.make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
|
||
2.如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
|
||
3.如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
|
||
4.如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
|
||
5.当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生成make的终极任务,也就是执行文件edit了。
|
||
一、Makefile是什么?
|
||
Makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
|
||
二、Makefile的好处是什么?
|
||
自动化编译,一旦写好,只需要一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。
|
||
三、怎么用?
|
||
/*********************************
|
||
编译基础 :编译四步骤,预编译->编译->汇编->链接
|
||
1) 预编译
|
||
将.c 文件转化成 .i文件
|
||
使用的gcc命令是:gcc –E
|
||
2) 编译
|
||
将.c/.h文件转换成.s文件
|
||
使用的gcc命令是:gcc –S
|
||
3) 汇编
|
||
将.s 文件转化成 .o文件
|
||
使用的gcc 命令是:gcc –c
|
||
4) 链接
|
||
将.o文件转化成可执行程序
|
||
使用的gcc 命令是: gcc
|
||
*************************************/
|
||
规则
|
||
target ... : prerequisites ... //一条规则,以依赖项来生成最终目标
|
||
command //(重点)说白一点就是说,prerequisites中如果有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行
|
||
示例
|
||
edit : main.o kbd.o command.o display.o \ //edit依赖以下二进制文件
|
||
insert.o search.o files.o utils.o
|
||
cc -o edit main.o kbd.o command.o display.o \ //将以下汇编文件链接成edit这个可执行文件
|
||
insert.o search.o files.o utils.o
|
||
|
||
main.o : main.c defs.h //main.o文件依赖以下文件
|
||
cc -c main.c //将main.c文件按依赖项汇编成main.o文件
|
||
kbd.o : kbd.c defs.h command.h
|
||
cc -c kbd.c
|
||
command.o : command.c defs.h command.h
|
||
cc -c command.c
|
||
display.o : display.c defs.h buffer.h
|
||
cc -c display.c
|
||
insert.o : insert.c defs.h buffer.h
|
||
cc -c insert.c
|
||
search.o : search.c defs.h buffer.h
|
||
cc -c search.c
|
||
files.o : files.c defs.h buffer.h command.h
|
||
cc -c files.c
|
||
utils.o : utils.c defs.h
|
||
cc -c utils.c
|
||
clean :
|
||
rm edit main.o kbd.o command.o display.o \
|
||
insert.o search.o files.o utils.o
|
||
|
||
makefile 中使用变量
|
||
如:
|
||
objects = main.o kbd.o command.o display.o \
|
||
insert.o search.o files.o utils.o
|
||
就可以使用“$(objects)”的方式来使用这个变量了
|
||
|
||
让 make 自动推导
|
||
只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make
|
||
找到一个 whatever.o,那么 whatever.c,就会是 whatever.o 的依赖文件。并且 cc -c
|
||
whatever.c 也会被推导出来
|
||
于是可以写成这样
|
||
objects = main.o kbd.o command.o display.o \
|
||
insert.o search.o files.o utils.o
|
||
|
||
edit : $(objects)
|
||
cc -o edit $(objects)
|
||
|
||
main.o : defs.h
|
||
kbd.o : defs.h command.h
|
||
command.o : defs.h command.h
|
||
display.o : defs.h buffer.h
|
||
insert.o : defs.h buffer.h
|
||
search.o : defs.h buffer.h
|
||
files.o : defs.h buffer.h command.h
|
||
utils.o : defs.h
|
||
|
||
.PHONY : clean //“.PHONY”表示,clean是个伪目标文件。
|
||
clean :
|
||
rm edit $(objects)
|
||
|
||
进一步还可以写成以下这样
|
||
objects = main.o kbd.o command.o display.o \
|
||
insert.o search.o files.o utils.o
|
||
|
||
edit : $(objects)
|
||
cc -o edit $(objects)
|
||
|
||
$(objects) : defs.h
|
||
kbd.o command.o files.o : command.h
|
||
display.o insert.o search.o files.o : buffer.h
|
||
|
||
.PHONY : clean
|
||
clean :
|
||
rm edit $(objects)
|
||
|
||
清空目标文件的规则
|
||
一般的风格都是:
|
||
|
||
clean:
|
||
rm edit $(objects)
|
||
|
||
更为稳健的做法是:
|
||
|
||
.PHONY : clean
|
||
clean :
|
||
-rm edit $(objects) //在 rm 命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事
|
||
|
||
赋值符:
|
||
= 延时变量,只有被使用时才展开定义 //真实值为最后定义的
|
||
:= 立即变量,定义时的赋值立即有效 //真实值为立即定义的
|
||
?= 条件变量,当变量为空时才赋值
|
||
+= 追加赋值
|
||
示例:
|
||
VAR_A=abc
|
||
VAR_B=$(VAR_A) 222
|
||
VAR_C:=$(VAR_A)
|
||
VAR_A=def
|
||
#VAR_B的值会改变为def 222,而VAR_C的值还是为abc
|
||
|
||
VAR_A:=$(VAR_B)222
|
||
VAR_B=$(VAR_A)
|
||
#由于一开始VAR_B没有值,所以VAR_A的值为222,VAR_B的值为222
|
||
|
||
VAR_D=111
|
||
VAR_D?=000
|
||
#VAR_D的值仍为111
|
||
|
||
VAR_E=file1.c
|
||
VAR_E+= file2.c
|
||
#VAR_E最后的值为file1.c file2.c
|
||
#等价于:
|
||
VAR_E=$(VAR_E) file2.c
|
||
|
||
模式规则
|
||
通配符“%”和“*”
|
||
当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值,使用方
|
||
法如下:%.o : %.c
|
||
自动化变量
|
||
示例
|
||
test:test.o test1.o test2.o
|
||
gcc -o $@ $^
|
||
test.o:test.c test.h
|
||
gcc -o $@ $<
|
||
test1.o:test1.c test1.h
|
||
gcc -o $@ $<
|
||
test2.o:test2.c test2.h
|
||
gcc -o $@ $<
|