最简makefile教程(一)

一直对makefile文件一知半解,今天好好研究了一下他的用法。

研究过后,发现其实makefile语法很简单,核心思想就是执行对应的指令而已,为了叙述方便先从最简单的指令讲起。例如:

A : 
    cmd a
B : C D
    cmd b
C :
    cmd c
D : 
    cmd d
    
#注意cmd前面必须要有tab键

你可以把A,B看作是一个指令标签,也可以用于make指令的参数,如make A 就会执行对应的指令cmd a。cmd只是一条linux shell命令而已,可以执行任何合法的命令,如gcc, rm等。

我们注意到B后面还跟着一个C和D,他们是干嘛的呢?

可以把C和D看作B命令的子命令,简单来讲也就是说执行B的时候先执行C标签的指令,再执行D标签指令。例如上面的指令,如果执行make B,最终的执行过程是cmd c, cmd d, cmd b。

但是执行B命令的时候不一定会执行C和D命令,这个下面要讲到。由于make程序主要用于编译项目工程,还是举个编译程序的例子:

P : test.o
	gcc -o test test.o
	
test.o : test.c
	gcc -c test.c

执行上面的make,我们发现第一次执行时,两条指令都被执行了。可是再次执行时,只有第一条指令被执行。这是为什么呢?为了讲明白这个,我们引入两个概念,目标和依赖。即命令标签为目标,子命令为依赖。上面的makefile中目标P依赖test.o,目标test.o依赖test.c。

makefile命令被执行时有这样的一个规则:如果目标比依赖新,即目标文件(如果存在)生成的时间比依赖文件晚,就不用执行该目标对应的命令,当然如果目标文件不存在的话肯定是要执行对应的命令的。

当执行make时,如果没有参数,默认是执行第一个指令,即P。由于目标P依赖test.o,他就先去执行test.o命令。刚开始的时候是没有test.o的,于是执行test.o对应的指令gcc -c test.c,生成了test.o。第二次执行test.o时,由于test.o已经生成,且生成时间比test.c要晚,所以不用再次执行对应的命令。

我们看到这种规则是正好适用于编译工程的。当目标文件生成后,再次执行目标命令时是不会执行对应的命令的,这样有利于节省编译的时间。只有当依赖文件变动后,目标文件变的比依赖文件早,这时就需要且必须重新执行对应的命令了。

当我们去掉依赖文件时,例如上面的test.o后面没有test.c,虽然仍然可以执行下面对应的命令,生成test.o。如果已经生成了test.o,当我们改动test.c文件后,再也不会重新生成test.o了,最终导致我们抓狂的找为什么改动不生效的bug。所以我们编写makefile时一定要记得加上依赖文件。

以上就是makefile文件的核心,我们发现makefile文件其实就是来执行shell 命令的,只不过他的语法规则正好适用于编译工程。或者说为了编译工程发明了make程序及其对应的makefile脚本。

为什么说makefile正好适用于编译工程呢?因为一般编译一个工程正好需要两步:编译和链接,而且这两步有依赖关系,也就是说先编译生成中间文件,然后才能链接成可执行文件。如下所示:

Make_Execute_Progaram : Make_Obj_File
    gcc xxx.c -o target.x 
    
Make_Obj_File:
    gcc -c  xxx.c -o xxx.o

读到这一步应该很好理解上面的代码了。从上面的例子来看,makefile好像和shell脚本没什么差别,如果真的是这样直接用shell脚本就好了。事实上makefile有更强大的功能,他能像编程语言一样有相应的语法和变量,在编译大型工程,特别是跨平台编译时会很高效。

makefile变量名的声明和引用:

src = http.c         #变量名和值之间可以有空格
target = http.o

A : $(src)
	gcc -c $(src) -o $(target)
	

$()符号就是引用变量名了,以上替换后变为:

src = http.c         #可以有空格
target = http.o

A : http.c
	gcc -c http.c -o http.o
	

执行make A 就会执行gcc -c http.c -o http.o,A后面的http.c是他的依赖文件,其实这里可以不写,但是一般写上是为了检测http.c文件是否存在,更重要的是判断文件是否有更新。

以上就是makefile文件的基本用法和概念,更多的内容将在后面介绍。

 

欢迎加入QQ群 858791125 讨论skynet,游戏后台开发,lua脚本语言等问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值