makefile的使用
make是Linux内置指令,makefile是工程师自己要创建的文件。makefile为常用的工具,本文章从代码入手,学习makefile的用法,并理解其原理。
直接书写代码观察现象
-
在当前目录创建
code.c文件和makefile文件 -
使用
makefile书写gcc编译链接code.c过程 -
!!!一定要注意,实例代码中的
gcc开头的空,是tab键,不是tab会报错code:code.o gcc -o code code.o code.o:code.s gcc -o code.o -c code.s code.s:code.i gcc -o code.s -S code.i code.i:code.c gcc -o code.i -E code.c .PHONY:clean clean: rm -f code.i code.s code.o code -
使用
makefile- ``shell
中输入make指令,发现shell出现对应指令,生成code.i code.s code.o code`文件 shell中再次输入make指令,发现提示文件已经是最新- 修改
code.c文件,再次输入make指令,发现系统会再次编译链接 shell中输入make clean指令,发现shell出现对应指令,code.i code.s code.o code文件被删除shell中再次输入make clean指令,发现shell出现对应指令
- ``shell
代码原理讲解
-
在
shell中输入make指令,会自动运行当前文件夹makefile或Makefile的内容。(makefile和Makefile只是文件名字不同,使用时没有任何差异,按自己喜好命名即可) -
以
code:code.o为例,我们把:左边的称为目标文件,右边的称为依赖文件列表,code:code.o叫做依赖关系。gcc -o code code.o叫做依赖方法。 -
makefile根据依赖关系进行正向解析,解析过程把依赖方法依次入栈,解析到出口后依次出栈,具体如下:makefile拥有自动推导的功能,输入make后,发现code的依赖文件code.o不存在,把gcc -o code code.o入栈,向下寻找code.o的依赖;发现没有code.o的依赖文件code.s,把gcc -o code.o -c code.s入栈……直到发现有code.i的依赖文件code.c,执行gcc -o code.i -E code.c,依次出栈执行依赖方法,最终生成code.i code.s code.o code
-
指令回显:
- 想要取消指令回显,只需要在指令开始处加上
@即可
- 想要取消指令回显,只需要在指令开始处加上
-
shell中再次输入make指令,发现提示文件已经是最新——解释-
一个工程通常由数十上百个文件,如果只是修改其中一个文件,再把所有文件重新编译链接,有些太费时间。
makefile为了提升编译链接的效率,会确认目标文件是否是最新的,如果是最新的就不会再进行依赖方法。那么,makefile是如何确定文件是否是最新的呢?-
我们首先要知道,文件的属性包括了文件的ACM——Access Change Modify。在修改文件内容时,Change Modify时间会改变;在修改文件权限、所属关系时,Change改变,Modify不变
-
对比目标文件和依赖文件的时间,如果目标文件Modify比依赖文件Modify早,会判定其不是最新的,反之则是最新的。
-

-
-
.PHONY.PHONY会创建伪目标,伪目标总是被执行的,无视上文所说判断更新的规则- 为防止删不彻底,删除时通常使用伪目标
代码书写
下文设置变量,工程化规范性书写makefile文件
BIN=code
CC=gcc
LFLAG=-o
CFLAG=-c
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
RM=rm -f
$(BIN):$(OBJ)
@$(CC) $(LFLAG) $@ $^
@echo "链接$^成为$@"
%.o:%.c
@$(CC) $(CFLAG) $<
@echo "编译$<成为$@"
.PHONY:clean
clean:
@$(RM) $(OBJ) $(BIN)
@echo "清理工作完毕"
.PHONY:print
print:
@echo $(SRC)
@echo "-----------------"
@echo $(OBJ)
-
$解析变量
-
@表示目标文件
-
^表示依赖文件列表
-
SRC=$(wildcard *.c)表示当前路径所有
*.c文件 -
OBJ=$(SRC:.c=.o)表示当前路径所有
*.o文件 -
%.o:%.c @$(CC) $(CFLAG) $< @echo "编译$<成为$@"负责把当前文件夹所有
*.c文件编译生成对应*.o文件

被折叠的 条评论
为什么被折叠?



