关于如何编写Makefile

陈皓老师曾经在CSDN上写过关于Makefile很详细的文章,有兴趣的可以到这里慢慢研读。
http://blog.csdn.net/haoel/article/month/2004/02
这里我把他在文章里写的关于Makefile的一些较为基本且常用的操作总结在这里。

简介

在windows的开发环境下编译汇编链接生成目标文件,这一系列工作全都是IDE帮我们完成。但是在Linux的开发环境下,需要开发者自己来输入指令完成这些步骤。这个时候就出现了Makefile,Makefile在linux下的作用就是自动化编译,它完成的工作就和IDE一样,把工程中的各类源文件按照开发者在Makefile里定义的一系列规则来编译,比如文件的编译先后顺序,哪些文件需要重新编译等等。在Makefile定义好了以后,使用make指令就可以直接生成所有你要的目标文件了。

Makefile编写规则

基本格式为:

 target : prerequisites
     command

target是目标文件,即你想要得到的文件。
prerequisite是你要生成target所需要的文件也叫依赖文件。
command是要获得上面目标文件所需要执行的指令。

我在这里写了一个简单的例子,包含了两个头文件和一个c文件。
Makefile示例1
接着我们使用vim创建一个Makefile文件,并往里面写入如下代码
Makefile示例2

退出vim使用指令make,再ls显示文件夹内容,发现多了test可执行文件和test.o目标文件。
Makefile3

清空目标文件的规则

为了便于代码的重编译和文件的清洁,我们会在Makefile中写入一个清空目标文件的语句。如图2中最后clean语句。在执行make语句后我们不想再要中间生成的.o文件,则执行指令make clean,Makefile则会执行clean下面的语句,删除掉.o文件。如图
Makefile5

make的工作原理

1.make在当前目录下找到Makefile文件;
2.找到后,按照文件中所写的第一个目标文件即最终目标;
3.如果目标文件不存在,或是目标文件所依赖的后面的 .o 文件的文件修改时间要比目标文件新,那么,他就会执行后面所定义的命令用来生成目标文件;
4.如果目标文件所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。
5.当所有目标文件所需要的文件都创建完成后,就会创建最后的目标文件。

这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。但是像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,我们只能使用make clean去调用它。

Makefile中的伪目标

Makefile中有一个伪目标的概念,它的定义方式为
.PHONY:伪目标
伪目标可以是没有依赖文件的目标文件,例如clean就可以定义为伪目标,防止误触发。或者在一个Makefile里面你想一次make生成多个可执行文件,也可以利用伪目标的定义。例如

all : prog1 prog2 prog3
   .PHONY : all

   prog1 : prog1.o utils.o
           cc -o prog1 prog1.o utils.o

   prog2 : prog2.o
           cc -o prog2 prog2.o

   prog3 : prog3.o sort.o utils.o
           cc -o prog3 prog3.o sort.o utils.o

all就为定义的伪目标,由于all是Makefile里的第一个出现的目标文件,所以它就是最终的目标文件,他又依赖于后面的的三个目标文件,make就会分别去生成这三个目标文件,从而达到一次make生成多个可执行文件的目的。

变量的声明

当我们一个工程是由多个.o文件组合而成的时候,这个时候为了方便修改和管理我们可以采用声明一个变量来代替这些.o文件。这样如果想要修改这些.o文件其中的哪一个的时候只要修改声明处的就可以了。
这里使用陈皓老师给出的例子

edit : main.o kbd.o command.o display.o \(\为续行符)
       insert.o search.o files.o utils.o
       gcc -o edit main.o kbd.o command.o display.o \
       insert.o search.o files.o utils.o

这个edit目标文件由多个.o文件构成,如果想要修改其中一个时,加上后面的clean要修改三处,如果工程量再大一点则很容易出现遗漏。所以这里声明了变量objects,并且在后面的Makefile描述中就可以使用$(objects)代替这些变量。

objects = main.o kbd.o command.o display.o \
          insert.o search.o files.o utils.o

edit : $(objects)
       gcc -o edit $(objects)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值