从头开始写项目Makefile(一):基本规则

【版权声明:转载请保留出处:

一般一个稍大的

# lscommon.h debug.c debug.h ipc.c ipc.h main.c tags timer.c timer.h tools.c tools.h #

以上源代码可以这样编译:

# gcc -o target_bin main.c debug.c ipc.c timer.c tools.c

如果之后修改了其中某一个文件(如tools.c),再执行一下上一行代码即可,但如果有成千上万个源文件这样编译肯定是不够合理的。此时我们可以按下面步骤来编译:

# gcc -c debug.c# gcc -c ipc.c# gcc -c main.c# gcc -c timer.c# gcc -c tools.c# gcc -o target_bin main.o debug.o ipc.o timer.o tools.o

如果其中tools.c修改了,只需要编译该文件,再执行最后生成可执行文件的操作,也就是做如下两步操作即可:

# gcc -c tools.c# gcc -o target_bin main.o debug.o ipc.o timer.o tools.o

这样做看上去应该很合理了。但是如果修改了多个文件,就很可能忘了编译某一文件,那么运行时就很有可能出错。如果是

下面给一个简单的

target_bin : main.o debug.o ipc.o timer.o tools.o>—gcc -o target_bin main.o debug.o ipc.o timer.o tools.o main.o: main.c common.h>—gcc -c main.c debug.o: debug.c debug.h common.h>—gcc -c debug.c ipc.o: ipc.c ipc.h common.h>—gcc -c ipc.c timer.o: timer.c timer.h common.h>—gcc -c timer.c tools.o: tools.c tools.h common.h>—gcc -c tools.c

然后在命令行上执行命令:

# make gcc -c main.cgcc -c debug.cgcc -c ipc.cgcc -c timer.cgcc -c tools.cgcc -o target_bin main.o debug.o ipc.o timer.o tools.o## lscommon.h common.h~ debug.c debug.h debug.o ipc.c ipc.h ipc.o main.c main.o Makefile Makefile~ tags target_bin timer.c timer.h timer.o tools.c tools.h tools.o#

可见在该目录下生成了

所谓Makefile我的理解其实就是由一组组编译规则组成的文件,每条规则格式大致为:

target … : prerequisites … >—command…

其中Prerequisites是产生>—标示tab字符)开头,,不可用空格代替。

说白了就是要产生

比如在我们给出的main.odebug.oipc.otimer.otools.o是main.ccommon.h是

在该例子中,Makefile工作过程如下:

1.首先查找第一条规则目标,第一条规则的目标称为缺省目标,只要缺省目标更新了就算完成任务了,其它工作都是为这个目的而做的。该main.odebug.oipc.otimer.otools.o都没有生成,所以需要先更新这些文件,然后才能更新target_bin。

2.所以main.ccommon.h,文件存在,所以执行规则命令gcc-cmain.c,生成

3.最后执行gcc-otarget_binmain.odebug.oipc.otimer.otools.o,更新target_bin。

在没有更改源代码的情况下,再次运行make:

# makemake: `target_bin' is up to date.#

得到提示目标target_bin已经是最新的了。

如果修改文件

# vim main.c# makegcc -c main.cgcc -o target_bin main.o debug.o ipc.o timer.o tools.o#

此时make会自动选择受影响的目标重新编译:

首先更新缺省目标,先检查target_bin是否需要更新,这需要检查其依赖文件main.odebug.oipc.otimer.otools.o是否需要更新。

其次发现gcc-cmain.c更新main.o。

最后发现目标gcc-otarget_binmain.odebug.oipc.otimer.otools.o更新target_bin。

总结下,执行一条规则步骤如下:

1.先检查它的依赖文件,如果依赖文件需要更新,则执行以该文件为目标的的规则。如果没有该规则但找到文件,那么该依赖文件不需要更新。如果没有该规则也没有该文件,则报错退出。

2.再检查该文件的目标,如果目标不存在或者目标存在但依赖文件修改时间比他要晚或某依赖文件已更新,那么执行该规则的命令。

由此可见,

Makefile

# make tools.o gcc -c tools.c#

编译成功,这里又引出一个问题,如果继续执行同样的命令:

# make tools.omake: `tools.o' is up to date.#

我们先手动删掉

我们在上面Makefile最后加上如下内容:

clean:>—rm *.o target_bin当我们直接# make cleanrm *.o target_bin#可见

clean

最后总结一下,

给一个今天完整的makefile:

target_bin : main.o debug.o ipc.o timer.o tools.o>—gcc -o target_bin main.o debug.o ipc.o timer.o tools.o main.o: main.c common.h>—gcc -c main.c debug.o: debug.c debug.h common.h>—gcc -c debug.c ipc.o: ipc.c ipc.h common.h>—gcc -c ipc.c timer.o: timer.c timer.h common.h>—gcc -c timer.c tools.o: tools.c tools.h common.h>—gcc -c tools.c clean:>—rm *.o target_bin

艰苦能磨练人的意志。

从头开始写项目Makefile(一):基本规则

相关文章:

你感兴趣的文章:

标签云: