生成文件预处理
可以使用预处理指令和表达式来控制 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
和推理规则传递到递归生成文件。!IF
constant_expression如果 constant_expression 的计算结果为非零值,则处理
!IF
和下一个!ELSE
或!ENDIF
之间的语句。!IFDEF
宏_name如果 macro_name 已定义,则处理
!IFDEF
和下一个!ELSE
或!ENDIF
之间的语句。 将 null 宏视为已定义。!IFNDEF
宏_name如果 macro_name 未定义,则处理
!IFNDEF
和下一个!ELSE
或!ENDIF
之间的语句。!ELSE
[IF
constant_expression |IFDEF
宏_name |IFNDEF
宏_name ]如果前面的
!IF
、!IFDEF
或!IFNDEF
语句的计算结果为零,则处理!ELSE
与下一个!ENDIF
之间的语句。 可选关键字可进一步控制预处理。!ELSEIF
!ELSE IF
的同义词。!ELSEIFDEF
!ELSE IFDEF
的同义词。!ELSEIFNDEF
!ELSE IFNDEF
的同义词。!ENDIF
标记
!IF
、!IFDEF
或!IFNDEF
块的末尾。 忽略同一行中!ENDIF
之后的任何文本。!UNDEF
宏_name取消定义 macro_name。
生成文件预处理中的表达式
!IF
或!ELSE IF
constant_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( 宏_name ) |
为 macro_name 的当前定义状态生成一个逻辑值。 |
EXIST( 路径 ) |
为 path 上存在的文件生成一个逻辑值。 |
! |
一元逻辑“非”。 |
~ |
一元 1 的补数。 |
- |
一元求反。 |
* |
乘。 |
/ |
除。 |
% |
取模(余数)。 |
+ |
加。 |
- |
减。 |
<< |
按位左移。 |
>> |
按位右移。 |
<= |
小于或等于。 |
>= |
大于或等于。 |
< |
小于。 |
> |
大于。 |
== |
相等。 |
!= |
不相等。 |
& |
按位“与”。 |
^ |
位异或。 |
| |
位或。 |
&& |
逻辑 AND。 |
|| |
逻辑 OR。 |
注意
按位“异或”运算符 (^
) 与转义符相同,当在表达式中使用该运算符时,必须对其进行转义(如 ^^
)。
在预处理中执行程序
若要在预处理期间使用某个命令的退出代码,请在括号内指定带任意参数的该命令 ([ ]
)。 在执行命令之前,将展开任何宏。 NMAKE 将命令规范替换为命令的退出代码,该代码可用在表达式中来控制预处理。
示例
!IF [my_command.exe arg1 arg2] != 0
!MESSAGE my_command.exe failed!
!ENDIF