可以使用预处理指令和表达式来控制 NMAKE 会话。 预处理指令可以放置在生成文件或 Tools.ini 中。 使用指令,你可以有条件地处理生成文件、显示错误消息、包括其他生成文件、取消定义宏,以及打开或关闭某些选项。
生成文件预处理指令
预处理指令不区分大小写。 初始感叹号 (!) 必须出现在行的开头。 对于缩进,零个或零个以上的空格或选项卡可以在感叹号后面显示。
!CMDSWITCHES{+option |-option } ...打开或关闭每个列出的选项。 空格或选项卡必须显示在
+或-运算符之前。 运算符和选项字母之间不能显示空格。 字母不区分大小写,在指定时不能使用斜杠 (/)。 若要打开某些选项并关闭其他选项,请使用单独的!CMDSWITCHES规范。只能在生成文件中使用
/D、/I、/N和/S。 在Tools.ini中,允许除/F、/HELP、/NOLOGO、/X、/?之外的所有选项。 在一个说明块中指定的更改在遇到下一个说明块之前不会生效。 此指令更新MAKEFLAGS;如果指定MAKEFLAGS,则会在递归期间继承更改。!ERROR发短信显示错误 U1050 中的文本,然后停止 NMAKE,即使使用了
/K、/I、.IGNORE、!CMDSWITCHES或短划线 (-) 命令修饰符。 忽略文本前的空格或制表符。!MESSAGE发短信将文本显示到标准输出。 忽略文本前的空格或制表符。
!INCLUDE[<] filename [>]将 filename 读取为生成文件,然后继续处理当前生成文件。 NMAKE 首先在指定或当前目录中搜索 filename,然后在任何父生成文件的目录中递归搜索,最后,如果 filename 括在尖括号 (
< >) 内,则在由INCLUDE宏(最初设置为INCLUDE环境变量)指定的目录中搜索。 用于将.SUFFIXES设置、.PRECIOUS和推理规则传递到递归生成文件。!IFconstant_expression如果 constant_expression 的计算结果为非零值,则处理
!IF和下一个!ELSE或!ENDIF之间的语句。!IFDEFmacro_name如果 macro_name 已定义,则处理
!IFDEF和下一个!ELSE或!ENDIF之间的语句。 将 null 宏视为已定义。!IFNDEFmacro_name如果 macro_name 未定义,则处理
!IFNDEF和下一个!ELSE或!ENDIF之间的语句。!ELSE[IFconstant_expressionIFDEF| macro_name |IFNDEFmacro_name ]如果前面的
!IF、!IFDEF或!IFNDEF语句的计算结果为零,则处理!ELSE与下一个!ENDIF之间的语句。 可选关键字可进一步控制预处理。!ELSEIF!ELSE IF的同义词。!ELSEIFDEF!ELSE IFDEF的同义词。!ELSEIFNDEF!ELSE IFNDEF的同义词。!ENDIF标记
!IF、!IFDEF或!IFNDEF块的末尾。 忽略同一行中!ENDIF之后的任何文本。!UNDEFmacro_name取消定义 macro_name。
生成文件预处理中的表达式
!IF或!ELSE IFconstant_expression由整数常量(以十进制或 C 语言表示法)、字符串常量或命令组成。 使用括号对表达式进行分组。 表达式使用 C 样式的带符号长整型算术;数字采用 32 位 2 的补数形式,其范围为 -2147483648 到 2147483647。
表达式可以使用在常数值、命令的退出代码、字符串、宏和文件系统路径上使用的运算符。
生成文件预处理运算符
生成文件预处理表达式可以使用在常数值、命令的退出代码、字符串、宏和文件系统路径上使用的运算符。 若要计算该表达式,预处理器应先展开宏、执行命令,然后再执行运算。 它的运算先按括号中的显式分组进行,然后再按运算符优先级进行。 该结果是一个常数值。
DEFINED 运算符是宏名称上使用的逻辑运算符。 如果已定义 macro_name,则即使没有赋值,表达式 DEFINED( macro_name ) 仍为 true。 DEFINED 与 !IF 或 !ELSE IF 一起使用等效于 !IFDEF 或 !ELSE IFDEF。 但是,与这些指令不同,DEFINED 可用在复杂表达式中。
EXIST 运算符是文件系统路径上使用的逻辑运算符。 如果 path 存在,则 EXIST( path ) 为 true。 EXIST 的结果可用在二进制表达式中。 如果 path 包含空格,则用双引号将它引起来。
若要比较两个字符串,请使用相等 (==) 运算符或不相等 (!=) 运算符。 用双引号将字符串引起来。
整数常数可以将一元运算符用于数字求反 (-)、1 的补数 (~) 和逻辑求反 (!)。
表达式可使用以下运算符。 将相同优先级的运算符分组在一起,分组将按优先级递减的顺序列出。 一元运算符向右关联操作数。 相同优先级的二元运算符按照从左到右的顺序关联操作数。
| 运算符 | 说明 |
|---|---|
DEFINED(macro_name ) |
为 macro_name 的当前定义状态生成一个逻辑值。 |
EXIST(路径 ) |
为 path 上存在的文件生成一个逻辑值。 |
! |
一元逻辑“非”。 |
~ |
一元 1 的补数。 |
- |
一元求反。 |
* |
乘。 |
/ |
除。 |
% |
取模(余数)。 |
+ |
加。 |
- |
减。 |
<< |
按位左移。 |
>> |
按位右移。 |
<= |
小于或等于。 |
>= |
大于或等于。 |
< |
小于。 |
> |
大于。 |
== |
相等。 |
!= |
不相等。 |
& |
按位“与”。 |
^ |
位异或。 |
| |
位或。 |
&& |
逻辑 AND。 |
|| |
逻辑 OR。 |
注意
按位“异或”运算符 (^) 与转义符相同,当在表达式中使用该运算符时,必须对其进行转义(如 ^^)。
在预处理中执行程序
若要在预处理期间使用某个命令的退出代码,请在括号内指定带任意参数的该命令 ([ ])。 在执行命令之前,将展开任何宏。 NMAKE 将命令规范替换为命令的退出代码,该代码可用在表达式中来控制预处理。
示例
!IF [my_command.exe arg1 arg2] != 0
!MESSAGE my_command.exe failed!
!ENDIF