原文出自出自学与思编程网
本文将详细介绍什么是Makefile,为什么linux下编程我们需要Makefile,以及最简单的Makefile应该如何编写。
什么是Makefile,为什么我们需要它?
回想一下我们编程生涯,多数朋友都是从下面这个最简的hello world程序开始进入美妙的linux编程世界的。
————main.c—————-
#include <stdio.h>

int main(int argc, char *argv[])
{
        printf(”hello world!n”);
        return 0;
}

当我们用编辑器编写好上面的代码后,就会在linux命令行输入gcc main.c -o hello从而编译得到hello这个可执行文件。很简单是吧,编译时我们输入的命令很短,只有一行。别忙,这只是只有一个源代码文件的情况,要是我们拥 有10个,100个源代码文件,我们也是手动输入gcc main.c file1.c file2.c file3.c …… -o real来编译生成这个real可执行程序吗?也许您会说,可以阿,嗯,确实是可以,那您又想,如果由于某些原因,您修改了这些源文件中的部分代码,为了 生成real程序您是不是又得重复输入上面那一长串编译指令,重复一遍您可能觉得没什么,可是重复2遍,3遍,10遍,100遍呢,我相信您一定烦了!别 担心,在我们遇到这些问题之前,早有人遇到了,而且他们还想出一个很好的办法来解决这个问题。他们编写了一个叫make的程序,这个程序可以帮我们无怨无 悔的反复输入那些烦人的编译指令。除了勤劳,make还很聪明,他可以自动判断我们修改了哪些文件,从而再次编译时他只会让编译器去编译那些修改过的源代 码文件,而不是一刀切把所有的不管修改没修改的源代码文件通通交给编译器去编译,别小看这个功能哦,在大项目中可以为我们节省很多很多时间的哦,是不是很 爽呢!
别高兴得太早哦,make这个程序虽然很勤劳很聪,可是他也得按照我们程序员的意愿去帮干活吧,否则乱干也没有用阿。那么我们怎么把我们的意愿告诉这个make程序呢?答案就是通过Makefile这种文件,今天的主角终于上场了。
了解了吧,我们绝对需要make,为了最大限度的make程序的作用,我们也绝对需要Makefile,下面我们就来学习如何编写Makefile这个文件。
Makefile编写入门
Makefile其实是一个文本文件,我们可以用cat查看它,也可以用vi来编辑它。Makefile包含一条或多条规则,这些规则就是我们与make程序交流时使用的的语言。每条规则都由目标体,依赖体和命令构成,通用格式为:
target: dependencies
        command1
        command2
        command3
        …
target是一个目标,它也起标签的作用,就像c语言中的goto语句指定的那个标签一样。dependencies是与target相关的一些 文件,make程序依据denpendencies与target的时间先后关系来决定是否要执行这条规则中的command部分。command1, command2组成的command部分指定了本条规则应该执行的命令,command部分可以包含一个或多个命令。注意:每个命令占一行,而且每个命 令的前面必须是一个tab字符,不是一个或多个空格哦,切忌!
我们来看一个简单的例子:
假如我们有一个项目中包含了main.c,file1.c, file2.c file1.h file2.h这些文件,编译出来的程序叫example。下面是对应的Makefile
——————Makefile———————-

# makefile example

example: main.o file1.o file2.o
        gcc main.o file1.o file2.o -o example

main.o: main.c file1.h file2.h
        gcc -c main.c -o main.o

file1.o: file1.c file1.h
        gcc -c file1.c -o file1.o

file2.o: file2.c file2.h
        gcc -c file2.c -o file2.o

这里简单解释下这个Makefile,第一行是以#号开头的一行,意思是它是注释,在Makefile中,以#号开始到本行结束都是注释部 分,make这个程序不会管注释部分的内容,注释部分可以出现在Makefile中的任何地方。紧接着注释后面的是example这个target对应的 规则:它有三个依赖体,分别是main.o, file1.o, file2.o,那为什么依赖部分是他们三个而不是其它的呢?原因就在于要生成example这个程序,必须依赖这三个.o的目标文件,如果这三个目标文 件中的任何一个或多个更改过就必须重新生成example,当然您也可以只包含main.o作为依赖体,但如果这样的话,您修改了file1.c或 file2.c却没有修改main.c的话,make会拒绝去执行这条规则后面的命令,也就是他不会重新去生成example,那您的修改也就没有被真正 编译到你的程序中去;我们可以从这里看出,所谓的依赖体其实应该说是时间依赖体,它只起到与目标体一起判断是否执行规则命令部分的作用而已,当然这也有例 外,我们以后再说,但您必须理解这里所说的它与target的关系。命令部分只有一条命令gcc main.o file1.o file2.o -o example用于生成example;接下来的还有三条规则,样子与第一条规则差不多我们就不分析了。这里重点要理解目标体target与依赖体 dependencies的关系,要理解每条规则为什么需要那些依赖体而不是其它的或则更少更多的依赖体。
有了这个Makefile我们在命令行输入make example回车,example就会自动被编译出来了。
下篇文章我们继续以上面这个例子来分析一下当我们输入make example后,make这个程序所做的动作。