本节将介绍 Boost.Jam 语言的基础知识,足以编写 Jamfiles。有关更多信息,请参阅 Boost.Jam 文档。
Boost.Jam 具有解释性的过程式语言。在最低级别,一个 Boost.Jam 程序由变量和 规则(Jam 中对函数的称呼)组成。它们被分组到模块中,有一个全局模块和多个命名模块。除此之外,一个 Boost.Jam 程序还包含类和类实例。
从语法上讲,一个 Boost.Jam 程序由两种元素组成:关键字(对 Boost.Jam 具有特殊含义)和字面量。考虑这段代码
a = b ;
它将值 b
赋值给变量 a
。这里,=
和 ;
是关键字,而 a
和 b
是字面量。
所有语法元素,即使是关键字,都必须用空格分隔。例如,省略 ;
之前的空格字符会导致语法错误。
如果要使用与某些关键字相同的字面量值,可以将该值用引号引起来
a = "=" ;
在 Boost.Jam 中,所有变量都具有相同的类型:字符串列表。要定义变量,请像前面的示例一样为它赋值。未定义的变量与具有空值的变量相同。可以使用 $(
语法访问变量。例如variable
)
a = $(b) $(c) ;
规则通过指定规则名称、参数名称以及每个参数允许的值列表大小来定义。
ruleexample
(parameter1
:parameter2 ?
:parameter3 +
:parameter4 *
) { # rule body }
调用此规则时,作为第一个参数传递的列表必须恰好包含一个值。作为第二个参数传递的列表可以包含一个值,也可以为空。其余两个参数可以任意长,但第三个参数不能为空。
下面是 Boost.Jam 语言语句的概述
helper 1 : 2 : 3 ; x = [ helper 1 : 2 : 3 ] ;
此代码使用指定参数调用命名规则。当需要在某个表达式内部使用调用的结果时,需要在调用周围添加括号,如第二行所示。
if cond { statements } [ else { statements } ]
这是一个普通的 if 语句。条件由以下部分组成:
字面量(如果至少有一个字符串非空,则为真)
比较:a
,其中 operator
boperator
是 =
、!=
、<
、>
、<=
或 >=
之一。比较是在左、右参数的每个字符串之间成对执行。
逻辑运算:! a
、a && b
、a || b
分组:( cond )
for var in list { statements }
对列表中的每个元素执行语句,将变量 var
设置为元素值。
while cond { statements }
重复执行语句,直到 cond 在进入时保持为真。
return values ;
此语句应仅在规则内部使用,并将 values
赋值给规则的返回值。
该 return
语句不会退出规则。例如
rule test ( ) { if 1 = 1 { return "reasonable" ; } return "strange" ; }
将返回 strange
,而不是 reasonable
。
importmodule
; importmodule
:rule
;
第一种形式导入指定的模块。该模块中的所有规则都将使用限定名称可用:
。第二种形式仅导入指定的规则,并且可以使用非限定名称调用它们。 module
.rule
有时,需要指定在创建目标时要使用的实际命令行。在 jam 语言中,可以使用命名操作来执行此操作。例如
actions create-file-from-another { create-file-from-another $(<) $(>) }
这指定了一个名为 create-file-from-another
的命名操作。花括号内的文本是要调用的命令。$(<)
变量将扩展到一个生成的文件列表,而 $(>)
变量将扩展到一个源文件列表。
为了灵活地调整命令行,可以定义一个与操作名称相同的规则,并接受三个参数:目标、源和属性。例如
rule create-file-from-another ( targets * : sources * : properties * ) { if <variant>debug in $(properties) { OPTIONS on $(targets) = --debug ; } } actions create-file-from-another { create-file-from-another $(OPTIONS) $(<) $(>) }
在此示例中,规则检查是否指定了某个构建属性。如果是,则设置变量 OPTIONS
,然后在操作内部使用它。请注意,在目标上设置的变量仅在构建该目标的操作内部可见,而不是全局可见。如果它们在全局设置,则在两个不相关的操作中使用名为 OPTIONS
的变量将是不可能的。
更多详细信息可以在 Jam 参考中找到,名为“规则”的部分。