[002-Makefile-笔记] Makefile的执行过程

来源:互联网 发布:2016淘宝买药货到付款 编辑:程序博客网 时间:2024/06/05 10:07

Makefile的执行过程

  1. 依次读取变量“MAKEFILES”定义的makefile文件列表
  2. 读取工作目录下的makefile文件(根据命名的查找顺序“GNUmakefile”,“makefile”,“Makefile”,首先找到哪个就读取哪个)
  3. 依次读取工作目录makefile文件中使用指示符“include”包含的文件
  4. 查找重建所有已读取的makefile文件的规则(如果存在一个目标是当前读取的某一个makefile文件,则执行此规则重建此makefile文件,完成以后从第一步开始重新执行)
  5. 初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支
  6. 根据“终极目标”以及其他目标的依赖关系建立依赖关系链表
  7. 执行除“终极目标”以外的所有的目标的规则(规则中如果依赖文件中任一个文件的时间戳比目标文件新,则使用规则所定义的命令重建目标文件)
  8. 执行“终极目标”所在的规则

示例

有三个C文件,组成一个Hello World的程序:

/* hello.c */#include <stdio.h>#include "mystr.h"void main(void){    Print("Hello World");}
/* mystr.c */#include <stdio.h>#include "mystr.h"void Print(char* str){    printf("%s\n", str);}
/* mystr.h */#ifndef __MY_STR_H__#define __MY_STR_H__void Print(char*);#endif // __MY_STR_H__

我们使用三个Makefile文件来测试Makefile的执行过程:

/* Makefile_env */${warning Makefile_env running}
/* rule.mk */${warning Rule.mk running} %.o : %.c    ${CC} -c $< -o $@   %.dep : %.c    ${CC} -MM $< > $@
/* Makefile */${warning Makefile running} ${warning include rule.mk}include rule.mkcfile=$(wildcard *.c)depfile=${cfile:.c=.dep}ofile=${cfile:.c=.o}${warning include ${depfile}}include ${depfile}hello: ${ofile}    ${CC} -o $@ $^all: hello    @echo "End"${warning Makefile end}

为了测试执行过程的第一步,我们增加了MAKEFILES的环境变量(实际工作中,我们尽量不要使用这个变量配置特殊的Makefile文件)

$ export MAKEFILES=Makefile_env

执行结果和注释如下:

$ make all# 首先执行MAKEFILES定义的文件列表Makefile_env:1: Makefile_env running# 开始执行当前目录下的Makefile(解析阶段)Makefile:1: Makefile runningMakefile:3: include rule.mkrule.mk:1: Rule.mk runningMakefile:10: include hello.dep mystr.depMakefile:11: hello.dep: 没有那个文件或目录Makefile:11: mystr.dep: 没有那个文件或目录Makefile:19: Makefile end# hello.dep mystr.dep 不存在,根据rule.mk中定义的规则生成该文件cc -MM mystr.c > mystr.depcc -MM hello.c > hello.dep# Makefile文件发生了改变,重新开始执行Makefile# 第二次执行MAKEFILES定义的文件列表Makefile_env:1: Makefile_env running# 第二次执行当前目录下的Makefile(解析阶段)Makefile:1: Makefile runningMakefile:3: include rule.mkrule.mk:1: Rule.mk running# 因为hello.dep mystr.dep已经存在,所以在include时跳过规则,不重新生成文件Makefile:10: include hello.dep mystr.depMakefile:19: Makefile end# 解析阶段完毕,开始执行逻辑链(执行阶段)# hello 依赖 hello.o 和 mystr.o, 根据rule.mk中的规则生成.o文件cc -c hello.c -o hello.occ -c mystr.c -o mystr.o# 执行最终目标定义的命令cc -o hello hello.o mystr.oEnd
1 0