上一页 | 目录 | 下一页

5.4 条件编译

编译器有一个定义符号列表,定义符号可以通过 !define 定义或使用 /D 命令行切换。这些定义符号可以用于条件编译 (通过 !ifdef 定义) 或用于符号替换(一种格式简单的宏)。若要用它的值替换一个符号,请使用 ${符号} (如果 "符号" 没有定义,那么不会产生转换)。这个转换为先到先得(first-come-first-served),这意味着如果你做了:

!define 符号1 ${符号2}

如果定义了 "${符号2}" ,那么当出现那一行时,它将会被替换。否则,当 ${符号1} 被引用时,任何替换都会发生。

与定义、条件编译相关的命令:

5.4.1 !define

([/date|/utcdate] 符号 [值]) | (/math 符号 值1 运算符 值2) | (/file 符号 filename.txt)

这个命令将会向全局定义列表中添加 符号。这个效果与编译器使用 /D 命令行切换效果相似(只有在 !define 命令之后,定义才有效)。

如果使用了 /date/utcdate 将被传递到 strftime 中并且结果将会作为 符号 值使用。strftime 会把代表当前的时间日期转换为实际的值。例如, %H 会转换为当前时间的24小时格式。完整的可用符号列表可以在 MSDN 上查找 strftime。在 POSIX 平台,你可以使用 man strftime 来获取列表。

如果使用了 /math ,把(值1 运算符 值2)的运算结果作为 符号 的定义值。“运算符” 在这里可以是 +,-,*,&,|,^,/ 或 % 。请注意,值1 和 值2 都必须为整型值!

如果使用了 /file ,把指定的整个文本文件(包括空白和新行)读取并填充到 符号 中。

!define USE_SOMETHING
!define VERSION 1.2
!define /date NOW "%H:%M:%S %d %b, %Y"
!define /math RESULT 3 + 10
!define /math REST 15 % ${RESULT}
!define /file BUNCHASTUFF somesourcefile.cpp

5.4.2 !undef

符号

从全局定义列表中移除一个已定义的符号。请注意,取消定义符号的地方(${符号})将会自己转换为 "${符号}"。

!define SOMETHING
!undef SOMETHING

5.4.3 !ifdef

符号 [布尔逻辑符号 符号 [...]]]

当这个命令与 !endif 命令组成一对时,将会告诉编译器是否编译含在其两者之间的代码。如果 符号 被全局定义了(使用 !define 或 the /D 进行切换),那么所含的代码将会被编译。否则,那些代码将会被跳过。布尔逻辑符号可以在更多的 宏名称 之间被指定为 & (布尔与) 或 | (布尔或) -- 优先顺序很简单,从左到右。

!define SOMETHING
!ifdef SOMETHING
  !echo "SOMETHING is defined"
!endif
!undef SOMETHING
!ifdef SOMETHING
  !echo "SOMETHING is defined" # will never be printed
!endif

5.4.4 !ifndef

符号 [布尔逻辑符号 符号 [...]]]

它与 !ifdef 正好相反。当 符号 没有被定义时,代码将会被编译。

5.4.5 !if

[!] 值 [运算符 值2]

当这个命令与 !endif 命令组成一对时,将会告诉编译器是否编译含在其两者之间的代码。如果 为非零或者 值2 的逻辑运算结果为真,那么所含的代码将会被编译。否则,那些代码将会被跳过。 运算符 可以是 == or != (字符串比较), <=, < > 或 >= (实数比较), && or || (布尔运算)。 如果设置了 [!] ,则逻辑运算结果取非。

!if 1 < 2
  !echo "1 is smaller than 2!!"
!else if ! 3.1 > 1.99
  !error "this line should never appear"
!else
  !error "neither should this"
!endif

5.4.6 !ifmacrodef

宏名称 [布尔逻辑符号 宏名称 [...]]]

当这个命令与 !endif 命令组成一对时,将会告诉编译器是否编译在其两者之间的代码。如果宏 宏名称 存在,那么所含的代码将会被编译。否则,那些代码将会被跳过。布尔逻辑符号可以在更多的 宏名称 之间被指定为 & (布尔与) 或 | (布尔或) -- 优先顺序很简单,从左到右。

!macro SomeMacro
!macroend
!ifmacrodef SomeMacro
  !echo "SomeMacro is defined"
!endif

5.4.7 !ifmacrondef

宏名称 [布尔逻辑符号 宏名称 [...]]]

它与 !ifmacrodef 正好相反。当 宏名称 不存在时,代码块将会被编译。

5.4.8 !else

[if|ifdef|ifndef|ifmacrodef|ifmacrondef [...]]

当有不同的定义或设置了不同的宏时,这个命令允许轻松插入不同的代码。你可以创建类似 !ifdef/!else/!endif, !ifdef/!else ifdef/!else/!endif 等代码块。

!ifdef VERSION
OutFile installer-${VERSION}.exe
!else
OutFile installer.exe
!endif

5.4.9 !endif

这个命令用于关闭以 !if, !ifdef, !ifndef, !ifmacrodef 或 !ifmacrondef 起始的代码块。

5.4.10 !insertmacro

宏名称 [参数] [...]

插入一个由 !macro 创建的宏的内容。如果创建的宏带有参数,那么你必须按宏的需求向它传送足够的参数。

!macro Print text
  DetailPrint "${text}"
!macroend
!insertmacro Print "some text"
!insertmacro Print "some more text"

5.4.11 !macro

宏名称 [参数][...]

创建一个名为 "宏名称" 的宏。所有在 !macro 与 !macroend 之间的代码行都会被保存。若要稍后插入宏,请使用 !insertmacro 。!macro 定义可以有一个或多个定义的参数。这些参数可以按相同的方式被访问,宏参数会被依次定义(例如:${PARMNAME})且在宏结束的时候依次取消定义。

!macro SomeMacro parm1 parm2 parm3
  DetailPrint "${parm1}"
  MessageBox MB_OK "${parm2}"
  File "${parm3}"
!macroend

5.4.12 !macroend

结束一个以 !macro 为起始的宏。

5.4.13 !searchparse

[/ignorecase] [/noerrors] [/file] 源字符串或文件 子字符串开始 输出符号1 [子字符串 [输出符号2 [子字符串 ...]]]

从语法上分析 源字符串或文件(被视为一个字符串或者如果设置了 /file 则被视为一个文件名)是查找子字符串开始。如果发现子字符串开始,那么输出符号1被定义为字符串其余部分(减去任何其他可以找到的子字符串)。可以指定任意数量的输出符号x并且最后的子字符串是可选的。

如果指定了 /noerrors ,则将允许匹配小于全部数量的字符串 (所有输出符号x在没有发现子字符串之后会被忽略)。

如果指定了 /file 文件会被视为一连串的行。该文件被搜索直到所有子字符串都匹配过。如果指定了 /noerrors 并且不是所有字符串都匹配,那么匹配最多的符号会被作为第一行使用。

# 查找 filename.cpp 中的一行 '#define APP_VERSION "2.5"' 并且设置 ${VER_MAJOR} 为 2, ${VER_MINOR} 为 5。
!searchparse /file filename.cpp `#define APP_VERSION "` VER_MAJOR `.` VER_MINOR `"`

5.4.14 !searchreplace

[/ignorecase] 符号输出 源字符串 搜索字符串 替换字符串

查找源字符串。在源字符串中搜索搜索字符串并使用替换字符串替换所有实例。不像 !define, !searchreplace 允许你重新定义没有警告或错误的符号输出

# ${blah} 被定义为 "i like ponies"
!searchreplace blah "i love ponies" "love" "like"

上一页 | 目录 | 下一页