Makefile(转)

Makefile 文件如下:
func: main.o func1.o func2.o
        gcc main.o func1.o func2.o -o func
main.o: main.c mylib.h
        gcc -Wall -c main.c
func1.o: func1.c mylib.h
        gcc -Wall -c func1.c
func2.o: func2.c mylib.h
        gcc -Wall -c func2.c
然后在这个目录下运行make编译:
$ make
gcc -Wall -c main.c
gcc -Wall -c func1.c
gcc -Wall -c func2.c
gcc main.o func1.o func2.o -o func
make命令会自动读取当前目录下的Makefile 文件,完成相应的编译步骤。
Makefile 由一组规则组成,每条规则的格式是:
target ... : prerequisites ...
command1
command2
...
例如:
func: main.o func1.o func2.o
        gcc main.o func1.o func2.o -o func
func是这条规则的目标(Target), main.o func1.o和 func2.o是这条规则的条件(Prerequisite)。
目标和条件之间的关系是:欲更新目标,必须首先更新它的所有条件;所有条件中只要有一个条件被更新

了,目标也必须随之被更新。
所谓“更新”就是执行一遍规则中的命令列表,命令列表中的每条命令必须以一个Tab开头,注意不能是

空格Makefile 的格式不像C语言的缩进那么随意,对于Makefile 中的每个以Tab开头的命令,make会创建

一个Shell进程去执行它。

对于上面这个例子,make执行如下步骤:
尝试更新Makefile 中第一条规则的目标func,第一条规则的目标称为缺省目标,只要缺省目标更新了就算

完成任务了,其它工作都是为这个目的而做的。由于我们是第一次编译,func文件还没生成,显然需要更

新,但规则说必须先更新了main.o、func1.o和func2.o这三个条件,然后才能更新func。
所以make会进一步查找以这三个条件为目标的规则,这些目标文件也没有生成,也需要更新,所以执行相

应的命令(gcc –Wall -c main.c、gcc –Wall -c func1.c和gcc –Wall -c func2.c)更新它们。
最后执行gcc main.o func1.o func2.o -o func更新func。

如果没有做任何改动,再次运行make:
$ make
make: `main' is up to date .
make会提示缺省目标已经是最新的了,不需要执行任何命令更新它。
现在总结一下Makefile 的规则。如果一条规则的目标属于以下情况之一,就称为需要更新:
目标没有生成。
某个条件需要更新。
某个条件的修改时间比目标晚。

通常Makefile 都会有一个clean规则,用于清除编译过程中产生的二进制文件(.o的目标文件),保留源文

件:
clean:
@echo "cleanning project"
-rm func*.o
@echo "clean completed"
把这条规则添加到我们的Makefile 文件的末尾,然后执行这条规则:
$ make clean
     cleanning project
     rm func *.o
     clean completed

clean目标不依赖于任何条件,并且执行它的命令列表不会生成clean这个文件。
@和-字符的效果:如果make执行的命令前面加了@字符,则不显示命令本身而只显示它的结果;通常make

执行的命令如果出错,就立刻终止,不再执行后续命令。但如果命令前面加了-号,即使这条命令出错,

make也会继续执行后续命令。通常rm命令前面要加-号,因为rm要删除的文件可能不存在,这个命令有可

能出错,但这种错误是应该忽略的。例如上面已经执行过一遍make clean,再执行一遍就没有文件可删了

,这时rm会报错,但make忽略这一错误,继续执行后面的echo命令。

如果当前目录下存在一个文件叫clean会怎么样呢?
如果存在clean这个文件,clean目标又不依赖于任何条件,make就认为它不需要更新了。而我们希望把

clean当作一个特殊的名字使用,不管它存在不存在都要更新,可以添一条特殊规则,把clean声明为一个

伪目标:
.PHONY: clean
这条规则没有命令列表。
clean:
@echo "cleanning project"
-rm func*.o
@echo "clean completed"
    .PHONY: clean

本例子中的Makefile 文件如下:
func: main.o func1.o func2.o
        gcc main.o func1.o func2.o -o func
main.o: main.c mylib.h
        gcc -Wall -c main.c
func1.o: func1.c mylib.h
        gcc -Wall -c func1.c
func2.o: func2.c mylib.h
        gcc -Wall -c func2.c
clean:
        @echo "cleanning project"
        -rm func *.o
        @echo "clean completed"
.PHONY: clean

clean目标是一个约定俗成的名字,在所有软件项目的Makefile 中都表示清除编译生成的文件,类似这样

的约定俗成的目标名字有:
all,执行主要的编译工作,通常用作缺省目标。
install,执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。
clean,删除编译生成的二进制文件。
只要符合所描述的语法的文件我们都叫它Makefile ,而它的文件名则不一定是Makefile 。事实上,执行

make命令时,是按照GNUmakefile、makefileMakefile 的顺序找到第一个存在的文件并执行它,不过还

是建议使用Makefile 做文件名。

猜你喜欢

转载自xueqi.iteye.com/blog/1567879
今日推荐