Chapter 33. Recipe Syntax

This defines the recipe syntax. It is not very strict, but you should be able to understand what is allowed and what isn't.

The intention is that recipes are always encoded in UTF-8. Currently this is not fully supported yet. US-ASCII works in any case.

Table 33.1. Notation

|separates alternatives
()grouping a sequence of items or alternatives
[]optional items (also does grouping)
""contains literal text; """ is one double quote
...indicates the preceding item or group can be repeated
EOLan end-of-line, optionally preceded by a comment
INDENT  an amount of white space, at least one space
INDENT2  an amount of white space, at least one space more than INDENT


A comment starts with "#" and continues until the end-of-line. It continues in the next line if the last character in the line is a backslash. A comment may appear where white space may appear, but not inside quotes.

        # comment \
        continued comment
        # another comment

White space may be inserted in between items. It is often ignored, but does have a meaning in a few places.

Line continuation may be done with a backslash immediately before an end-of-line. It is not needed for items that use extra indent to indicate that it continues on the next line.

The backslash can be also used for line continuation in Python commands. A leading @ char and white space before it is removed. Example:

        @ python command \
        @   continued python command \
               still continued

When lines are joined because a command continues in a line with more indent, the line break and leading white space of the next line are replaced with a single space. An exception is when the line ends in "$BR": The $BR is removed, the line break is inserted in the text and leading white space of the next line is removed.

All indent is computed with a tabstop setting of eight spaces.

For items that have a build_block, the start of the build block is the line with the smallest indent that is larger than the indent of the line that started the item. The lines before this are continuation lines of the command itself. Example:

        mytarget : source1
                      source2   # continuation line of dependency
            :print $source      # first line of the build block
                 something      # continuation line of :print command
aapfile::=( [ aap_item ] EOL ) ...
aap_item::=dependency | rule | variant | toplevel_command | build_command
   
dependency::=targets ":" [ attribute ... ] [ sources ] [ EOL build_block ]
targets::=item_list
sources::=item_list
build_block::=INDENT build_command [ EOL [ INDENT build_command ] ] ...
   
rule::= :rule [ attribute ... ] pattern ... ":" [ attribute ... ] pattern ... [ EOL build_block ]
   
variant::= ":variant" variable_name ( EOL variant_item ) ...
variant_item::=INDENT varvalue EOL INDENT2 build_block
   
toplevel_command::=child_command | clearrules_command | delrule_command | dll_command | lib_command | program_command | recipe_command | route_command | rule_command | totype_command | variant_command
   
build_command::=assignment | block_assignment | python_item | generic_command
   
assignment::=variable_name [ "$" ] ( "=" | "+=" | "?=" ) item_list
block_assignment::=variable_name [ "$" ] ( "<<" | "+<<" | "?<<" ) marker ( EOL item_list ) ... EOL [ INDENT ] marker
   
python_item::=python_line | python_block
python_line::="@" python_command
python_block::= ":python" EOL ( INDENT python_command EOL ) ...
   
generic_command::=":" command_name [ command_argument ]
   
   
# An item_list can contain white-separated items and Python style expressions.
   
item_list::=item [ white_space item ] ...
item::=simple_item [ attribute ... ]
simple_item::=( expression | non_white_item ) ...
attribute::="{" attribute_name [ "=" item_list ] "}"
expression::=string_expr | python_expr
string_expr::=""" text """ | "'" text "'"
python_expr::="`" python-expression "`"
non_white_item::=non-white-text | variable_reference
variable_reference::="$" [ expand_type ] ... (variable_ext_name | "(" variable_ext_name ")" | "{" variable_ext_name "}" )
expand_type::="?" | "-" | "+" | "*" | "=" | "'" | '"' | "\" | "!"
variable_ext_name::=[ scope_name "." ] variable_name [ "[" index "]" ]
variable__name, attribute_name::=ascii-letter [ ascii-letter | ascii-number | "_" ] ...
scope_name::=( "_no" | "_stack" | "_tree" | "_up" | "_recipe" | "_top" | "_default" | "_start" | "_parent" | "_caller" | user_scope_name )
user_scope_name::=ascii-letter [ ascii-letter | ascii-number | "_" ] ...