Share via


生成文件预处理

可以使用预处理指令和表达式来控制 NMAKE 会话。 预处理指令可以放置在生成文件或 Tools.ini 中。 使用指令,你可以有条件地处理生成文件、显示错误消息、包括其他生成文件、取消定义宏,以及打开或关闭某些选项。

生成文件预处理指令

预处理指令不区分大小写。 初始感叹号 (!) 必须出现在行的开头。 对于缩进,零个或零个以上的空格或选项卡可以在感叹号后面显示。

  • !CMDSWITCHES { +option | -option } ...

    打开或关闭每个列出的选项。 空格或选项卡必须显示在 +- 运算符之前。 运算符和选项字母之间不能显示空格。 字母不区分大小写,在指定时不能使用斜杠 (/)。 若要打开某些选项并关闭其他选项,请使用单独的 !CMDSWITCHES 规范。

    只能在生成文件中使用 /D/I/N/S。 在 Tools.ini 中,允许除 /F/HELP/NOLOGO/X/? 之外的所有选项。 在一个说明块中指定的更改在遇到下一个说明块之前不会生效。 此指令更新 MAKEFLAGS;如果指定 MAKEFLAGS,则会在递归期间继承更改。

  • !ERRORtext

    显示错误 U1050 中的文本,然后停止 NMAKE,即使使用了 /K/I.IGNORE!CMDSWITCHES 或短划线 (-) 命令修饰符。 忽略文本前的空格或制表符。

  • !MESSAGEtext

    将文本显示到标准输出。 忽略文本前的空格或制表符。

  • !INCLUDE [ < ] filename [ > ]

    将 filename 读取为生成文件,然后继续处理当前生成文件。 NMAKE 首先在指定或当前目录中搜索 filename,然后在任何父生成文件的目录中递归搜索,最后,如果 filename 括在尖括号 (< >) 内,则在由 INCLUDE 宏(最初设置为 INCLUDE 环境变量)指定的目录中搜索。 用于将 .SUFFIXES 设置、.PRECIOUS 和推理规则传递到递归生成文件。

  • constant_expression

    如果 constant_expression 的计算结果为非零值,则处理 !IF 和下一个 !ELSE!ENDIF 之间的语句。

  • !IFDEFmacro_name

    如果 macro_name 已定义,则处理 !IFDEF 和下一个 !ELSE!ENDIF 之间的语句。 将 null 宏视为已定义。

  • !IFNDEFmacro_name

    如果 macro_name 未定义,则处理 !IFNDEF 和下一个 !ELSE!ENDIF 之间的语句。

  • !ELSE [ IFconstant_expression | IFDEFmacro_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

另请参阅

NMAKE 参考