分享

nmake.exe使用整理

 量子记忆 2020-02-24

    具体可以参考罗云彬先生的《Windows环境下32位汇编语言程序设计》

    我现在编译汇编程序的主要工具有两个。

    一个是RadASM,这是一个集成的IDE使用起来非常的方便,资源编辑器,调试器等全都帮你配置好了,也许要设置一下执行的环境变量但基本使用是没什么问题。

    还有一个是MASM32 SDK软件包(下载:http:///)。但是有一个点很麻烦,就是汇编程序的编译链接都是要自己来的,即使MASM32提供了很完整的工具,但是在dos下打这几个命令还是要花很多时间,有没有办法可以让这个过程变得简洁? nmake工具就可以做到。其实就是make工具,类似一个批处理工具,能够把一系列的操作和命令集合起来一起执行,下面开始总结一下nmake的使用方法和参数,该工具可在VC++中Bin目录下找到:

    注意: nmake的这种make工具需要一个描述文件一般默认叫makefile,需要自己创建,改名

    你可以直接在nmake.exe所在目录下用命令行窗口打出nmake /?就可以看到如图的帮助信息:


nmake的语法:

    nmake [选项] [ /f makefile ] [ /x stderrfile ] [ macrodefs ] [ targets ]

/f: nmake需要一个类似于文件来指导nmake的工作,就像你编写程序,编译器来执行一样。这个文件名字默认是makefile,如果你想改,那就用/f选项后面跟你要的文件名字。

/x:如果你想把nmake的输出信息保存在一个文件里那就用这个选项,比如nmake /x a.txt。那么nmake所输出的执行信息都会存储在a.txt中。类似Linux或dos中的重定向,但是这里是/x选项

macrodefs:用新的定义覆盖描述文件中的宏定义

目标: 在makefile中执行哪一条(下面详细说明)

/A:不检测文件时间,强制更新所有文件

/B:文件时间相等时也更新文件

/D:make时显示文件新旧信息

/N:make时显示执行命令但并不真正执行

/P:make时显示详细信息

PS:nmake是基于时间的,如果电脑时钟有问题或者拷贝到另一台电脑,那么可能导致文件更新不准,可用/A选项强制更新

描述文件的语法:

1.注释和换行

与Linux的shell脚本一样,用#作为注释。 \是换行符 如果一条命令太长,可以用\来换一行写。下面会举例子

2.宏定义

你可以用一些变量来定义一个或多个常量。比如WORKPATH=C:\\Users\\..... 之类,你用的时候就可以直接打$(WORKPATH)或者$WORKPATH就可以了。感觉和Linux中的${xxxx} 很像吧?

几个特殊的内定宏:

a. $@ ----> 全路径的目标文件

b. $*  ----> 除去扩展名的全路径目标文件

c.$?  ----> 全部的源文件名

d.$< ----> 源文件名 (只能用在隐式规则里,隐式规则在下方第4点)

3.显式规则

这种就是如果你打入了nmake就会直接执行的规则,有两种语法写:

第一种是:    目标文件: 依赖文件; 命令

第二种是:    目标文件: 依赖文件 \n\t命令 (这里的\n\t意思是先一个回车换行,然后在下一行打一个tab键在开始写命令)

;分割线之前是宏定义,就是上面第二小点, 这里定义后面变量可以有多个,比如OBJ = a.obj b.obj都是可以的
ASM = a.asm 
OBJ = a.obj
EXE = test.exe

#如果是Win32就是windows
LINK_FLAG = /subsystem:console 
ML_FLAG = /c /coff
#下面是显式规则-----------------------
#第一种写法, 这里是编译汇编程序
#这句话的意思是如果要生成$(OBJ)文件就必
#须具备 $(ASM)文件,分号后面是命令,那些#变量照着上面宏定义看就行了
$(OBJ):$(ASM); ml $(ML_FLAG) $(ASM)
#第二种写法
#唯一的区别就是分号变成了换一行然后打个#TAB在输入命令,这是链接过程
$(EXE):$(OBJ)
	Link $(LINK_FLAG) $(OBJ) /out:test.exe


如果你仅仅只想执行其中的某一步比如说编译,那么你可以:直接打入nmake /x makefile_new a.obj,就行了,也就是(目标文件: 依赖文件 \n\t命令)中的目标文件那对应的东西。 


我目录里有两个描述文件,如果你用的是Makefile(默认)中的规则,那你就:


便可全部执行。不用加/x

4.隐式规则

大体和显式规则相同,如下:

第一种是:    .源扩展名.目标扩展名:   ;命令

第二种是:    .源扩展名.目标扩展名:\n\t命令 (扩展名就是比如text.txt中,那个"txt"就是扩展名)

ASM = a.asm
OBJ = a.obj
EXE = test.exe
LINK_FLAG = /subsystem:console
ML_FLAG = /c /coff

#显式规则
$(OBJ):$(ASM); ml $(ML_FLAG) $(ASM)


$(EXE):$(OBJ)
	Link $(LINK_FLAG) $(OBJ) /out:test.exe

#隐式规则
#第一种写法
.asm.obj: ;ml $(ML_FLAG) $<

#第二种写法
.obj.exe:
	Link $(LINK_FLAG) $<

clean:  #如果要执行就需要打nmake clean才会执行(默认描述文件为makefile)
	del *.obj
	del .exe
值得注意的是: 隐式规则由于不能有依赖文件,所以冒号后面是啥也没有。还有其命令中不能包含文件名,它后面跟的都是一类相同扩展名的整类文件,所以用上面说的内定宏来描述。比如.asm.obj ;ml $(ML_FLAG) $<中的$<就代表源文件名就是.asm扩展名的文件。
ASM = a.asm
OBJ = a.obj
EXE = test.exe
LINK_FLAG = /subsystem:console
ML_FLAG = /c /coff

#显式规则
$(OBJ):$(ASM); ml $(ML_FLAG) $(ASM)


$(EXE):$(OBJ)
	Link $(LINK_FLAG) $(OBJ) /out:test.exe



#如果如下那种显式规则没有命令的,那么它们会去隐式规则中找命令
#下面这句的意思是如果Common.inc存在的话,为了产生$(OBJ), 就找到来执行
$(OBJ):Common.inc	
a.obj: a.inc



.asm.obj: ;ml $(ML_FLAG) $<


.obj.exe:
	Link $(LINK_FLAG) $<

clean: 
	del *.obj
	del .exe

(完)

    

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多