1 <embedded image>

2 Front Matter

2.1 Title

2.1.1 The BUSY Build System - Language and Built-ins Specification

2.2 Version

2.2.1 2023-02-12

2.3 Author

2.3.1 me@rochus-keller.ch

2.4 Additional Credits

2.4.1 The sections 4 Predeclared Class Reference and 5 Predeclared Field Reference are derived from the help text included in GN (gn.googlesource.com/.../ as of July 2019), copyright (c) 2013 by The Chromium Authors, made available under a BSD-style license.
2.4.2 A lot of text is derived from the Oberon+ language specification, github.com/.../specification
2.4.3 This specification was written in CrossLine (see github.com/.../CrossLine)

2.5 Table of Contents

2.5.1 3 Language Specification
2.5.1.1 3.1 Introduction
2.5.1.2 3.2 Syntax
2.5.1.3 3.3 Vocabulary and Representation
2.5.1.3.1 3.3.3 Identifiers
2.5.1.3.2 3.3.4 Booleans
2.5.1.3.3 3.3.5 Numbers
2.5.1.3.4 3.3.6 Strings
2.5.1.3.5 3.3.7 Symbols
2.5.1.3.6 3.3.8 Paths
2.5.1.3.7 3.3.9 Operators and Delimiters
2.5.1.3.8 3.3.10 Reserved Words
2.5.1.3.9 3.3.11 Comments
2.5.1.4 3.4 Declarations and scope rules
2.5.1.5 3.5 Type declarations
2.5.1.5.1 3.5.3 Basic types
2.5.1.5.2 3.5.4 Class types
2.5.1.5.3 3.5.5 Enumeration types
2.5.1.5.4 3.5.6 List types
2.5.1.6 3.6 Variable declarations
2.5.1.7 3.7 Expressions
2.5.1.7.1 3.7.2 Operands
2.5.1.7.2 3.7.3 Operators
2.5.1.7.2.1 3.7.3.3 Logical operators
2.5.1.7.2.2 3.7.3.4 Arithmetic operators
2.5.1.7.2.3 3.7.3.5 Relations
2.5.1.7.2.4 3.7.3.7 Function Call
2.5.1.8 3.8 Statements
2.5.1.9 3.9 Macros
2.5.1.10 3.10 Modules
2.5.1.11 3.11 Alternative Syntax
2.5.2 4 Predeclared Class Reference
2.5.2.1 4.1 Config
2.5.2.2 4.2 Product
2.5.2.2.1 4.2.3 ConfigurableProduct
2.5.2.2.1.1 4.2.3.1 CompiledProduct
2.5.2.2.1.1.1 4.2.3.1.4 Executable
2.5.2.2.1.1.2 4.2.3.1.5 Library
2.5.2.2.1.1.3 4.2.3.1.6 SourceSet
2.5.2.2.2 4.2.4 Group
2.5.2.2.3 4.2.5 Action
2.5.2.2.3.1 4.2.5.1 Script
2.5.2.2.3.1.1 4.2.5.1.2 LuaScript
2.5.2.2.3.1.2 4.2.5.1.3 LuaScriptForeach
2.5.2.2.3.2 4.2.5.2 Message
2.5.2.2.3.3 4.2.5.3 Moc
2.5.2.2.3.4 4.2.5.4 Rcc
2.5.2.2.3.5 4.2.5.6 Copy
2.5.3 5 Predeclared Field Reference
2.5.4 6 Predeclared Enumeration Reference
2.5.5 7 Predeclared Variable Reference
2.5.6 8 Predeclared Procedure Reference

3 Language Specification

3.1 Introduction

3.1.1 BUSY (for BUild SYstem) is a lean, cross-platform build system with very little system requirements and easy bootsrapping.
3.1.2 The BUSY build specifcation language features modularity, information hiding, static typing with strong type checking, immutability and garbage collection. The language is not a full programming language by intention.
3.1.3 This report is not intended as a programmer’s tutorial. It is intentionally kept concise. Its function is to serve as a reference for programmers, implementors, and tutorial writers. What remains unsaid is mostly left so intentionally, either because it can be derived from stated rules of the language, or because it would require to commit the definition when a general commitment appears as unwise.

3.2 Syntax

3.2.1 An extended Backus-Naur Formalism (EBNF) is used to describe the syntax of BUSY:
3.2.1.1 Alternatives are separated by |.
3.2.1.2 Brackets [ and ] denote optionality of the enclosed expression.
3.2.1.3 Braces { and } denote its repetition (possibly 0 times).
3.2.1.4 Syntactic entities (non-terminal symbols) are denoted by English words expressing their intuitive meaning.
3.2.1.5 Symbols of the language vocabulary (terminal symbols) are denoted by strings formatted in bold face.

3.3 Vocabulary and Representation

3.3.1 BUSY source code is a string of characters encoded using the UTF-8 variable-width encoding as defined in ISO/IEC 10646. Numbers, operators, keywords and delimiters are represented using the ASCII character set; identifiers, strings, symbols, paths and comments are represented using the Unicode Basic Multilingual Plane (BMP, plane 0, as defined in ISO/IEC 10646) character set.
3.3.2 The following lexical rules apply: blanks and line breaks must not occur within symbols (except in block comments, and blanks in strings); they are ignored unless they are essential to separate two consecutive symbols. Capital and lower-case letters are considered as distinct.

3.3.3 Identifiers

3.3.3.1 Identifiers are sequences of unicode letters, unicode digits and underscore. The first character must be a unicode letter or an underscore.

3.3.4 Booleans

3.3.4.1 Boolean literals are represented by the keywords true and false.

3.3.5 Numbers

3.3.5.1 Number literals are (unsigned) integer or real constants. If the literal is specified with the prefix 0x, the representation is hexadecimal, otherwise the representation is decimal.
3.3.5.2 A real number always contains a decimal point and at least one digit before the point. Optionally it may also contain a decimal scale factor. The letter e means times ten to the power of.

3.3.6 Strings

3.3.6.1 Strings are sequences of printable unicode characters enclosed in " (quote marks). A string may extend over the end of a line; the enclosed end of line characters are part of the string. Strings use backslash as the escape character. The only escape sequences supported are:
3.3.6.1.1 \" (for literal quote)
3.3.6.1.2 \\ (for literal backslash)

3.3.7 Symbols

3.3.7.1 Symbols are interned strings consisting of unicode letters, unicode digits and underscores; symbols are prefixed by ` (backquote, ASCII 0x60).

3.3.8 Paths

3.3.8.1 A path is an abstraction of a file system absolute or relative file or directory path. A path is a sequence of zero or more name segments, separated by the / (slash) character, with a path prefix. The current module is the reference for relative path resolution (see 3.10 Modules). The following path prefixes are supported:
3.3.8.1.1 // (for an absolute path in Unix file systems)
3.3.8.1.2 a // followed by one ASCII letter followed by one : (colon, for an absolute path in Windows file systems)
3.3.8.1.3 ./ (for a path relative to the directory represented by the current module)
3.3.8.1.4 ../ (for a path relative to the directory immediately above the directory represented by the current module)
3.3.8.1.5 a sequence of two or more ../
3.3.8.2 A name segment consists of a sequence of one or more printable unicode characters. A name segment cannot include the following characters: / \ ? * : | " < > , ; = . A name segment cannot include sequences of . (dot).
3.3.8.3 If a name segment includes unicode characters which qualify as white space (blanks), the path must be enclosed in ' (tick marks); line breaks in name segments are not allowed.
3.3.8.4 If a path is enclosed in ' (tick marks), the ./ path prefix is optional.
3.3.8.5 As a special case, a path may consist only of one of the following character combinations:
3.3.8.5.1 // (for the absolute root in a Unix file system)
3.3.8.5.2 a // followed by one ASCII letter followed by one : (colon, for the absolute root in a Windows file system)
3.3.8.5.3 . (for the directory represented by the current module)
3.3.8.5.4 .. (for the directory immediately above directory represented by the current module)
3.3.8.5.5 a sequence of one or more ../ followed by ..

3.3.9 Operators and Delimiters

3.3.9.1 Operators and delimiters are the special characters, or character pairs listed here:
3.3.9.1.1 ! != # % && || ( ) * /* */ *= -= += + - ; , . / : := < <= = == > >= ? [ ] [] ^ ` { }

3.3.10 Reserved Words

3.3.10.1 The reserved words (keywords) consist of all lower case letters and cannot be used as identifiers. All words listed here are reserved:
3.3.10.1.1 begin class else elsif end false if in let param submod submodule then true type var
3.3.10.2 In addition the following words are reserved for future extensions:
3.3.10.2.1 include import is module
3.3.10.3 Deprecated:
3.3.10.3.1 subdir

3.3.11 Comments

3.3.11.1 Comments are arbitrary character sequences opened by the bracket /* and closed by */. Comments may be nested. They do not affect the meaning of a program. BUSY also supports line comments; text starting with # up to a line break is considered a comment.

3.4 Declarations and scope rules

3.4.1 Every identifier occurring in a BUSY file must be introduced by a declaration, unless it is a predeclared identifier. Declarations also specify certain permanent properties of an object, such as whether it is a constant, a type, or a variable. The identifier is then used to refer to the associated object.
3.4.2 The scope of an object x extends textually from the point of its declaration to the end of the block (module, constructor, condition, or class) to which the declaration belongs and hence to which the object is local. It excludes the scopes of equally named objects which are declared in nested blocks. The scope rules are:
3.4.2.1 No identifier may denote more than one object within a given scope (i.e. no identifier may be declared twice in a block)
3.4.2.2 An object may only be referenced within its scope
3.4.2.3 Identifiers denoting class fields are valid in class designators only
3.4.3 If a module N constitutes module M using a submod declaration (see 3.10 Modules), the BUSY file in the file system directory of M becomes a nested module of N; this relation is recursive.
3.4.4 An identifier declared in a module may be followed by an export mark (*, - or !) in its declaration to indicate that it is visible to either both outer and nested modules (* and !), or only to nested modules (-).
3.4.5 Syntax:
3.4.5.1 identdef ::= ident ['*'|'-'|'!']
3.4.5.2 declaration ::= vardecl | typedecl
3.4.5.3 designator ::= ['^'|'.'] ident { '.' ident }
3.4.6 A nested module M can access a visible identifier x declared in an outer module N by ^x, if it was declared before the submod M declaration in N (^ is the outer module operator). A module N can access an identifier y declared in a nested module by M.x, but only after the submod M declaration
3.4.7NOTE This implies that a nested module cannot reference objects declared after the submod declaration in the outer modules which (directly or indirectly) references the nested module.
3.4.8 The identifiers in section 4 Predeclared Class Reference, 5 Predeclared Field Reference, 6 Predeclared Enumeration Reference, 7 Predeclared Variable Reference, and 8 Predeclared Procedure Reference are predeclared; their meaning is defined in the indicated sections.

3.5 Type declarations

3.5.1 A data type determines the set of values which variables of that type may assume, and the operators that are applicable. A type declaration associates an identifier with a type. In the case of class types it also defines the structure of variables of this type.
3.5.2 Syntax:
3.5.2.1 typedecl ::= type identdef '=' ( enumdecl | classdecl )

3.5.3 Basic types

3.5.3.1 The basic types are denoted by predeclared identifiers. The associated operators are defined in 3.7.3 Operators. The values of the given basic types are the following:
3.5.3.1.1 bool (see 3.3.4 Booleans); the default value is false
3.5.3.1.2 int (see 3.3.5 Numbers); the default value is 0; an implementation shall at least support 52 bit resolution
3.5.3.1.3 real (see 3.3.5 Numbers); the default value is 0.0; an implementation shall at least support IEEE 754 64 bit resolution
3.5.3.1.4 string (see 3.3.6 Strings); the default value is the empty string
3.5.3.1.5 path (see 3.3.8 Paths); the default value is '.'
3.5.3.1.6 symbol (see 3.3.7 Symbols); the default value is an empty string

3.5.4 Class types

3.5.4.1 A class type is a structure consisting of a fixed number of elements, called fields, with possibly different types. The class type declaration specifies the name and type of each field. The scope of the field identifiers extends from the point of their declaration to the end of the class type, but they are also visible within designators referring to elements of class variables (see 3.7.2 Operands). If a variable of class type is visible, also all field identifiers are visible.
3.5.4.2 Class types are extensible, i.e. a class type can be declared as an extension of another class type. In the example
3.5.4.2.1 type T0 = class { x: int }
type T1 = class (T0) { y: real }
3.5.4.3 T1 is a (direct) extension of T0 and T0 is the (direct) base type of T1. An extended type T1 consists of the fields of its base type and of the fields which are declared in T1. In general all identifiers declared in the extended class must be different from the identifiers declared in its base type classes.
3.5.4.4 Syntax:
3.5.4.4.1 classdecl ::= class [ '(' designator ')' ] '{' { fielddecl [';'] } '}'
3.5.4.4.2 fielddecl ::= ident ':' typeref
3.5.4.5 Classes are reference types, i.e. an assignment of variables of class type creates a copy of the reference, not a copy of the referenced object.
3.5.4.6 Fields can be of basic, enumeration or list types.
3.5.4.7NOTE Fields cannot be of class type, but they can be of a list type the element type of which is a class type.
3.5.4.8 This specification includes a set of predeclared classes with a defined meaning for the build process (see 4 Predeclared Class Reference).

3.5.5 Enumeration types

3.5.5.1 An enumeration is a sequence of symbols that denote the values which constitute the data type. They, and no other values, belong to this type. The default value of an enumeration type is the first symbol of the sequence.
3.5.5.2 Syntax:
3.5.5.2.1 enumeration = '(' symbol { [','] symbol } ')'
3.5.5.3 Example:
3.5.5.3.1 type color = ( `red, `green, `blue )
3.5.5.4 There are predeclared enumeration types (see 6 Predeclared Enumeration Reference).

3.5.6 List types

3.5.6.1 A list is a dynamic structure consisting of a variable number of elements which are all of the same type, called the element type.
3.5.6.2 List types are not declared using the type keyword. Instead each variable or field of basic, class or enumeration type becomes a list by appending [] to its type.
3.5.6.3 The elements of a list cannot be of list type.
3.5.6.4 Lists are created by list literals. If the list literal appears on the right side of an assignment or initializer, the list type is given by the left side; otherwise or when the left side has no explicit type, then the type of the list is determined by the first element expression of the list literal. The type of an empty list literal is undefined.
3.5.6.5 The default value of a field of list type is the empty list.
3.5.6.6 Lists are reference types, i.e. an assignment of variables of list type creates a copy of the reference, not a copy of the referenced list.
3.5.6.7 Syntax:
3.5.6.7.1 list_type ::= designator '[]'
3.5.6.7.2 list ::= '[' [ expression { ',' expression } [ ',' ] ] ']'

3.6 Variable declarations

3.6.1 Variable declarations introduce variables by defining an identifier and an optional data type for them. Variables are immediately initialized, either by a default value or an object constructor.
3.6.2 Syntax:
3.6.2.1 vardecl ::= ( var | let | param ) identdef [ ':' explicitType ] initializer
3.6.2.2 initializer ::= constructor | defaultValue
3.6.2.3 constructor ::= '{' block '}'
3.6.2.4 defaultValue ::= '=' expression
3.6.2.5 explicitType ::= designator [ '[]' ]
3.6.2.6 designator ::= ['^'|'.'] ident {'.' ident }
3.6.3 Variables declared with var are mutable. Variables declared with let are immutable. The immutability is transitive: when the variable is of class or list type, also the class fields or list elements are immutable.
3.6.4 The explicit type reference is optional if an default vallue is assigned; if an explicit type reference is present, then the type of the default value must be assignment compatible with the explicit type (see 3.8.3 Assignments).
3.6.5 Variables declared as param can only be of basic or enumeration type, and can only be set by a parameter list in the submod declaration of the outer module (see 3.4 Declarations and scope rules and 3.10 Modules), by assignment in the same module where the param declaration lives, or by means provided by the compiler implementation (e.g. command line parameters); in the latter case parameters located in submodules can only be set if the corresponding submod declaration is public.
3.6.6 If an explicit type reference is present and of class type, then the initializer can be an object constructor. Before the object constructor runs, an instance of the explicit class type is created and initialized with default values by the runtime. The created instance is mutable within the constructor block even if the variable is declared with let. The created instance can be referenced by a designator with a '.' prefix (local instance operator). Here is an example:
3.6.6.1 type T1 = class (T0) { y: real }
3.6.6.2 let t : T1 { .y = 12.3 }
3.6.7NOTE If in a constructor a designator is followed by a '.' prefix, a semicolon must be put in between, otherwise the '.' ident is added to the previous designator.
3.6.8 Constructors can only appear on module level, not in constructor or condition scopes. Constructors and default value assignments are executed in the regular declaration and statement flow.
3.6.9 There are predefined variables with global scope (see 7 Predeclared Variable Reference).

3.7 Expressions

3.7.1 Expressions are constructs denoting rules of computation whereby constants and current values of variables are combined to compute other values by the application of operators and function procedures. Expressions consist of operands and operators. Parentheses may be used to express specific associations of operators and operands.

3.7.2 Operands

3.7.2.1 With the exception of literal constants (numbers, strings, paths, symbols, or lists), operands are denoted by designators. A designator consists of an identifier referring to a variable, type, or predeclared procedure. This identifier may possibly be qualified by one or more module identifier, an outer module operator or local instance operator (see 3.4 Declarations and scope rules, 3.6 Variable declarations and 3.10 Modules), and may be followed by selectors if the designated object is a class field.
3.7.2.2 Syntax:
3.7.2.2.1 designator ::= ['^'|'.'] ident { '.' ident }
3.7.2.2.2 ExpList ::= expression {[','] expression}
3.7.2.3 If r designates a class, then r.f denotes the field f of r.
3.7.2.4 If the designated object is a constant or a variable, then the designator refers to its current value.
3.7.2.5 If the designated object is a predeclared procedure, the designator implies an activation of that procedure and stands for the value resulting from its execution; the actual parameters must correspond to the formal parameters.

3.7.3 Operators

3.7.3.1 Four classes of operators with different precedences (binding strengths) are syntactically distinguished in expressions. The operator ! as well as the unary + and - operators have the highest precedence, followed by multiplication operators, addition operators, and relations. Operators of the same precedence associate from left to right. For example, x - y - z stands for (x - y) - z.
3.7.3.2 Syntax:
3.7.3.2.1 expression ::= SimpleExpression [ relation SimpleExpression ]
3.7.3.2.2 relation ::= '==' | '!=' | '<' | '<=' | '>' | '>=' | in
3.7.3.2.3 SimpleExpression ::= term { AddOperator term }
3.7.3.2.4 AddOperator ::= '+' | '-' | '||'
3.7.3.2.5 term ::= factor {MulOperator factor}
3.7.3.2.6 MulOperator ::= '*' | '/' | '&&' | '%'
3.7.3.2.7 factor ::= integer | real | string | symbol | path | true | false
| designator [ '(' [ ExpList ] ')' ]
| '(' expression [ '?' expression ':' expression ] ')'
| ('+' | '-' |'!') factor
| list
3.7.3.2.8 list ::= '[' [ expression { [','] expression } [ ',' ] ] ']'

3.7.3.3 Logical operators

3.7.3.3.1
||
logical disjunction

p || q

if p then true, else q

&&

logical conjunction

p && q

if p then q, else false

!

negation

!p

not p
3.7.3.3.2 These operators apply to bool operands and yield a bool result.

3.7.3.4 Arithmetic operators

3.7.3.4.1
+
sum

-

difference

*

product

/

quotient

%

modulus
3.7.3.4.2 The operators +, -, *, and / apply to operands of numeric types (int and real). Both operands must be of the same type. To convert from real to int or back use the predeclared toint() or toreal() functions (see 8 Predeclared Procedure Reference). The type of the result is the type of the operands. When used as monadic operators, - denotes sign inversion and + denotes the identity operation.
3.7.3.4.3 The operators +, - and * also apply to list types and mixed list and element types. Each operator creates a new list and doesn't affect the operands. The operands must be of the same type (if both are lists) or the element types must be assignment compatible (see 3.8.3 Assignments). The result of the + operator is a list consisting of the right operand appended to the left operand (at least one of the operands must be a list type). The result of the * operator is a list with the right operand (a list element) appended to the left operand (a list), but only if not contained in the left operand, or a list which corresponds to the intersection of the operands (both lists). The result of the - operator is a list which corresponds to the left operand (a list) with the right operand (a list or a list element) removed.
3.7.3.4.4 The operator + also applies to string and path types. Both operands must be of the same type. The type of the result is the type of the operands. If the operands are strings, the result corresponds to the concatenation of the left and right operand. If the operands are paths, then the result corresponds to the concatenated, normalized path; the right operand must be a relative path; the ../ are resolved with the operation; if the left operand doesn't have enough segments to accommodate the right operand, the execution halts with an error.

3.7.3.5 Relations

3.7.3.5.1
==
equal

!=

unequal

<

less

<=

less or equal

>

greater

>=

greater or equal

in

set membership
3.7.3.5.2 Relations yield a bool result. The relations ==, !=, <, <=, >, and >= apply to the numeric types, as well as strings. The relations == and != also apply to bool, enumerations, symbols, path, class and list types. Both operands must be of the same type.
3.7.3.5.3 x in s stands for "s contains x"; s must be of list type and x must be compatible to the element type of s.
3.7.3.5.4NOTE The expression A == B || C == D corresponds to (A == (B || C)) == D), not to (A==B) || (C==D)

3.7.3.6 Conditional expression

3.7.3.6.1 The value of an expression can depend on a condition.
3.7.3.6.2 Example:
3.7.3.6.2.1 let x = ( cond ? 22 : 33 )
3.7.3.6.3 If in the example cond is true, then x becomes 22, otherwise 33.

3.7.3.7 Function Call

3.7.3.7.1 A function call is a factor in an expression. Each expression in the actual parameters list (if any) is used to initialize a corresponding formal parameter. The number of expressions in the actual parameter list must correspond the number of formal parameters of the corresponding predeclared procedure (see 8 Predeclared Procedure Reference).

3.8 Statements

3.8.1 Statements denote actions. There are elementary and structured statements. Elementary statements are not composed of any parts that are themselves statements. They are the assignment and the procedure call. Structured statements are composed of parts that are themselves statements. The condition is a structured statement. The initializer of a variable declaration is statement-like and also executed in the regular statement flow.
3.8.2 Syntax:
3.8.2.1 statement ::= condition | assignment | call | macrouse
3.8.2.2 assignment ::= designator ( '=' | '+=' | '-=' | '*=' ) expression
3.8.2.3 call ::= ident '(' ExpList ')'
3.8.2.4 condition ::= if expression '{' block '}' [ else ( condition | '{' block '}' ) ]
3.8.2.5 block ::= { ( declaration | statement ) [';'] }

3.8.3 Assignments

3.8.3.1 Assignments replace the current value of a variable or field by a new value specified by an expression. The expression type must be assignment compatible with the variable or field. Variables declared with let cannot be assigned to, nor can they be assigned to other variables not declared with let.
3.8.3.2 Types A and B are assignment compatible, if
3.8.3.2.1 A and B are the same type,
3.8.3.2.2 A is the same or a base class of B,
3.8.3.2.3 A is an enumeration type and B is a symbol which belongs to A.
3.8.3.3 There are four assignment variants: plain replacement (=), in-place add (+=), in-place subtract (-=) and in-place multiply (*=).
3.8.3.4 All four variants are available for numeric types. The in-place variants are an abbreviation of their corresponding arithmetic operators; e.g. a += 10 is an abbreviation of a = a + 10 (see 3.7.3.4 Arithmetic operators).
3.8.3.5 All four variants are available for list type variables or fields. The plain assignment replaces the the designated variable or field by the list resulting from the expression. In contrast the in-place arithmetic operations modify the list referenced by the designated variable or field. The += operator appends a copy of the value of the expression (a list or element) to the list. The *= operator appends the value of the expression to the list, if it is a single element and not yet contained in the list. The *= operator replaces the contents of the list by the intersection, if the value of the expression is a list. The -= operator removes the given element(s) from the list, if the value of the expression is either a single element or a list.
3.8.3.6 The plain replacement (=) and in-place add (+=) operators also apply to string and path types. The designated variable or field must be of the same type as the expression. The plain assignment replaces the the designated variable or field value by the string or path resulting from the expression. In case of strings, the += operator concatenates the right side to the left side. In case of paths, the left side is replaced by a concatenated, normalized version of the left and right side; the right side must be a relative path; the ../ are resolved with the operation; if the left side doesn't have enough segments to accommodate the right side, the execution halts with an error.

3.8.4 Conditions

3.8.4.1 If statements specify the conditional execution of guarded statement sequences. The boolean expression preceding a statement sequence is called its guard. The guards are evaluated in sequence of occurrence, until one evaluates to true, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol else is executed, if there is one.

3.8.5 Calls

3.8.5.1 A procedure call activates a predeclared procedure. It has a (possibly empty) a list of actual parameters. The correspondence is established by the positions.
3.8.5.2 Each actual parameter must be an expression. This expression is evaluated before the procedure activation, and the resulting value is assigned to the formal parameter. The evaluation order is from left to right.

3.9 Macros

3.9.1 Macros are suitable for combining a sequence of declarations and statements into a single command. Macros work at the level of lexical tokens. The tokens that make up the macro definition are inserted into the place where the macro is used, either one-to-one, or modified in accordance with the arguments, if any.
3.9.2 Syntax:
3.9.2.1 macrodef ::= define identdef [ '(' [ ident { [','] ident } ] ')' ] body
3.9.2.2 body ::= '{' { ( subdirectory | declaration | statement ) [';'] } '}'
3.9.2.3 macrouse ::= designator '(' ExpList ')'
3.9.3 A macro definition associates an identifier with a sequence of tokens and optional arguments. Macros can only be defined on module level. Macro definitions belong to the regular name space of a module and can be dereferenced using a designator; the regular rules apply (see 3.4 Declarations and scope rules).
3.9.4 A macro use syntactically looks like a procedure call. Arguments - if any - are not evaluated at the call site like they are for procedure calls; instead the tokens passed as arguments are inserted in the macro body wherever the arument is referenced; only the resulting token stream is passed to the parser and validated. In contrast to procedure calls, the commas in the argument list are mandatory for macro uses. In the macro body it is possible to concatenate identifiers using the '&' operator.

3.10 Modules

3.10.1 A module is a collection of declarations of types and variables, together with a sequence of statements for the purpose of assigning values to the variables.
3.10.2 A module is associated with a directory in the file system, and specifically with a file in that directory called "BUSY"; each such file is either empty or includes source code as specified herein.
3.10.3 Syntax:
3.10.3.1 Module ::= { ( submodule | declaration | statement | macrodef ) [';'] }
3.10.3.2 submodule ::= submod identdef [ '=' ( path | ident ) ] [ else path ] [ '(' paramList ')' ]
3.10.3.3 paramList ::= paramValue { [','] paramValue }
3.10.3.4 paramValue ::= ident [ ( '=' | ':=' ) expression ]
3.10.4 Modules are in a hierarchical relationship to each other. This relationship is explicit. Each module - starting from the module which represents the root directory of the source tree - declares which other modules belong to the build using the submod declaration. A submod declaration references the file system directory the module is associated with, and makes the submodule accessible to the current module by the given identifier.
3.10.5 In the simple case, the identifier directly corresponds to the name of a subdirectory of the directory associated with the current module.
3.10.6 In the general case, the path given in the submod declaration can point to any file system directory, as long as it doesn't point to a file system directory already associated with the current or any of its outer modules (see 3.3.8 Paths and 3.4 Declarations and scope rules).
3.10.7NOTE In other words: the module hierarchy is a logical hierarchy which can, but doesn't have to be congruent with the file system hierarchy.
3.10.8 Each submod declaration constitutes a separate instance of a module, even if two or more modules in the module hierarchy are associated with the same file system directory.
3.10.9 Modules are parsed and executed depth-first; when the parser meets a submod declaration, it parses the submodule before it continues with the current module.
3.10.10 A submod declaration may have a list of parameter names and optional value expressions. The value expressions are evaluated from left to right. The name identifier must correspond to a name of a param declaration in the submodule (see 3.6 Variable declarations). If the value expression is missing, true is assumed as value. Parameter values set by means provided by the compiler override the parameter values set via submod declaration.
3.10.11 A submod declaration may have an optional else keyword followed by an alternative module file path. The file referenced by this path is parsed instead of the BUSY file in case the latter doesn't exist. An alternative module file itself must not include submod declarations.
3.10.12NOTE The alternative module file path is useful if e.g. in a big source tree it should be possible to delete the modules not required by a given project; the alternative module file just makes a minimal set of declarations mimicking the original public module declarations, but issuing an error, if the build tries to use the module anyway.
3.10.13 Implementations are expected to also support the submodule keyword as a synonym of submod.
3.10.14NOTE In an earlier version of this specification the keyword subdir was used instead of submod. Implementations might want to continue subdir as a synonym and true functional subset of submod.

3.11 Alternative Syntax

3.11.1 The syntax version so far has a C flair. For people preferring a Pascal flair syntax, BUSY makes the following alternatives available.
3.11.2 Syntax:
3.11.2.1 condition ::= if expression then block { elsif expression then block } [ else block ] end
3.11.2.2 initializer ::= constructor | ':=' expression
3.11.2.3 constructor ::= begin block end
3.11.2.4 assignment ::= designator ':=' expression
3.11.2.5 submodule ::= submod identdef [ ':=' ( path | ident ) ]

4 Predeclared Class Reference

4.1 Config

4.1.1 Flags: cflags, cflags_c, cflags_cc, cflags_objc, cflags_objcc, defines, include_dirs, ldflags, lib_dirs, lib_names, lib_files, frameworks
4.1.2 Nested configs: configs
4.1.3 Configuration objects can be applied to products and specify sets of compiler flags, includes, defines, etc. They provide a way to conveniently group sets of this configuration information.
4.1.4 The values in a config are additive only. If you want to remove a flag you need to remove the corresponding config that sets it. The final set of flags, defines, etc. for a target is generated in this order:
4.1.4.1 The values specified directly on the Product (rather than using a Config)
4.1.4.2 The configs specified in the ConfigurableProduct's configs list, in order.
4.1.5 Configs solve a problem where the build system needs to have a higher-level understanding of various compiler settings. For example, some compiler flags have to appear in a certain order relative to each other, some settings like defines and flags logically go together, and the build system needs to de-duplicate flags even though raw command-line parameters can't always be operated on in that way.

4.2 Product

4.2.1 A Product is also called a "build target". Products are inputs and outputs of build stages.
4.2.2 Deps: deps

4.2.3 ConfigurableProduct

4.2.3.1 CompiledProduct

4.2.3.1.1 Flags: cflags, cflags_c, cflags_cc, cflags_objc, cflags_objcc, defines, include_dirs, ldflags, lib_dirs, lib_names, lib_files, frameworks
4.2.3.1.2 General: configs, sources
4.2.3.1.3 The tools and commands used to create this product type will be determined by the source files in its sources. Products containing multiple compiler-incompatible languages are not allowed (e.g. a target containing both C and C++ sources is acceptable, but a target containing C and Rust sources is not).

4.2.3.1.4 Executable

4.2.3.1.4.1 General: name
4.2.3.1.4.2 Make a binary which can be directly run by the OS.
4.2.3.1.4.3 This is only the core binary, i.e. not a bundle as common on Mac.

4.2.3.1.5 Library

4.2.3.1.5.1 General: lib_type, def_file, name
4.2.3.1.5.2 Make a ".a" / ".lib" / ".so" / ".dll" / ".dylib" file.
4.2.3.1.5.3 If you only need the static library for intermediate results in the build, you should consider a SourceSet instead since it will skip the (potentially slow) step of creating the intermediate library file.
4.2.3.1.5.4 A shared library will be specified on the linker line for targets listing the shared library in its deps. If you don't want this (say you dynamically load the library at runtime), then you should depend on the shared library via <null reference>.

4.2.3.1.6 SourceSet

4.2.3.1.6.1 The language of a SourceSet target is determined by the extensions present in its sources.
4.2.3.1.6.2 A source set is a collection of sources that get compiled, but are not linked to produce any kind of library. Instead, the resulting object files are implicitly added to the linker line of all targets that depend on the source set.
4.2.3.1.6.3 In most cases, a source set will behave like a static library, except no actual library file will be produced. This will make the build go a little faster by skipping creation of a large static library, while maintaining the organizational benefits of focused build targets.
4.2.3.1.6.4 The main difference between a source set and a static library is around handling of exported symbols. Most linkers assume declaring a function exported means exported from the static library. The linker can then do dead code elimination to delete code not reachable from exported functions.
4.2.3.1.6.5 A source set will not do this code elimination since there is no link step. This allows you to link many source sets into a shared library and have the "exported symbol" notation indicate "export from the final shared library and not from the intermediate targets." There is no way to express this concept when linking multiple static libraries into a shared library.

4.2.4 Group

4.2.4.1 This target type allows you to create meta-targets that just collect a set of dependencies into one named target.

4.2.5 Action

4.2.5.1 Script

4.2.5.1.1 Main: args, script, outputs

4.2.5.1.2 LuaScript

4.2.5.1.2.1 This product type allows you to run a Lua script a single time to produce one or more output files.
4.2.5.1.2.2 If the script produces source files which have to be compiled by a dependent Product (and only then) list these source files (and only those) in the outputs list. This list might be redundant to what you specify in args, but allows the build system to recognize and properly process the generated output of the script.
4.2.5.1.2.3 args makes use of Source Expansion; the place-holders {{root_build_dir}} and {{current_build_dir}} are available.

4.2.5.1.3 LuaScriptForeach

4.2.5.1.3.1 Main: sources
4.2.5.1.3.2 This product type allows you to run a script once-per-file over a set of sources. If you want to run a script once that takes many files as input, see LuaScript.
4.2.5.1.3.3 The args field supports Source Expansion. To perform source expansion in the args field, BUSY substitutes placeholders and produces a different set of arguments for each invocation of the script.

4.2.5.2 Message

4.2.5.2.1 Main: text, msg_type
4.2.5.2.2 The instance displays a message to the console. In case of MessageType `error the build halts.

4.2.5.3 Moc

4.2.5.3.1 Mainsources, defines, tool_dir
4.2.5.3.2 Calls the Qt moc executable from tool_dir or - if tool_dir is '.' - from the directory given by the moc_path variable and generates the corresponding cpp file. Use it as a dependency of SourceSet, Library or Executable so the resulting cpp files are automatically compiled and linked.
4.2.5.3.3 Note that usually Q_OBJECT marked classes are in header files; if instead a .cpp file is added to sources a c++ file with the same name but the suffix .moc is generated, which has to be included at the bottom of the .cpp file (see the original Qt moc documentation for more information).

4.2.5.4 Rcc

4.2.5.4.1 Mainsources, tool_dir
4.2.5.4.2 Calls the Qt rcc executable from tool_dir or - if tool_dir is '.' - from the directory given by the rcc_path variable and generates the corresponding cpp file. Use it as a dependency of SourceSet, Library or Executable so the resulting cpp files are automatically compiled and linked (see the original Qt rcc documentation for more information).

4.2.5.5 Uic

4.2.5.5.1 Mainsources, tool_dir
4.2.5.5.2 Calls the Qt uic executable from tool_dir or - if tool_dir is '.' - from the directory given by the uic_path variable and generates a header file corresponding to the user interface specification (see the original Qt uic documentation for more information). Usually build_dir() has to be added to the include_dirs of the product using the interface (i.e. which includes the generated header).

4.2.5.6 Copy

4.2.5.6.1 Main: sources, outputs, use_deps
4.2.5.6.2 Copy the files explicitly listed in sources or received from deps (subject to the file types in use_deps) to the places listed in outputs.
4.2.5.6.3 outputs makes use of Source Expansion; the place-holders {{source_file_part}}, {{source_name_part}} and {{source_ext}} are available.
4.2.5.6.4 sources and outputs can include as many files as you want; each entry in sources is copied to all places in outputs.
4.2.5.6.5 The file system directories on the paths referenced by outputs are recursively created if they don't exist yet.
4.2.5.6.6NOTE If the output file exists it is overwritten without warning.

5 Predeclared Field Reference

5.1 args

5.1.1 args: string[]
5.1.2 For LuaScript and LuaScriptForeach targets, args is the list of arguments to pass to the script.

5.2 cflags

5.2.1 cflags : string[]
5.2.2 cflags are compiler flags passed to all invocations of the C, C++, Objective C, and Objective C++ compilers.
5.2.3 Each element of the list is passed verbatim to the compiler in charge, i.e. cflags doesn't absctract away specific compiler command line syntax.
5.2.4 To target one of these variants individually, use cflags_c, cflags_cc, cflags_objc, and cflags_objcc, respectively. These variant-specific versions of cflags* will be appended on the compiler command line after "cflags".

5.2.5 Order of application

5.2.5.1 TODO: check and sync with implementation
5.2.5.2 Those set on the current target (not in a config).
5.2.5.3 Those set on the configs on the product in order that the configs appear in the list.

5.3 cflags_c

5.3.1 Like cflags, but just used with C code.

5.4 cflags_cc

5.4.1 Like cflags, but just used with C++ code.

5.5 cflags_objc

5.5.1 Like cflags, but just used with Objective-C code (*.m files).

5.6 cflags_objcc

5.6.1 Like cflags, but just used with Objective-C++ (*.mm files)

5.7 configs

5.7.1 configs: Config[]

5.7.2 configs on a CompiledProduct

5.7.2.1 When used on a target, the include_dirs, defines, etc. in each config are appended in the order they appear to the compile command for each file in the target. They will appear after the include_dirs, defines, etc. that the target sets directly.
5.7.2.2 Since configs apply after the values set on a target, directly setting a compiler flag will prepend it to the command line. If you want to append a flag instead, you can put that flag in a one-off config and append that config to the target's configs list.

5.7.3 configs on a Config

5.7.3.1 It is possible to create composite configs by specifying configs on a config. One might do this to forward values, or to factor out blocks of settings from very large configs into more manageable named chunks.
5.7.3.2 In this case, the composite config is expanded to be the concatenation of its own values, and in order, the values from its sub-configs *before* anything else happens. This has some ramifications:
5.7.3.2.1 A target has no visibility into a config's sub-configs. Target code only sees the name of the composite config. It can't remove sub-configs or opt in to only parts of it.
5.7.3.2.2 You can get duplication of values if a config is listed twice, say, on a target and in a sub-config that also applies. In other cases, the configs applying to a target are de-duped. It's expected that if a config is listed as a sub-config that it is only used in that context. (Note that it's possible to fix this and de-dupe, but it's not normally relevant and complicates the implementation.)
5.7.4 see Order of application

5.8 defines

5.8.1 defines: string[]
5.8.2 string syntax "<ident> [ = <value> ]", so without the -D
5.8.3 These strings will be passed to the C/C++ compiler as #defines. The strings may or may not include an "=" to assign a value.
5.8.4 see Order of application

5.9 def_file

5.9.1 def_file: path
5.9.2 Optionally points to the .Def file when building a DLL on Windows.

5.10 deps

5.10.1 deps: Product[]
5.10.2 The deps field specifies compile-time dependencies of a Product instance. Products and dependencies must form a tree; cycles are not allowed.
5.10.3 The dependency tree is processed depth-first. When processed, the results of each dependent Product instance are propagated up the dependency tree.

5.10.4 Details of dependency propagation

5.10.4.1 The results of Executable, Library, SourceSet, Group, Moc, Rcc, LuaScript and LuaScriptForeach will be propagated up the dependency tree.
5.10.4.2 Group is special in that it just passes on all results of its dependencies.
5.10.4.3 SourceSet consumes sources from its dependencies and propagates object files up the dependency tree; object files and libraries from its dependencies are passed through.
5.10.4.4 Library consumes sources, object files and libraries from its dependencies and passes the resulting library up the dependency tree.
5.10.4.5 Executable consumes sources, object files and librarijes from its dependencies and passes the resulting executable up the dependency tree.
5.10.4.6 Moc and Rcc don't consume or pass through anything from their dependencies, but pass the resulting source files up the dependency tree.
5.10.4.7 LuaScript and LuaScriptForeach don't consume or pass through anything from their dependencies, but pass the source files listed in the outputs field up the dependency tree, relative to the build directory.
5.10.4.8 Copy includes the file types listed in use_deps from its dependencies in its source list, but doesn't pass anything up the dependency tree.
5.10.4.9 Message and Uic don't consume or pass through anything from their dependencies.

5.11 frameworks

5.11.1 frameworks: string[]
5.11.2 Like lib_names, but the names refer to Mac frameworks instead of static or dynamic libraries. In case the framework is referenced by file path use lib_files instead. Only names are used, i.e. without the ".framework" suffix
5.11.3 The switch "-framework" will be prepended instead of the lib_switch. This is to support the way Mac links framework dependencies.
5.11.4 NOTE: in GN this is part of the libs field.

5.12 include_dirs

5.12.1 include_dirs: path[]
5.12.2 A list of source directories.
5.12.3 The directories in this list will be added to the include path for the files in the affected target.
5.12.4 Relative paths are always resolved relative to the module where the object was initially declared.
5.12.5 see Order of application

5.13 ldflags

5.13.1 ldflags: string[]
5.13.2 These flags are passed on the command-line to the linker and generally specify various linking options. Most targets will not need these and will use lib_names, lib_files, frameworks and lib_dirs instead.
5.13.3 ldflags are NOT pushed to dependents, so applying ldflags to source sets or static libraries will be a no-op. If you want to apply ldflags to dependent targets, put them in a config and set it in the <null reference> or <null reference>.
5.13.4 see Order of application

5.14 lib_dirs

5.14.1 lib_dirs: path[]
5.14.2 Specifies additional directories passed to the linker for searching for the required libraries. If an item is not an absolute path, it will be treated as being relative to the current build file.
5.14.3 lib_names, lib_files, and lib_dirs work differently than other flags in two respects. First, they are inherited across static library boundaries until a shared library or executable target is reached. Second, they are uniquified so each one is only passed once (the first instance of it will be the one used).
5.14.4 see Order of application
5.14.5 For lib_names, lib_files, frameworks and lib_dirs only, the values propagated from dependencies (as described above) are applied last assuming they are not already in the list.
5.14.6 Relative paths are always resolved relative to the module where the object was initially declared.

5.15 lib_names

5.15.1 lib_names: string[]
5.15.2 A list of library names. NOTE: in GN both lib_names and lib_files are unified in the libs field.
5.15.3 Only the plain name of the library is used, i.e. without the lib prefix or the .lib or whatever suffix.
5.15.4 These libraries will be linked into the final binary (executable or shared library) containing the current target.
5.15.5 lib_names, lib_files, and lib_dirs work differently than other flags in two respects. First, they are inherited across static library boundaries until a shared library or executable target is reached. Second, they are uniquified so each one is only passed once (the first instance of it will be the one used).
5.15.6 The names will be passed unmodified to the linker and prefixed with the "lib_switch" attribute of the linker tool. Generally you would set the "lib_dirs" so the given library is found. Your BUSY file should not specify the switch (like "-l"): this will be encoded in the "lib_switch" of the tool.

5.16 lib_files

5.16.1 lib_files: path[]
5.16.2 A list of library paths.
5.16.3 These libraries will be linked into the final binary (executable or shared library) containing the current target.
5.16.4 lib_names, lib_files, and lib_dirs work differently than other flags in two respects. First, they are inherited across static library boundaries until a shared library or executable target is reached. Second, they are uniquified so each one is only passed once (the first instance of it will be the one used).
5.16.5 Relative paths are always resolved relative to the module where the object was initially declared.

5.16.6 Types of libs

5.16.6.1 File paths
5.16.6.1.1 They will be rebased to be relative to the build directory and specified in the "libs" for linker tools. This facility should be used for libraries that are checked in to the version control. For libraries that are generated by the build, use normal deps to link them.
5.16.6.2 Apple frameworks
5.16.6.2.1 System libraries ending in ".framework" will be special-cased: the switch "-framework" will be prepended instead of the lib_switch, and the ".framework" suffix will be trimmed. This is to support the way Mac links framework dependencies.

5.17 lib_type

5.17.1 lib_type : LibraryType
5.17.2 Specifies the library type, e.g. whether it is a static or dynamic library.

5.18 msg_type

5.18.1 msg_type : MessageType
5.18.2 Specifies the type of the Message instance

5.19 name

5.19.1 name: string
5.19.2 An optional name to be used to generate the file name of the product. If name is empty then the name of the variable declaration is used.
5.19.3 Watch out that names set using this variable don't collide with the names of other Executables or Libraries in the same module.

5.20 outputs

5.20.1 outputs: path[]
5.20.2 The outputs list is available for Copy, LuaScript and LuaScriptForeach product types and indicates the resulting files. The paths added to the outputs list always refer to files in the build directory.
5.20.3NOTE For security reasons outputs only accepts relative paths.
5.20.4 Copy
5.20.4.1 Copy targets should have exactly one entry in the outputs list. If there is exactly one source, this can be a literal file name or a Source Expansion. If there is more than one source, this must contain a Source Expansion to map a single input name to a single output name.
5.20.4.2 The paths added to the outputs list are relative to root_build_dir. This can be used to add known places in an otherwise implementation specific (i.e. non-deterministic) build tree.
5.20.5 LuaScript and LuaScriptForeach
5.20.5.1 The paths added to the outputs list are relative to where the specific product declaration is represented in the build directory. This location is implementation specific. It could correspond to the result of build_dir(), but there is no guarantee.

5.21 script

5.21.1 script: path
5.21.2 An absolute or buildfile-relative file name of a Lua script to run for action and action_foreach targets (see LuaScript and LuaScriptForeach).

5.22 sources

5.22.1 sources: path[]
5.22.2 A list of files. Non-absolute paths will be resolved relative to the current BUSY file (i.e. if you reference sources with relative paths from another BUSY file they will likely point to the wrong place).

5.22.3 Sources for binary targets

5.22.3.1 For binary targets (source sets, executables, and libraries), the known file types will be compiled with the associated tools. Unknown file types and headers will be skipped. However, you should still list all C/C+ header files so GN knows about the existence of those files for the purposes of include checking.
5.22.3.2 As a special case, a file ending in ".def" will be treated as a Windows module definition file. It will be appended to the link line with a preceding "/DEF:" string. There must be at most one .def file in a target and they do not cross dependency boundaries (so specifying a .def file in a static library or source set will have no effect on the executable or shared library they're linked into).

5.22.4 Sources for actions

5.22.4.1 LuaScriptForeach
5.22.4.1.1 The sources are the set of files that the script will be executed over. The script will run once per file.
5.22.4.2 Copy
5.22.4.2.1 The source are the source files to copy.
5.22.4.3 Moc, Rcc and Uic
5.22.4.3.1 The sources are the files which have to be processed by moc, rcc or uic.

5.22.5 Source Expansion

5.22.5.1 Source expansion is used for the LuaScriptForeach, LuaScript and Copy action types. Paths or strings can include one or more of the following placeholders. The result is the string representation of the path, as if tostring would have been called.

5.22.5.2 Placeholders

5.22.5.2.1
{{source}}
5.22.5.2.1.1 The absolute path of the source file.
5.22.5.2.2
{{source_file_part}}
5.22.5.2.2.1 The file part of the source including the extension, e.g. "//foo/bar/baz.txt" => "baz.txt"
5.22.5.2.3
{{source_name_part}}
5.22.5.2.3.1 The filename part of the source file with no path or extension. e.g. "//foo/bar/baz.tar.gz" => "baz.tar"
5.22.5.2.4
{{source_dir}}
5.22.5.2.4.1 The absolute path of the directory containing the source file with no trailing slash, e.g. "//foo/bar/baz.txt" => "/foo/bar"
5.22.5.2.5
{{source_ext}}
5.22.5.2.5.1 The extension of the source file including the dot, e.g. "//foo/bar/baz.tar.gz" => ".gz"
5.22.5.2.6 {{root_build_dir}}
5.22.5.2.6.1 The string representation of the root file system directory of the build tree.
5.22.5.2.7 {{current_build_dir}}
5.22.5.2.7.1 The string representation of the file system directory associated with the current instance of LuaScriptForeach and LuaScript.

5.23 text

5.23.1 text : string
5.23.2 An arbitrary string to be displayed

5.24 tool_dir

5.24.1 tool_dir: path
5.24.2 An absolute path to the directory where the executable of a specific tool is located. Defaults to '.' which means the tool is accessible on the operating system search path.

5.25 use_deps

5.25.1 use_deps: FileType[]
5.25.2 A list of file types to be consumed from the dependencies; currently only used by Copy.

6 Predeclared Enumeration Reference

6.1 type BuildMode = ( `optimized `nonoptimized `debug )
6.2 type LibraryType = ( `static, `shared, `framework )
6.2.1 Used by lib_type to control what kind of library is beeing built by a given Library instance.
6.3 type OsType = ( `darwin, `macos, `win32, ... )
6.3.1 The type of the OS as identified when compiling BUSY.
6.4 type CpuType = ( `arm, `x86, ... )
6.4.1 The CPU architecture as identified when compiling BUSY.
6.5 type WordSize = ( `16, `32, `64, `128 )
6.5.1 An attribute of the CPU type; corresponds to the pointer byte width of the given CPU.
6.6 type CompilerType = ( `msvc, `gcc, `clang )
6.7 type MessageType = ( `error, `warning, `info )
6.8 type FileType = ( `object_file, `source_file, `static_lib, `shared_lib, `executable )
6.8.1 Possible output file types as generated by the build and transmitted along the dependency chain.

7 Predeclared Variable Reference

7.1 let build_mode: BuildMode
7.1.1 An explicit value can be set e.g. via command line options; if not explicitly set `optimized is assumed.
7.2 let busy_version: string
7.3 let host_cpu: CpuType
7.3.1 The CPU detected when BUSY is compiled
7.4 let host_cpu_ver: int
7.4.1 The CPU version detected when BUSY is compiled
7.5 let host_wordsize: WordSize
7.5.1 The word size used to compile BUSY
7.6 let host_os: OsType
7.6.1 The OS detected when BUSY is compiled
7.7 let host_toolchain: CompilerType
7.7.1 The toolchain used to compile BUSY
7.8 let host_toolchain_ver: int
7.8.1 The version of the toolchain used to compile BUSY
7.9 let root_build_dir: path
7.9.1 The path where the build results are saved; either a default value or an explicit value set via command line options
7.10 let root_source_dir: path
7.10.1 The path of the source tree root directory; either a default value or an explicit value set via command line options
7.11 var moc_path: path
7.11.1 The absolute file system directory path where the moc executable is supposed to be. If the path is '.' then the tool is assumed to be on the operating system search path and called with no directory prefix.
7.12 var rcc_path: path
7.12.1 The absolute file system directory path where the rcc executable is supposed to be. If the path is '.' then the tool is assumed to be on the operating system search path and called with no directory prefix.
7.13 var uic_path: path
7.13.1 The absolute file system directory path where the uic executable is supposed to be. If the path is '.' then the tool is assumed to be on the operating system search path and called with no directory prefix.
7.14 param target_cpu: CpuType
7.14.1 initialized with host_cpu
7.15 param target_cpu_ver: int
7.15.1 initialized with host_cpu_ver
7.16 param target_wordsize: WordSize
7.16.1 initialized with host_wordsize
7.17 param target_os: OsType
7.17.1 initialized with host_os
7.18 param target_toolchain: CompilerType
7.18.1 initialized with host_toolchain
7.19 param target_toolchain_ver: int
7.19.1 initialized with host_toolchain_ver
7.20 param target_toolchain_path: path
7.20.1 initialized with '.'; if set to another path than '.' then the tool name is prefixed with the path (e.g. "path" + "gcc").
7.21 param target_toolchain_prefix: string
7.21.1 initialized with the empty string; the tool name is prefixes with this string (e.g. "xtensa-esp32-elf-" + "gcc").

8 Predeclared Procedure Reference

8.1 abspath

8.1.1 abspath(): path
8.1.1.1 Returns the absolute file system path associated with the current module.
8.1.2 abspath(p: path): path
8.1.2.1 Returns the absolute file system path of p relative to the path associated with the current module, or p if already absolute.
8.1.3 abspath(m: module): path
8.1.3.1 Returns the absolute file system path associated with the designated module.
8.1.4 abspath(m: module; p: path): path
8.1.4.1 Returns the absolute file system path of p relative to the path associated with the designated module.

8.2 build_dir

8.2.1 build_dir(): path
8.2.1.1 The result corresponds to root_build_dir + relpath()
8.2.2NOTE This function should be used with care because the structure of the build directory is implementation specific; there is no guarantee that build_dir() point to a valid path. Consider using Copy to copy executables and libraries to a known place in the build tree and use paths relative to root_build_dir.

8.3 cross_compiling

8.3.1 cross_compiling():bool
8.3.2 This is a convenience function which just returns the following expression:
8.3.2.1 (host_cpu != target_cpu) || (host_os != target_os) || (host_wordsize != target_wordsize) || (host_toolchain != target_toolchain) || (target_toolchain_prefix != "")

8.4 dump

8.4.1 This procedure is for debugging purpose. It expects one or two arguments. The first argument can be of any type; its type and value are printed to the console. The optional second argument is a string printed to the console.

8.5 error

8.5.1 Expects one or more string arguments. Prints the concatenated arguments to the console (stderr) and halts the program.

8.6 message

8.6.1 Expects one or more string arguments. Prints the concatenated arguments to the console (stdout).

8.7 modname

8.7.1 Returns the hierarchical name of the module (similar to relpath); the module associated with the root of the source tree is represented by the name of the corresponding file system directory; each successive name segment corresponds to the identifier used in the submod declaration in the corresponding BUSY file.
8.7.2 modname(): string
8.7.2.1 Returns the hierarchical name relative to the module associated with the root directory of the source tree.
8.7.3 modname(m: module): string
8.7.3.1 Returns the hierarchical name of the designated module relative to the module associated with the root directory of the source tree.

8.8 readstring

8.8.1 readstring(from: path): string
8.8.1.1 Read the given file as UTF-8 string. Double quotes and \ are replaced by \" and \\. Line breaks and the like are replaced by space. Leading and trailing white space (blanks, line breaks) is stripped. The maximum supported file lengh is limited to 16'000 bytes.

8.9 relpath

8.9.1 The returned path is a logical path; the module associated with the root of the source tree is represented by '.'; each successive name segment corresponds to the identifier used in the submod declaration; there is no requirement that the physical directory hierarchy is congruent with the module hierarchy; see 3.10 Modules for more information.
8.9.2 relpath(): path
8.9.2.1 Returns the path relative to the module associated with the root directory of the source tree.
8.9.3 relpath(m: module): path
8.9.3.1 Returns the path of the designated module relative to the module associated with the root directory of the source tree.

8.10 samelist

8.10.1 Expects two arguments of the same list type and compares their elements one by one in order. Returns false, if the elements or their number differ, and true otherwise.

8.11 sameset

8.11.1 Expects two arguments of the same list type and compares their elements. The lists are treated like sets, i.e. the order of elements is insignificant and multiple copies of the same element are counted as one. Returns true, if both lists contain the same elements, false otherwise.

8.12 set_defaults

8.12.1 set_defaults(CompilerType,Config)
8.12.2 Set the default configuration per toolchain. This is useful to avoid cluttering generic flags around BUSY files, or to e.g. control level of optimization.
8.12.3 The defaults should be kept as minimal as possible. A library should best not set the defaults at all. The defaults should not be used to select release or debug builds; instead the build_mode predeclared variable should be considered to decide which defaults to set (if at all).

8.13 toint

8.13.1 Expects one argument of real type and returns the largest int less than or equal to a given real.

8.14 toreal

8.14.1 Expects one argument of int type and returns the same number as real type.

8.15 tostring

8.15.1 Expects one argument of base or enumeration type und returns the string representation or the argument.
8.15.2 For bool type the strings "true" or "false" are returned.
8.15.3 For path types, a '//' prefix is changed to "/" and for a // letter ':' prefix is changed the two leading slashes are removed.
8.15.4 For symbols only the string part without ` prefix is returned.

8.16 topath

8.16.1 Expects one argument of type string. Tries to convert the string into a normalized representation as specified in 3.3.8 Paths. If that succeeds, the path is returned, otherwise the execution halts with an error.

8.17 trycompile

8.17.1 This function compiles C code (without linking). Returns true, if the compiler returns with no error, false otherwise. The following versions of the function are available:
8.17.1.1 TODO: consider including linking and libs
8.17.2 trycompile(code:string):bool
8.17.3 trycompile(code: string; defines: string[]):bool
8.17.4 trycompile(code: string; defines: string[]; include_dirs: path[]):bool
8.17.5 trycompile(code: string; defines: string[]; include_dirs: path[]; cflags: string[]):bool

8.18 warning

8.18.1 Expects one or more string arguments. Prints the concatenated arguments to the console (stderr).