data/method/一些思考/常用/Makefile.txt

153 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

规则:
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的值为222VAR_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 $@ $<