Linux C编程一站式学习 (akaedu.github.io)
22. Makefile基础
1.基本规则
欲更新目标,必须首先更新它的所有条件;
所有条件中只要有一个条件被更新了,目标也必须随之被更新。
“更新”:执行一遍规则中的命令列表,命令列表中的每条命令必须以一个Tab开头
对于Makefile中的每个以Tab开头的命令,make会创建一个Shell进程去执行它
#target ... : prerequisites
# command1
# command2
# …
main: main.o stack.o maze.o
gcc main.o stack.o maze.o-o main
# main.o stack.o maze.o发生改变则更新可执行文件main
main.o: main.c main.h stack.h maze.h
gcc -c main.c
# main.c main.h stack.h maze.h改变则编译main.c生成main.o
stack.o: stack.c stack.h main.h
gcc -c stack.c
# stack.cstack.hmain.h改变则编译stack.c生成stack.o
maze.o:maze.c maze.hmain.h
gcc -c maze.c
# maze.c maze.h main.h改变则编译maze.c生成maze.0
# 如果编译之后又对maze.c做了修改,又要把所有源文件编译一遍
# 即使main.c、stack.c和那些头文件都没有修改也要跟着重新编译。
# 一个大型的软件项目往往由上干个源文件组成,全部编译一遍需要几个小时
# 只改一个源文件就要求全部重新编译肯定是不合理的。
目标属于以下情况之一,就称为需要更新:
1.目标没有生成。
2.某个条件需要更新。
3.某个条件的修改时间比目标晚。
make执行的命令前面加了@字符,则不显示命令本身而只显示它的结果
通常make执行的命令如果出错(该命令的退出状态非0)就立刻终止,不再执行后续命令
但如果命令前面加了-号,即使这条命令出错,make也会继续执行后续命令
- rm和mkdir都有可能出错,但这种错误是应该忽略的
约定俗成的目标名字有:
all,执行主要的编译工作,通常用作缺省目标。
install,执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。
clean,删除编译生成的二进制文件。
distclean,不仅删除编译生成的二进制文件,也删除其它生成的文件
2.隐含规则和模式规则
一个目标依赖的所有条件不一定非得写在一条规则中,也可以拆开写
此时只有一条规则允许有命令列表,其它规则应该没有命令列表
一个目标在Makefile中的所有规则都没有命令列表,make会尝试在内建的隐含规则(Implicit Rule)数据库(可以用make -p命令打印)中查找适用的规则
例如配置文件和格式转换后的文档,执行make distclean之后应该清除所有这些文件,只留下源文件
# default
OUTPUT_OPTION = -o $@
# default
CC = cc
# default
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
%.o: %.c #模式规则(Pattern Rule)
# commands to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(CFLAGS)
展开是空,CPPFLAGS
和TARGET_ARCH
也是如此。
这样$(COMPILE.c)
展开应该是cc␣空␣空␣空␣-c
,去掉所有的“空”得到cc␣␣␣␣-c
注意中间留下4个空格
所以%.o: %.c
规则的命令$(COMPILE.c)␣$(OUTPUT_OPTION)␣$<
展开之后是cc␣␣␣␣-c␣-o␣$@␣$<
$@
的取值为规则中的目标
$<
的取值为规则中的第一个条件
翻译后如下!
main.o: main.c
cc -c -o main.o main.c
以条件为中心,Makefile还可以这么写(只要把所有的依赖关系都描述清楚了就行)
main: main.o stack.o maze.o
gcc main.o stack.o maze.o -o main
main.o stack.o maze.o: main.h
main.o maze.o: maze.h
main.o stack.o: stack.h
clean:
-rm main *.o
.PHONY: clean
多目标的规则,make会拆成几条单目标的规则来处理
target1 target2: prerequisite1 prerequisite2
command $< -o $@
展开如下
target1: prerequisite1 prerequisite2
command prerequisite1 -o target1
target2: prerequisite1 prerequisite2
command prerequisite1 -o target2
标签:命令,规则,C语言,编译,part2,Linux,maze,main,stack
From: https://www.cnblogs.com/asandstar/p/18092139