简单的makefile
转自 http://blog.csdn.net/todd911/article/details/42717995
make定义了一种语言,可用来描述源文件、中间文件以及可执行文件之间的关系。它还提供了一些功能,可用来管理各种
候选配置、实现可重用程序库的细节以及让用户自定义宏将过程参数化。简言之,make常被视为开发过程的核心,因为它
为应用程序的组件以及这些组件的搭配方式提供了一个可依循的准则。
make的主要价值在于它有能力完成编译应用程序时所需要的一系列复杂步骤,以及当有可能缩短“编辑-编译-调试”周期时对
这些步骤进行优化的动作。
1.工作目标和必要条件
基本上,makefile文件包含了一组用来编译应用程序的规则。make所看到的第一项规则,会被作为默认规则使用。一项
规则可分为三部分:工作目标(target)、它的必要条件(prerequisite)以及所要执行的命令(command):
target:prereq1 prereq2
commands
工作目标是一个必须建造的文件或进行的事情:必要条件或已存对象是工作目标得以被成功创建之前,必须实现存在的那些
文件;而所要执行的命令则是必要条件成立时将会创建工作目标的那些shell命令。
有如下文件:
main.c:
#include <stdio.h>
#include "myutil.h"
int main(void) {
myprint();
return 0;
}
myutil.h:
void myprint();
myutil.c:
#include <stdio.h>
void myprint(void) {
printf("this is myprint function.\n");
}
makefile:
main:main.o myutil.o
gcc main.o myutil.o -o main
main.o:main.c myutil.h
gcc -c main.c myutil.h
myutil.o:myutil.c
gcc -c myutil.c
执行make命令:
root@yan-vm:~/makefile# make
gcc -c main.c
gcc -c myutil.c
gcc main.o myutil.o -o main
这个makfile在执行时,发现make执行命令顺序几乎和它们出现在make中的顺序相反,这种自上而下的风格是makefile
文件中常见的手法。一般来说,通常形式的工作目标先会在makefile文件中被指定,而细节则会跟在后面。
2.检查依存关系
make首先注意到命令行上并未指定任何工作目标,所以会想要建立默认main,当make检查其必要时看到两个项目:main.o
和myutil.o,现在make会想要编译main.o并看到相应的规则。接着,make会检查必要条件并注意到main.c并未关联到任何
规则,但存在main.c这个文件,所以会执行相应的命令把main.c转换成main.o。
这种”从工作目标到必要条件,从必要条件到工作目标,再从工作目标到必要条件“的链接机制就是make分析makefile决定要
执行哪些命令的典型做法。
make将myutil.c转换成myutil.o后,会进行最后的动作--链接。
3.尽量减少重新编译的工作量
如果我们将上面的main.c文件修改为:
#include <stdio.h>
#include "myutil.h"
int main(void) {
myprint();
myprint();
return 0;
}
然后再次执行make命令:
root@yan-vm:~/makefile# make
gcc -c main.c myutil.h
gcc main.o myutil.o -o main
这次myutil.c文件并没有重新被编译,make发现myutil.o已经存在,而且该文件的时间戳在其必要条件myutil.c之后,所以
不需要采取任何更新的动作。
4.调用make
前面的范例做了一下假设:
项目的所有程序代码以及make描述文件都被放在单一目录中。
make描述文件的文件名为makefile、Makefile或GNUMakefile。
执行make命令时,make就方在用户的当前目录中。
当make在上述情况下被调用时,make会自动编译其所找到的第一个工作目标,要更新另一个不同的工作目标,请在
命令行上指定工作目标的名称:
make main
当make被执行时,它会读取描述文件以及找出所有要更新的工作目标。如果工作目标或其必要条件中的任一文件尚未更新,
则会执行相应规则的命令脚本中的shell命令。这些命令被执行之后,make会假设工作目标已完成更新的动作,于是移往
下一个工作目标或是结束执行。
5.Makefile的基本语法
makefiel文件中一般采用自上而下的结构,所以默认会更新最上层的工作目标,下层工作目标用来让上层工作目标保持在
最新的状态。下面是较完整的规则:
target1 target2 target3:prerequisite1 prerequisite2
command1
command2
command3
冒号的左边可以出现一个或多个工作目标,而冒号的右边可以出现另个或多个必要条件,如果冒号的右边没有指定必要条件,
那么只有在工作目标所代表的文件不存在时才会进行更新的动作。更新工作目标所要执行的那组命令有时会被称为命令脚本,
不过通常只被称为命令。
每个命令必须以tab开头,这个语法用来要求make将紧跟在跳格符之后的内容传给subshell来执行。如果你不经意地在非命令
行的第一个字符前插入了一个跳格符,则在大多数情况下,make将会把其后的文字作为命令来执行。
make会将#号视为注释字符,从#号开始到改行结束之间的所有文字都会被make忽略。注释字符#并不会在代表命令的文本行
中引入make的注释功能,这一整行会被传给shell来执行。
你可以使用标准Unix转义字符---反斜杠来延续过长的文本行。