Makefile 的规则
target ... : prerequisites ...
command
target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签。
prerequisites 就是要生成那个 target 所需要的文件或是目标 。
command 也就是 make 需要执行的命令。(任意的 Shell 命令) 。
这是一个文件的依赖关系,也就是说,target 这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在 command 中。说白一点就是说,prerequisites中如果有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行。这就是 Makefile 的规则。也就是 Makefile 中最核心的内容。
make是如何工作的
在默认的方式下,也就是我们只输入make命令。那么,
- make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
- 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
- 如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
- 如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
- 当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生成make的终极任务,也就是执行文件edit了
GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。
只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么 whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile 再也不用写得这么复杂。
Makefile示例
include ../Make.defines #可以包含其他Makefile PROGS = daytimetcpcli daytimetcpcli1 daytimetcpcli2 daytimetcpcli3 \ daytimetcpsrv daytimetcpsrv1 daytimetcpsrv2 daytimetcpsrv3 \ daytimetcpcliv6 daytimetcpsrvv6 \ byteorder all: ${PROGS} #all的依赖 daytimetcpcli: daytimetcpcli.o ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS} #$@为目标(target)名 daytimetcpcli1: daytimetcpcli1.o ${CC} ${CFLAGS} -o $@ daytimetcpcli1.o ${LIBS} daytimetcpcli2: daytimetcpcli2.o ${CC} ${CFLAGS} -o $@ daytimetcpcli2.o ${LIBS} daytimetcpcli3: daytimetcpcli3.o ${CC} ${CFLAGS} -o $@ daytimetcpcli3.o ${LIBS} daytimetcpsrv: daytimetcpsrv.o ${CC} ${CFLAGS} -o $@ daytimetcpsrv.o ${LIBS} daytimetcpsrv1: daytimetcpsrv1.o ${CC} ${CFLAGS} -o $@ daytimetcpsrv1.o ${LIBS} daytimetcpsrv2: daytimetcpsrv2.o ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS} daytimetcpsrv3: daytimetcpsrv3.o ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS} daytimetcpcliv6: daytimetcpcliv6.o ${CC} ${CFLAGS} -o $@ daytimetcpcliv6.o ${LIBS} daytimetcpsrvv6: daytimetcpsrvv6.o ${CC} ${CFLAGS} -o $@ daytimetcpsrvv6.o ${LIBS} byteorder: byteorder.o ${CC} ${CFLAGS} -o $@ byteorder.o ${LIBS} clean: rm -f ${PROGS} ${CLEANFILES}