Syntax

This appendix contains a rough sketch of the formal syntax used to define OE-lite recipes.

Formal grammar

The BNF grammar below is extracted from the actual source code used to parse recipes. On the one hand, that makes it quite authoritative. On the other hand, it might have been more readable if it was a little less formal. Also, not all terminals (productions in uppercase) are defined below [1] – but at least some of the missing ones should be obvious, and we explain a few more (e.g. what constitutes a valid variable name) in the semantics section below.

syntax               ::=  statement
                          statement syntax
statement            ::=  NEWLINE
                          assignment NEWLINE
                          export_variable NEWLINE
                          include NEWLINE
                          require NEWLINE
                          inherit NEWLINE
                          func NEWLINE
                          fakeroot_func NEWLINE
                          python_func NEWLINE
                          def_func
                          addtask NEWLINE
                          addhook NEWLINE
                          prefer NEWLINE
                          COMMENT
variable             ::=  VARNAME
                          export_variable
export_variable      ::=  EXPORT VARNAME
varflag              ::=  VARNAME FLAG
varoverride          ::=  VARNAME OVERRIDE
string               ::=  empty_string
                          quoted_string
                          STRING
empty_string         ::=  QUOTE QUOTE
quoted_string        ::=  QUOTE string_value QUOTE
string_value         ::=  STRING
                          STRING string_value
assignment           ::=  variable ASSIGN string
                          varflag ASSIGN string
                          varoverride ASSIGN string
                          variable EXPASSIGN string
                          varflag EXPASSIGN string
                          varoverride EXPASSIGN string
                          variable LAZYASSIGN string
                          variable WEAKASSIGN string
                          varflag WEAKASSIGN string
                          varoverride WEAKASSIGN string
                          variable APPEND string
                          varflag APPEND string
                          varoverride APPEND string
                          variable PREPEND string
                          varflag PREPEND string
                          varoverride PREPEND string
                          variable PREDOT string
                          varflag PREDOT string
                          varoverride PREDOT string
                          variable POSTDOT string
                          varflag POSTDOT string
                          varoverride POSTDOT string
include              ::=  INCLUDE INCLUDEFILE
require              ::=  REQUIRE INCLUDEFILE
inherit              ::=  INHERIT inherit_classes
inherit_classes      ::=  INHERITCLASS
                          INHERITCLASS inherit_classes
addtask              ::=  addtask_task
                          addtask_task addtask_dependencies
addtask_task         ::=  ADDTASK TASK
addtask_dependencies ::=  addtask_dependency
                          addtask_dependency addtask_dependencies
addtask_dependency   ::=  addtask_after
                          addtask_before
addtask_after        ::=  AFTER tasks
addtask_before       ::=  BEFORE tasks
tasks                ::=  TASK
                          TASK tasks
addhook              ::=  ADDHOOK HOOK TO HOOKNAME
                          ADDHOOK HOOK TO HOOKNAME HOOKSEQUENCE
                          ADDHOOK HOOK TO HOOKNAME addhook_dependencies
                          ADDHOOK HOOK TO HOOKNAME HOOKSEQUENCE addhook_dependencies
addhook_dependencies ::=  addhook_dependency
                          addhook_dependency addhook_dependencies
addhook_dependency   ::=  addhook_after
                          addhook_before
addhook_after        ::=  AFTER hooks
addhook_before       ::=  BEFORE hooks
hooks                ::=  HOOK
                          HOOK hooks
prefer               ::=  PREFER recipe maybe_layer maybe_version
                          PREFER packages maybe_recipe maybe_layer maybe_version
recipe               ::=  RECIPE RECIPENAME
maybe_recipe         ::= 
                          recipe
layer                ::=  LAYER LAYERNAME
maybe_layer          ::= 
                          layer
version              ::=  VERSION VERSIONNAME
maybe_version        ::= 
                          version
packages             ::=  PACKAGE package
package              ::=  PACKAGENAME
                          PACKAGENAME package
func                 ::=  VARNAME FUNCSTART func_body FUNCSTOP
func_body            ::=  FUNCLINE
                          FUNCLINE func_body
fakeroot_func        ::=  FAKEROOT func
python_func          ::=  python_func_start func_body FUNCSTOP
python_func_start    ::=  PYTHON VARNAME FUNCSTART
def_func             ::=  DEF VARNAME def_funcargs NEWLINE func_body
                          DEF VARNAME def_funcargs NEWLINE func_body FUNCSTOP
def_funcargs         ::=  ARGSTART STRING ARGSTOP
                          ARGSTART ARGSTOP
ADDHOOK              ::=  addhook
ADDTASK              ::=  addtask
AFTER                ::=  after
APPEND               ::=  +=
ASSIGN               ::=  =
BEFORE               ::=  before
DEF                  ::=  def
EXPASSIGN            ::=  :=
EXPORT               ::=  export
FAKEROOT             ::=  fakeroot
INCLUDE              ::=  include
INHERIT              ::=  inherit
POSTDOT              ::=  =.
PREDOT               ::=  .=
PREFER               ::=  prefer
PREPEND              ::=  =+
PYTHON               ::=  python
QUOTE                ::=  "
REQUIRE              ::=  require
TO                   ::=  to
WEAKASSIGN           ::=  ?=

Semantics

This section describes the semantics of the most important top-level productions in the above grammar.

Assignment

The most common statement in a recipe is some form of assignment. The LHS must be a valid variable name, which means that it must match the regular expression [a-zA-Z_][a-zA-Z0-9_\-\${}\+\.]*. In other words, it must start with a letter or underscore, and otherwise consist of alphanumeric characters, along with -${}+..

The characters ${} are not part of the actual variable name, but can be used to substitute the value of another variable. For example, if PN contains openssh, RDEPENDS_${PN} = "something" would assign the value something to RDEPENDS_openssh. In practice, ${PN} is the only variable one will ever use in this context.

The RHS should normally consist of a quoted string. References to other variables can be done by wrapping them in ${} (this differs from Makefile syntax where $() is used).

The semantics of the various operators is as follows:

LHS = "RHS": Assign RHS to the variable LHS.

LHS .= "RHS": Append RHS to the current value of LHS – if LHS was not defined, it is treated as if it was defined to the empty string.

LHS =. "RHS": This works just like .= except that it prepends rather than appends.

LHS += "RHS": If LHS is not currently defined or is the empty string, this works just as LHS = "RHS". Otherwise, this appends a space and then RHS to the value of LHS.

LHS =+ "RHS": This works just like += except that it prepends rather than appends.

LHS := "RHS": Expand all variables appearing in RHS (recursively) and assign the result to LHS. It is an error if the RHS, or any of the text it expands to, refers to undefined variables.

LHS ?= "RHS": If LHS is already defined (even as the empty string), this does nothing. Otherwise, it works just as LHS = "RHS".

Flags

Apart from its value, a variable can also have a number of attributes, or flags. It is rarely necessary to set flags in recipes, but you may encounter the syntax in classes and configuration files.

In general, the syntax for flag settings is just as for variable settings:

varname[flag] = "value"

Some flags just serve as boolean flags (hence the name) and are hence normally only set using the =, ?= and := operators, while others are treated as a whitespace separated list of words.

nohash

This flag indicates that the variable it is attached to should not be part of the metadata hashing.

export

When a shell function is executed as part of a task, most of the task’s metadata variables [2] are written to the shell script. Only those variables with the export flag set are further exported to the commands executed by the script.

Instead of setting this flag using the varname[export] = "1" syntax, an alternative is to use the export varname statement.

unexport

A variable with this flag does not get exported to the shell environment when a shell function is run. It is thus not quite the opposite of the export flag.

emit

This flag is used to limit the tasks which a given variable gets copied to. If set, the variable is only emitted to the metadata instances for the tasks listed, e.g.

PACKAGES[emit] = "do_split do_package"

Footnotes

[1]Automatically extracting the regexps definining the various tokens and presenting them in a reasonable way is not easy.
[2]Variables names which are not valid as shell variables, e.g. those containing -, are not exported.