首页
论坛
课程
招聘
雪    币: 1675
活跃值: 活跃值 (11)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝

[原创]Windows 下的 Makefile 编写(一)Makefile的基本规则

2010-12-23 13:24 13725

[原创]Windows 下的 Makefile 编写(一)Makefile的基本规则

2010-12-23 13:24
13725
Windows 下的 Makefile 编写(一)Makefile的基本规则

作者:cntrump

    Makefile对于很多人来说是陌生的,特别是习惯于使用 IDE 的人来说,似乎没有听说过 Makefile ,因为Makefile 的工作都由IDE代劳了。但是Makefile 的地位是不可忽略的,从VC诞生到现在Nmake这个实用程序就一直伴随着VC编译器一起发行。

    很多大的工程都是基于Makefile编译和维护的,对于开源项目来说,大多数都使用Makefile进行编译,使用IDE来编译大型工程是不可想象的。

    Makefile是什么?它是一个文本文件,里面记录着项目由哪些目标构成,以及各个目标的生成方式等信息,Makefile的核心任务是定义一系列的规则,然后由Nmake来解释执行,任何一个文本编辑器都可以用来编写Makefile。

    先来大概看一下Makefile的基本规则:

    Target:dependent;command

       Command

       ........


Target 是目标,目标可以是一个文件,也可以是一个标签,如果Target用作标签,则称之为伪目标。Makefile至少要有一个目标。

Dependent是依赖项目,指明目标所依赖的具体项目。依赖项目和目标之间用 : 号分隔。

Command是命令,如果命令和依赖项目在同一行,则需要使用;号与之相隔,各个命令之间使用空格或Tab键分开,如果命令是单独一行,则需要使用Tab缩进。Command命令由Nmake来执行。

    上述内容简单地表明了一个依赖关系,生成Target目标依赖dependent中指定的文件,而生成的规则由Command来定义,Nmake负责执行这些命令。

    默认情况下,Nmake会查找当前目录下任何名称为Makefile的文件(名称不区分大小写,并且没有后缀),如果你的Makefile文件名称是其他的,则需要使用 –f 参数指定。

    以上就是Makefile的核心内容,任何系统的Makefile都是这样执行的。但是要写好一个Makefile,仅仅这些还不够。

    对于一个新知识,我更喜欢从做中学。下面举一个例子来说明上面的规则在实际应用中如何操作:

    Test.exe:main.obj

       Link.exe main.obj /out:Test.exe

    main.obj:main.cpp

    #仅编译文件

       cl.exe main.cpp 

     在Makefile中注释使用 # 号开头,且仅有这一种注释方式。它的作用和C++ 语法中的 // 注释是一样的。所不同的是 # 号必须放在行首。

上面的Makefile 文件指定了两个目标,分别是Test.exe 和 main.obj,生成Test.exe需要依赖 main.obj文件,而生成 main.obj文件依赖main.cpp。在目标下方指明了生成该目标方法。

    main.cpp 的内容如下:

#include <stdio.h>

int main()

{

  printf("Hello Makefile!\n");

  return 0;

}


     将Makefile和main.cpp放置于同一目录下,在VC的命令提示符窗口中执行 nmake命令,就会自动生成Test.exe和 main.obj两个文件。再运行生成后的Test.exe测试一下:


    在Makefile中定义了两个目标,Nmake默认只生成Makefile中的第一个目标,由于main.obj是Test.exe 的依赖项,所以main.obj目标也得以执行。

    是不是每执行一次namke命令就会重新生成一次目标文件呢?答案:不是。每次都重新生成目标显然是一种资源浪费,nmake是根据时间戳来决定是否需要重新生成目标。只有在依赖文件不存在或者依赖文件时间高于目标文件时,nmake才会生成目标。

    前面的例子已经生成了目标文件,如果修改了main.cpp中的代码或者删除了main.obj,都将会重新生成Test.exe。

    一般来说,为了使清理中间文件或重新生成目标更加方便,都会在Makefile中加入一个伪目标来清理生成的中间文件。以删除main.obj为例,Makefile修改如下:

Test.exe:main.obj

    Link.exe main.obj /out:Test.exe

Main.obj:main.cpp

# 仅编译文件

    cl.exe /c main.cpp

clean:

    @del *.obj

    @echo Project has clean.


clean是一个伪目标,只是作为标签使用。clean下的指令是命令行下的删除文件命令和显示一个字符串。在命令前加 @ 符号是为了不显示命令本身。

默认情况下nmake只会生成第一个Test.exe目标,不会执行到clean目标,如果要指定生成目标,需要显式指定目标名称:

nmake clean


就指定要执行Makefile中的clean伪目标。执行之后会删除生成的main.obj并显示一行文字:


还可以指定多个目标,nmake会从左往右依次生成目标。所以如果要在清除中间之后立即生成Test.exe,可以这么做:

    nmake clean Test.exe


一般来说,总是把最终生成的目标放在最前,而把清理中间文件的伪目标放到最后。下一回,我会结合实际的例子再介绍Makefile的其他内容。

[公告]看雪论坛2020激励机制上线了!多多参与讨论可以获得积分快速升级?

上传的附件:
最新回复 (19)
雪    币: 486
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
vivid 活跃值 2010-12-23 13:40
2
0
沙发!!!!!!!!!!!!!!
雪    币: 281
活跃值: 活跃值 (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
kkmylove 活跃值 2 2010-12-23 16:39
3
0
占座 !!!!!!!
雪    币: 2273
活跃值: 活跃值 (16)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
北极狐狸 活跃值 7 2010-12-23 16:49
4
0
不错不错...好好学习一下..
雪    币: 2558
活跃值: 活跃值 (77)
能力值: ( LV13,RANK:273 )
在线值:
发帖
回帖
粉丝
littlewisp 活跃值 2 2010-12-23 17:00
5
0
期待后面的文章......
雪    币: 2687
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
溯雪 活跃值 2010-12-24 13:43
6
0
解除许久的疑惑,获益良多。
雪    币: 307
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
iSpeak 活跃值 2010-12-24 15:07
7
0
不错,学习了
雪    币: 232
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dlmu 活跃值 1 2010-12-24 15:15
8
0
学习cntrump大牛的文章
雪    币: 555
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:16 )
在线值:
发帖
回帖
粉丝
kinglord 活跃值 2010-12-25 02:32
9
0
mark期待给力的续
雪    币: 564
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lixupeng 活跃值 2010-12-25 08:32
10
0
和 AVR GCC Makefile差不多支持 !!
雪    币: 30
活跃值: 活跃值 (13)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
lyricC 活跃值 2010-12-25 13:19
11
0
顶,好文章。。
雪    币: 189
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
adomore 活跃值 2010-12-26 12:39
12
0
感谢楼猪分享了!先学习了!
雪    币: 160
活跃值: 活跃值 (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
profmit 活跃值 2010-12-26 15:28
13
0
正在学习,谢谢分享~
雪    币: 288
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
周zhou周 活跃值 2010-12-27 00:45
14
0
好文章!抽时间仔细研究研究。。。
雪    币: 176
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
greatnew 活跃值 2010-12-27 17:06
15
0
写的很清楚啊,下载了留着
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
门栓 活跃值 2010-12-28 21:04
16
0
谢谢楼主,下载收藏了.
雪    币: 413
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
孟贤 活跃值 2010-12-29 09:33
17
0
基础的东西就是最实惠的东西
雪    币: 1404
活跃值: 活跃值 (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
FCrane 活跃值 1 2010-12-30 12:49
18
0
标记一下,好东西啊,一直想学习的东西
雪    币: 367
活跃值: 活跃值 (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
cnhnyu 活跃值 2 2010-12-31 15:13
19
0
非常不错
雪    币: 1
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
红海_927712 活跃值 2018-4-25 17:41
20
0
游客
登录 | 注册 方可回帖
返回