Makefile简介
背景
make程序可以让将一个项目中的源文件编译成可执行文件之类的工作自动化。项目中的文件总是存在树状的依赖关系,比如某个.o文件依赖.c和若干头文件,一个程序又依赖几个.o和.so等等,修改过.c后,它对应的.o需要重新生成,依赖该.o的程序也需要重新生成,而该程序依赖的其他.o则不需要重新生成。make的优点是:它可以根据文件之间的依赖关系和时间戳判断应该重新执行那些步骤,以产生需要的程序。有了这个信息,make可以优化编译的过程,跳过非必要的步骤。而且Makefile的规则更容易表达文件之间的依赖关系和文件的更新顺序。
基本构成
基本上,makefile包含了一组用来编译应用程序的规则。第一条规则被认为是默认规则。一项规则可以分为三个部分:工作目标(target),它的必要条件(prerequisite),以及发生更新动作时所要执行的命令(command):
target:prereq1 prereq2 ...
commands
- 工作目标是make命令行可以指定的参数,它可以是一个需要创建的文件或者某个动作(又称假想的目标)。
- 必要条件可以有多个,用空白隔开
- 命令是将被放到shell中执行的命令,可以有多行多条命令。每行必须以tab开头。
如果需要更新一条规则的目标,那么先递归地更新它的必要条件,之后再判断如果有比目标更“新”的必要条件,就执行命令。
一个实用的makefile中还会包含其他元素,比如自定义的变量、条件判断指令、内置函数外置函数等。这些都是为了更方便、全面地描述规则而存在的。
工作机制
make的工作机制很简单。它首先将来自命令行的参数作为工作目标,如果没有指定,则为默认工作目标。然后按顺序查找所有该目标依赖的文件,并依次把依赖文件作为目标在makefile中查找相应的规则…按此递归下去形成依赖树。树的叶子节点在makefile中没有相应的规则更新他们,所以他们必须是已经存在的,否则make报错:所需文件不存在而且没有更新他们的规则。(产生也视为更新操作。)make的规则树的搜索是先序遍历,规则的执行是后序遍历。
规则的执行:如果某个必要条件比目标“新”,则将此规则的命令交给shell执行。而如果工作目标最“新”,则什么也不做。执行下一条规则。