• 全部
  • 问答

【C/C++ _非_值班室】关于makefile (netease收藏)

dot99 2004-07-12 01:13:59
前段时间看着有人问起makefile的用法~贴上来

以下内容来自古老的网易虚拟社区~
===================

make文件其实就是一种批操作文件,将一系列命令行的编译连接命令写成一个文本文件,供nmake.exe程序调用,在命令行方式下运行nmake就可以生成所需的文件,其效果和IDE中的BUILD类似。

先简单介绍一下几个必要的工具(nmake当然是必不可少的了,但它的使用比较简单,就不提了)。ml.exe/cl.exe作用是将汇编源程序或c源程序编译连接成可执行文件(ml就是masm和link),其后可以加上命令行选项(开关)对编译连接的过程进行控制。另一个程序是link.exe, 当然就是对obj文件作连接的啦。它不但可以生成exe文件,还可以生成DLL和VxD(这也是我采用命令行方式的主要原因)。关于ml.exe和link.exe的命令行选项很多,这里也不可能一一解释,详细说明可以看帮助(masm6或MSDN上都有)。

如果会用ml和link进行编译连接了,那make文件就很容易写了。

一. 依赖规则:

make文件由依赖规则(Dependent Rulers)组成,基本结构是指定目标文件(Targets)及其依赖文件(Dependents),然后定义目标文件如何形成(当然是用ml和link了,也有其他的,我们下边会看到)。

具体格式是:

目标文件:依赖文件

命令行

例如有源文件myasm.asm和myasm.inc,依赖规则就可以写成

myasm.obj:myasm.asm myasm.inc


ml /c myasm.asm

nmake还支持通用依赖规则(Inference Rules),例如我们可以将由asm文件到obj文件的规则写成一个通用依赖规则(一个asm文件生成一个obj文件).asm.obj:

ml /c $*.asm

这样我们就不用一遍一遍的写ml......了,只要写出目标文件和依赖文件就行了。这里$*是一个预定义宏,下面就讲一下宏的应用。

二. 宏的定义和引用:

首先是定义宏。很简单,用"="就行了,例如我们可以将ml的命令行选项串(就是多个选项啦,一时想不出用什么词描述了,可能用词不当了)定义成一个宏AFLAGS:

AFLAGS= /C /Zi /Sn

使用时用$(宏名)的形式,即nmake执行时会将AFLAGS替换成/C /Zi /Sn,怎么样,简单吧。

而前面用到的$*表示不带扩展名的目标文件名(这样才通用嘛),向这样的预定义宏还有很多,如$@,表示目标文件的完整文件名,$< 表示比目标文件时间更新的依赖文件名,等等。

三. 例子:

讲了这么多不知道大家是否已经糊涂了,下面就给出一个完整的例子,这个例子来自DDK,为了大家看得清楚,我先将源文件贴出,而下一篇是带注释的。


#
*

# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF AN
Y *

# KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
*

# IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULA
R *

# PURPOSE.
*

#
*

# Copyright (C) 1993-95 Microsoft Corporation. All Rights Reserved.
*

#
*

#*********************************************************************
*******

#


# Makefile for serial device

#

######################################################################
####



!ifdef MASTER_MAKE


BUILD_BITS=32

BUILD_TYPE=comm

!INCLUDE $(DDKROOT)\master.mk

!endif



DEVICE = SERIAL



OBJS = serial.obj serutil.obj serfunc.obj serinit.obj serdbg.obj



########## Definitions ###############################




ASM = ml

AFLAGS = -coff -DBLD_COFF -DIS_32 -nologo -W2 -Zd -c -Cx -DMASM6

ASMENV = ML



LFLAGS = /VXD /NOD



############## VxD device link rule ###################



.asm.obj:

set $(ASMENV)=$(AFLAGS)

$(ASM) -Fo$*.obj $<




$(DEVICE).SYM: $(DEVICE).MAP

mapsym -s -o $(DEVICE).sym $(DEVICE).map



$(DEVICE).VXD $(DEVICE).MAP: $(OBJS)

link @<<$(DEVICE).lnk /DEF:<<$(DEVICE).def

$(LFLAGS)

/OUT:$(DEVICE).VXD

/MAP:$(DEVICE).map

$(OBJS)

<<


VXD $(DEVICE) DYNAMIC

DESCRIPTION '$(DEVICE) Device'



SEGMENTS

_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE

_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE

_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE

_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE

_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE

CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE

_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE


_ITEXT CLASS 'ICODE' DISCARDABLE

_IDATA CLASS 'ICODE' DISCARDABLE

_PTEXT CLASS 'PCODE' NONDISCARDABLE

_PDATA CLASS 'PCODE' NONDISCARDABLE

_STEXT CLASS 'SCODE' RESIDENT

_SDATA CLASS 'SCODE' RESIDENT

_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE

_RCODE CLASS 'RCODE'

EXPORTS

$(DEVICE)_DDB @1

<<



clean:

-@del *.obj

-@del *.lib

-@del *.exp

-@del *.map

-@del *.sym

-@del *.vxd


#
*
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF AN
Y *
# KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
*
# IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULA
R *
# PURPOSE.
*
#
*
# Copyright (C) 1993-95 Microsoft Corporation. All Rights Reserved.
*
#
*
#*********************************************************************
*******
*******
#

# Makefile for serial device
#
######################################################################
####

!ifdef MASTER_MAKE
BUILD_BITS=32
BUILD_TYPE=comm
!INCLUDE $(DDKROOT)\master.mk
!endif

#这是一个串口VxD的MAKE文件

#先定义了一个设备名的宏DEVICE
DEVICE = SERIAL

#所有的目标文件
OBJS = serial.obj serutil.obj serfunc.obj serinit.obj serdbg.obj

########## Definitions ###############################

ASM = ml
AFLAGS = -coff -DBLD_COFF -DIS_32 -nologo -W2 -Zd -c -Cx -DMASM6
ASMENV = ML

LFLAGS = /VXD /NOD

############## VxD device link rule ###################

.asm.obj:
#下面一行设置了环境变量 用上面定义的宏替换就是
#set ML=-coff -DBLD_COFF -DIS_32 -nologo -W2 -Zd -c -Cx -DMASM6
set $(ASMENV)=$(AFLAGS)
#当ML环境变量设置后,在执行ml就不必写命令行选项了
#下面一行就是引用规则,/Fo选项指定目标文件名
$(ASM) -Fo$*.obj $<

#下面是生成sym文件(即符号文件)的规则,
$(DEVICE).SYM: $(DEVICE).MAP
#mapsym.exe将map文件转换为sym文件
mapsym -s -o $(DEVICE).sym $(DEVICE).map


#下面是生成vxd和map文件的规则
$(DEVICE).VXD $(DEVICE).MAP: $(OBJS)
#这里涉及到两个重要的概念,响应文件(Response File)和内联文本(Inlinete
xt),
#响应文件作为link的输入,也是文本文件,它包括link所需的命令行选项和对提示的响应
#响应文件的用法是link @responsefile,并不要求特定的扩展名,这里的响应文件
#是serial.lnk。
#内联文本,写在make文件中的一段文本,与一个内联文件名对应,而内联文件要作为程序的输入
#如下面的serial.lnk和serial.def都是内联文件。
#"<<"作为一段内联文本的结束标志,可以看出serial.lnk是从“$(LFLAGS)”开始的
#而serial.def是从“VXD $(DEVICE) DYNAMIC”开始的。至于def文件的结构
link @<<$(DEVICE).lnk /DEF:<<$(DEVICE).def
#应该看得出下面的宏是link的命令行选项
$(LFLAGS)
#下面两行是对link程序提示的响应
#用过link的都知道它会问你输出文件和map文件名(这就是提示(prompt))
/OUT:$(DEVICE).VXD
/MAP:$(DEVICE).map
$(OBJS)
<<
#下面是def文件的结构,大家应该比较熟悉了吧,我也就不献丑了。
VXD $(DEVICE) DYNAMIC
DESCRIPTION '$(DEVICE) Device'

SEGMENTS
_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE
_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_PTEXT CLASS 'PCODE' NONDISCARDABLE
_PDATA CLASS 'PCODE' NONDISCARDABLE
_STEXT CLASS 'SCODE' RESIDENT
_SDATA CLASS 'SCODE' RESIDENT
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
_RCODE CLASS 'RCODE'
EXPORTS
$(DEVICE)_DDB @1
<<

clean:
-@del *.obj
-@del *.lib
-@del *.exp
-@del *.map
-@del *.sym
-@del *.vxd

...全文
187 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
oo 2004-07-12
不错。
文档中心有不少关于makefile的文章,写的很详细。
回复
yjh1982 2004-07-12
【C/C++ _非_值班室】?
回复
howler 2004-07-12
mark
回复
hunter20 2004-07-12
没怎么写过MakeFile文件,应该是8错的帖子,顶以下
回复
freefalcon 2004-07-12
up,支持

虽然目前大多数集成开发环境都不需要自己写makefile,但给有兴趣的朋友看看也是很好的
回复
expert2000 2004-07-12
太麻烦。IDE中一按编译或运行就搞定了。可能学习方向不一样。帮顶。。。。。。
回复
hcj2002 2004-07-12
学习中……
回复
sharkhuang 2004-07-12
初学级别.
回复
yoisyois 2004-07-12
mark
回复
kaphoon 2004-07-12
不好意思我以前保存了好几篇文档讲makefile的制作
只是没时间看
帮你up
回复
peter9606 2004-07-12
mark 偶不会makefile的
回复
BluntBlade 2004-07-12
好长,Mark下来慢慢看……顶!
回复
发帖
C语言
创建于2007-09-28

6.3w+

社区成员

C语言相关问题讨论
申请成为版主
帖子事件
创建了帖子
2004-07-12 01:13
社区公告
暂无公告