Syntax of recipes

The basic items that make up a bitbake recipe file are:

functions

Functions provide a series of actions to be performed. Functions are usually used to override the default implementation of a task function, or to compliment (append or prepend to an existing function) a default function. Standard functions use sh shell syntax, although access to OpenEmbedded variables and internal methods is also available.

The following is an example function from the sed recipe:

do_install () {
    autotools_do_install
    install -d ${D}${base_bindir}
    mv ${D}${bindir}/sed ${D}${base_bindir}/sed.${PN}
}

It is also possible to implement new functions, that are not replacing or complimenting the default functions, which are called between existing tasks. It is also possible to implement functions in python instead of sh. Both of these options are not seen in the majority of recipes.

variable assignments and manipulations

Variable assignments allow a value to be assigned to a variable. The assignment may be static text or might include the contents of other variables. In addition to assignment, appending and prepending operations are also supported.

The follow example shows the some of the ways variables can be used in recipes:

S = "${WORKDIR}/postfix-${PV}"
PR = "r4"
CFLAGS += "-DNO_ASM"
SRC_URI_append = "file://fixup.patch;patch=1"
keywords

Only a few keywords are used in bitbake recipes. They are used for things such as including common functions (inherit), loading parts of a recipe from other files (include and require) and exporting variables to the environment (export).

The following example shows the use of some of these keywords:

export POSTCONF = "${STAGING_BINDIR}/postconf"
inherit autoconf
require otherfile.inc
comments

Any lines that begin with a # are treated as comment lines and are ignored.

# This is a comment

The following is a summary of the most important (and most commonly used) parts of the recipe syntax:

Line continuation: \

To split a line over multiple lines you should place a \ at the end of the line that is to be continued on the next line.

VAR = "A really long \
       line"

Note that there must not be anything (no spaces or tabs) after the \.

Comments: #

Any lines beginning with a # are comments and will be ignored.

# This is a comment
Using variables: ${...}

To access the contents of a variable you need to access it via ${}:

SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"
Quote all assignments

All variable assignments should be quoted with double quotes. (It may work without them at present, but it will not work in the future).

VAR1 = "${OTHERVAR}"
VAR2 = "The version is ${PV}"
Conditional assignment

Conditional assignement is used to assign a value to a variable, but only when the variable is currently unset. This is commonly used to provide a default value for use when no specific definition is provided by the machine or distro configuration of the users local.conf configuration.

The following example:

VAR1 ?= "New value"

will set VAR1 to "New value" if its currently empty. However if it was already set it would be unchanged. In the following VAR1 is left with the value "Original value":

VAR1 = "Original value"
VAR1 ?= "New value"
Appending: +=

You can append values to existing variables using the += operator. Note that this operator will add a space between the existing content of the variable and the new content.

SRC_URI += "file://fix-makefile.patch;patch=1"
Prepending: =+

You can prepend values to existing variables using the =+ operator. Note that this operator will add a space between the new content and the existing content of the variable.

VAR =+ "Starts"
Appending: _append

You can append values to existing variables using the _append method. Note that this operator does not add any additional space, and it is applied after all the +=, and =+ operators have been applied.

The following example show the space being explicitly added to the start to ensure the appended value is not merged with the existing value:

SRC_URI_append = " file://fix-makefile.patch;patch=1"

The _append method can also be used with overrides, which result in the actions only being performed for the specified target or machine: [TODO: Link to section on overrides]

SRC_URI_append_sh4 = " file://fix-makefile.patch;patch=1"

Note that the appended information is a variable itself, and therefore it's possible to used += or =+ to assign variables to the _append information:

SRC_URI_append = " file://fix-makefile.patch;patch=1"
SRC_URI_append += "file://fix-install.patch;patch=1"
Prepending: _prepend

You can prepend values to existing variables using the _prepend method. Note that this operator does not add any additional space, and it is applied after all the +=, and =+ operators have been applied.

The following example show the space being explicitly added to the end to ensure the prepended value is not merged with the existing value:

CFLAGS_prepend = "-I${S}/myincludes "

The _prepend method can also be used with overrides, which result in the actions only being performed for the specified target or machine: [TODO: Link to section on overrides]

CFLAGS_prepend_sh4 = " file://fix-makefile.patch;patch=1"

Note that the appended information is a variable itself, and therefore it's possible to used += or =+ to assign variables to the _prepend information:

CFLAGS_prepend = "-I${S}/myincludes "
CFLAGS_prepend += "-I${S}/myincludes2 "

Note also the lack of a space when using += to append to a prepend value - remember that the += operator is adding space itself.

Spaces vs tabs

Spaces should be used for indentation, not hard tabs. Both currently work, however it is a policy decision of OE that spaces always be used.

Style: oe-stylize.py

To help with using the correct style in your recipes there is a python script in the contrib directory called oe-stylize.py which can be used to reformat your recipes to the correct style. The output will contain a list of warning (to let you know what you did wrong) which should be edited out before using the new file.

contrib/oe-stylize.py myrecipe.bb > fixed-recipe.bb
vi fixed-recipe.bb
mv fixed.recipe.bb myrecipe.bb
Using python for complex operations: ${@...}

For more advanced processing it is possible to use python code during variable assignments, for doing search and replace on a variable for example.

Python code is indicated by a proceeding @ sign in the variable assignment.

CXXFLAGS := "${@'${CXXFLAGS}'.replace('-frename-registers', '')}"

More information about using python is available in the advanced python section.

Shell syntax

When describing a list of actions to take shell syntax is used (as if you were writing a shell script). You should ensure that you script would work with a generic sh and not require any bash (or other shell) specific functionality. The same applies to various system utilities (sed, grep, awk etc) that you may wish to use. If in doubt you should check with multiple implementations - including those from busybox.

For a detailed description of the syntax for the bitbake recipe files you should refer to the bitbake use manual.