2698 lines
126 KiB
XML
2698 lines
126 KiB
XML
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||
|
|
||
|
<chapter id="bitbake-user-manual-metadata">
|
||
|
<title>Syntax and Operators</title>
|
||
|
|
||
|
<para>
|
||
|
Bitbake files have their own syntax.
|
||
|
The syntax has similarities to several
|
||
|
other languages but also has some unique features.
|
||
|
This section describes the available syntax and operators
|
||
|
as well as provides examples.
|
||
|
</para>
|
||
|
|
||
|
<section id='basic-syntax'>
|
||
|
<title>Basic Syntax</title>
|
||
|
|
||
|
<para>
|
||
|
This section provides some basic syntax examples.
|
||
|
</para>
|
||
|
|
||
|
<section id='basic-variable-setting'>
|
||
|
<title>Basic Variable Setting</title>
|
||
|
|
||
|
<para>
|
||
|
The following example sets <filename>VARIABLE</filename> to
|
||
|
"value".
|
||
|
This assignment occurs immediately as the statement is parsed.
|
||
|
It is a "hard" assignment.
|
||
|
<literallayout class='monospaced'>
|
||
|
VARIABLE = "value"
|
||
|
</literallayout>
|
||
|
As expected, if you include leading or trailing spaces as part of
|
||
|
an assignment, the spaces are retained:
|
||
|
<literallayout class='monospaced'>
|
||
|
VARIABLE = " value"
|
||
|
VARIABLE = "value "
|
||
|
</literallayout>
|
||
|
Setting <filename>VARIABLE</filename> to "" sets it to an empty string,
|
||
|
while setting the variable to " " sets it to a blank space
|
||
|
(i.e. these are not the same values).
|
||
|
<literallayout class='monospaced'>
|
||
|
VARIABLE = ""
|
||
|
VARIABLE = " "
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
You can use single quotes instead of double quotes
|
||
|
when setting a variable's value.
|
||
|
Doing so allows you to use values that contain the double
|
||
|
quote character:
|
||
|
<literallayout class='monospaced'>
|
||
|
VARIABLE = 'I have a " in my value'
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
Unlike in Bourne shells, single quotes work identically
|
||
|
to double quotes in all other ways.
|
||
|
They do not suppress variable expansions.
|
||
|
</note>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='line-joining'>
|
||
|
<title>Line Joining</title>
|
||
|
|
||
|
<para>
|
||
|
Outside of
|
||
|
<link linkend='functions'>functions</link>, BitBake joins
|
||
|
any line ending in a backslash character ("\")
|
||
|
with the following line before parsing statements.
|
||
|
The most common use for the "\" character is to split variable
|
||
|
assignments over multiple lines, as in the following example:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO = "bar \
|
||
|
baz \
|
||
|
qaz"
|
||
|
</literallayout>
|
||
|
Both the "\" character and the newline character
|
||
|
that follow it are removed when joining lines.
|
||
|
Thus, no newline characters end up in the value of
|
||
|
<filename>FOO</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Consider this additional example where the two
|
||
|
assignments both assign "barbaz" to
|
||
|
<filename>FOO</filename>:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO = "barbaz"
|
||
|
|
||
|
FOO = "bar\
|
||
|
baz"
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
BitBake does not interpret escape sequences like
|
||
|
"\n" in variable values.
|
||
|
For these to have an effect, the value must be passed
|
||
|
to some utility that interprets escape sequences,
|
||
|
such as <filename>printf</filename> or
|
||
|
<filename>echo -n</filename>.
|
||
|
</note>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='variable-expansion'>
|
||
|
<title>Variable Expansion</title>
|
||
|
|
||
|
<para>
|
||
|
Variables can reference the contents of other variables
|
||
|
using a syntax that is similar to variable expansion in
|
||
|
Bourne shells.
|
||
|
The following assignments
|
||
|
result in A containing "aval" and B evaluating to "preavalpost".
|
||
|
<literallayout class='monospaced'>
|
||
|
A = "aval"
|
||
|
B = "pre${A}post"
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
Unlike in Bourne shells, the curly braces are mandatory:
|
||
|
Only <filename>${FOO}</filename> and not
|
||
|
<filename>$FOO</filename> is recognized as an expansion of
|
||
|
<filename>FOO</filename>.
|
||
|
</note>
|
||
|
The "=" operator does not immediately expand variable
|
||
|
references in the right-hand side.
|
||
|
Instead, expansion is deferred until the variable assigned to
|
||
|
is actually used.
|
||
|
The result depends on the current values of the referenced
|
||
|
variables.
|
||
|
The following example should clarify this behavior:
|
||
|
<literallayout class='monospaced'>
|
||
|
A = "${B} baz"
|
||
|
B = "${C} bar"
|
||
|
C = "foo"
|
||
|
*At this point, ${A} equals "foo bar baz"*
|
||
|
C = "qux"
|
||
|
*At this point, ${A} equals "qux bar baz"*
|
||
|
B = "norf"
|
||
|
*At this point, ${A} equals "norf baz"*
|
||
|
</literallayout>
|
||
|
Contrast this behavior with the
|
||
|
<link linkend='immediate-variable-expansion'>immediate variable expansion</link>
|
||
|
operator (i.e. ":=").
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
If the variable expansion syntax is used on a variable that
|
||
|
does not exist, the string is kept as is.
|
||
|
For example, given the following assignment,
|
||
|
<filename>BAR</filename> expands to the literal string
|
||
|
"${FOO}" as long as <filename>FOO</filename> does not exist.
|
||
|
<literallayout class='monospaced'>
|
||
|
BAR = "${FOO}"
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='setting-a-default-value'>
|
||
|
<title>Setting a default value (?=)</title>
|
||
|
|
||
|
<para>
|
||
|
You can use the "?=" operator to achieve a "softer" assignment
|
||
|
for a variable.
|
||
|
This type of assignment allows you to define a variable if it
|
||
|
is undefined when the statement is parsed, but to leave the
|
||
|
value alone if the variable has a value.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
A ?= "aval"
|
||
|
</literallayout>
|
||
|
If <filename>A</filename> is set at the time this statement is parsed,
|
||
|
the variable retains its value.
|
||
|
However, if <filename>A</filename> is not set,
|
||
|
the variable is set to "aval".
|
||
|
<note>
|
||
|
This assignment is immediate.
|
||
|
Consequently, if multiple "?=" assignments
|
||
|
to a single variable exist, the first of those ends up getting
|
||
|
used.
|
||
|
</note>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='setting-a-weak-default-value'>
|
||
|
<title>Setting a weak default value (??=)</title>
|
||
|
|
||
|
<para>
|
||
|
It is possible to use a "weaker" assignment than in the
|
||
|
previous section by using the "??=" operator.
|
||
|
This assignment behaves identical to "?=" except that the
|
||
|
assignment is made at the end of the parsing process rather
|
||
|
than immediately.
|
||
|
Consequently, when multiple "??=" assignments exist, the last
|
||
|
one is used.
|
||
|
Also, any "=" or "?=" assignment will override the value set with
|
||
|
"??=".
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
A ??= "somevalue"
|
||
|
A ??= "someothervalue"
|
||
|
</literallayout>
|
||
|
If <filename>A</filename> is set before the above statements are parsed,
|
||
|
the variable retains its value.
|
||
|
If <filename>A</filename> is not set,
|
||
|
the variable is set to "someothervalue".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Again, this assignment is a "lazy" or "weak" assignment
|
||
|
because it does not occur until the end
|
||
|
of the parsing process.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='immediate-variable-expansion'>
|
||
|
<title>Immediate variable expansion (:=)</title>
|
||
|
|
||
|
<para>
|
||
|
The ":=" operator results in a variable's
|
||
|
contents being expanded immediately,
|
||
|
rather than when the variable is actually used:
|
||
|
<literallayout class='monospaced'>
|
||
|
T = "123"
|
||
|
A := "${B} ${A} test ${T}"
|
||
|
T = "456"
|
||
|
B = "${T} bval"
|
||
|
C = "cval"
|
||
|
C := "${C}append"
|
||
|
</literallayout>
|
||
|
In this example, <filename>A</filename> contains
|
||
|
"test 123" because <filename>${B}</filename> and
|
||
|
<filename>${A}</filename> at the time of parsing are undefined,
|
||
|
which leaves "test 123".
|
||
|
And, the variable <filename>C</filename>
|
||
|
contains "cvalappend" since <filename>${C}</filename> immediately
|
||
|
expands to "cval".
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='appending-and-prepending'>
|
||
|
<title>Appending (+=) and prepending (=+) With Spaces</title>
|
||
|
|
||
|
<para>
|
||
|
Appending and prepending values is common and can be accomplished
|
||
|
using the "+=" and "=+" operators.
|
||
|
These operators insert a space between the current
|
||
|
value and prepended or appended value.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
These operators take immediate effect during parsing.
|
||
|
Here are some examples:
|
||
|
<literallayout class='monospaced'>
|
||
|
B = "bval"
|
||
|
B += "additionaldata"
|
||
|
C = "cval"
|
||
|
C =+ "test"
|
||
|
</literallayout>
|
||
|
The variable <filename>B</filename> contains
|
||
|
"bval additionaldata" and <filename>C</filename>
|
||
|
contains "test cval".
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='appending-and-prepending-without-spaces'>
|
||
|
<title>Appending (.=) and Prepending (=.) Without Spaces</title>
|
||
|
|
||
|
<para>
|
||
|
If you want to append or prepend values without an
|
||
|
inserted space, use the ".=" and "=." operators.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
These operators take immediate effect during parsing.
|
||
|
Here are some examples:
|
||
|
<literallayout class='monospaced'>
|
||
|
B = "bval"
|
||
|
B .= "additionaldata"
|
||
|
C = "cval"
|
||
|
C =. "test"
|
||
|
</literallayout>
|
||
|
The variable <filename>B</filename> contains
|
||
|
"bvaladditionaldata" and
|
||
|
<filename>C</filename> contains "testcval".
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='appending-and-prepending-override-style-syntax'>
|
||
|
<title>Appending and Prepending (Override Style Syntax)</title>
|
||
|
|
||
|
<para>
|
||
|
You can also append and prepend a variable's value
|
||
|
using an override style syntax.
|
||
|
When you use this syntax, no spaces are inserted.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
These operators differ from the ":=", ".=", "=.", "+=", and "=+"
|
||
|
operators in that their effects are deferred
|
||
|
until after parsing completes rather than being immediately
|
||
|
applied.
|
||
|
Here are some examples:
|
||
|
<literallayout class='monospaced'>
|
||
|
B = "bval"
|
||
|
B_append = " additional data"
|
||
|
C = "cval"
|
||
|
C_prepend = "additional data "
|
||
|
D = "dval"
|
||
|
D_append = "additional data"
|
||
|
</literallayout>
|
||
|
The variable <filename>B</filename> becomes
|
||
|
"bval additional data" and <filename>C</filename> becomes
|
||
|
"additional data cval".
|
||
|
The variable <filename>D</filename> becomes
|
||
|
"dvaladditional data".
|
||
|
<note>
|
||
|
You must control all spacing when you use the
|
||
|
override syntax.
|
||
|
</note>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
It is also possible to append and prepend to shell
|
||
|
functions and BitBake-style Python functions.
|
||
|
See the
|
||
|
"<link linkend='shell-functions'>Shell Functions</link>" and
|
||
|
"<link linkend='bitbake-style-python-functions'>BitBake-Style Python Functions</link>
|
||
|
sections for examples.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='removing-override-style-syntax'>
|
||
|
<title>Removal (Override Style Syntax)</title>
|
||
|
|
||
|
<para>
|
||
|
You can remove values from lists using the removal
|
||
|
override style syntax.
|
||
|
Specifying a value for removal causes all occurrences of that
|
||
|
value to be removed from the variable.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
When you use this syntax, BitBake expects one or more strings.
|
||
|
Surrounding spaces are removed as well.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO = "123 456 789 123456 123 456 123 456"
|
||
|
FOO_remove = "123"
|
||
|
FOO_remove = "456"
|
||
|
FOO2 = "abc def ghi abcdef abc def abc def"
|
||
|
FOO2_remove = "abc def"
|
||
|
</literallayout>
|
||
|
The variable <filename>FOO</filename> becomes
|
||
|
"789 123456" and <filename>FOO2</filename> becomes
|
||
|
"ghi abcdef".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Like "_append" and "_prepend", "_remove"
|
||
|
is deferred until after parsing completes.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='override-style-operation-advantages'>
|
||
|
<title>Override Style Operation Advantages</title>
|
||
|
|
||
|
<para>
|
||
|
An advantage of the override style operations
|
||
|
"_append", "_prepend", and "_remove" as compared to the
|
||
|
"+=" and "=+" operators is that the override style
|
||
|
operators provide guaranteed operations.
|
||
|
For example, consider a class <filename>foo.bbclass</filename>
|
||
|
that needs to add the value "val" to the variable
|
||
|
<filename>FOO</filename>, and a recipe that uses
|
||
|
<filename>foo.bbclass</filename> as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
inherit foo
|
||
|
|
||
|
FOO = "initial"
|
||
|
</literallayout>
|
||
|
If <filename>foo.bbclass</filename> uses the "+=" operator,
|
||
|
as follows, then the final value of <filename>FOO</filename>
|
||
|
will be "initial", which is not what is desired:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO += "val"
|
||
|
</literallayout>
|
||
|
If, on the other hand, <filename>foo.bbclass</filename>
|
||
|
uses the "_append" operator, then the final value of
|
||
|
<filename>FOO</filename> will be "initial val", as intended:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO_append = " val"
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
It is never necessary to use "+=" together with "_append".
|
||
|
The following sequence of assignments appends "barbaz" to
|
||
|
<filename>FOO</filename>:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO_append = "bar"
|
||
|
FOO_append = "baz"
|
||
|
</literallayout>
|
||
|
The only effect of changing the second assignment in the
|
||
|
previous example to use "+=" would be to add a space before
|
||
|
"baz" in the appended value (due to how the "+=" operator
|
||
|
works).
|
||
|
</note>
|
||
|
Another advantage of the override style operations is that
|
||
|
you can combine them with other overrides as described in the
|
||
|
"<link linkend='conditional-syntax-overrides'>Conditional Syntax (Overrides)</link>"
|
||
|
section.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='variable-flag-syntax'>
|
||
|
<title>Variable Flag Syntax</title>
|
||
|
|
||
|
<para>
|
||
|
Variable flags are BitBake's implementation of variable properties
|
||
|
or attributes.
|
||
|
It is a way of tagging extra information onto a variable.
|
||
|
You can find more out about variable flags in general in the
|
||
|
"<link linkend='variable-flags'>Variable Flags</link>"
|
||
|
section.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
You can define, append, and prepend values to variable flags.
|
||
|
All the standard syntax operations previously mentioned work
|
||
|
for variable flags except for override style syntax
|
||
|
(i.e. "_prepend", "_append", and "_remove").
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Here are some examples showing how to set variable flags:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO[a] = "abc"
|
||
|
FOO[b] = "123"
|
||
|
FOO[a] += "456"
|
||
|
</literallayout>
|
||
|
The variable <filename>FOO</filename> has two flags:
|
||
|
<filename>[a]</filename> and <filename>[b]</filename>.
|
||
|
The flags are immediately set to "abc" and "123", respectively.
|
||
|
The <filename>[a]</filename> flag becomes "abc 456".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
No need exists to pre-define variable flags.
|
||
|
You can simply start using them.
|
||
|
One extremely common application
|
||
|
is to attach some brief documentation to a BitBake variable as
|
||
|
follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
CACHE[doc] = "The directory holding the cache of the metadata."
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='inline-python-variable-expansion'>
|
||
|
<title>Inline Python Variable Expansion</title>
|
||
|
|
||
|
<para>
|
||
|
You can use inline Python variable expansion to
|
||
|
set variables.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
DATE = "${@time.strftime('%Y%m%d',time.gmtime())}"
|
||
|
</literallayout>
|
||
|
This example results in the <filename>DATE</filename>
|
||
|
variable being set to the current date.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Probably the most common use of this feature is to extract
|
||
|
the value of variables from BitBake's internal data dictionary,
|
||
|
<filename>d</filename>.
|
||
|
The following lines select the values of a package name
|
||
|
and its version number, respectively:
|
||
|
<literallayout class='monospaced'>
|
||
|
PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
|
||
|
PV = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[1] or '1.0'}"
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
Inline Python expressions work just like variable expansions
|
||
|
insofar as the "=" and ":=" operators are concerned.
|
||
|
Given the following assignment, <filename>foo()</filename>
|
||
|
is called each time <filename>FOO</filename> is expanded:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO = "${@foo()}"
|
||
|
</literallayout>
|
||
|
Contrast this with the following immediate assignment, where
|
||
|
<filename>foo()</filename> is only called once, while the
|
||
|
assignment is parsed:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO := "${@foo()}"
|
||
|
</literallayout>
|
||
|
</note>
|
||
|
For a different way to set variables with Python code during
|
||
|
parsing, see the
|
||
|
"<link linkend='anonymous-python-functions'>Anonymous Python Functions</link>"
|
||
|
section.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='unsetting-variables'>
|
||
|
<title>Unseting variables</title>
|
||
|
|
||
|
<para>
|
||
|
It is possible to completely remove a variable or a variable flag
|
||
|
from BitBake's internal data dictionary by using the "unset" keyword.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
unset DATE
|
||
|
unset do_fetch[noexec]
|
||
|
</literallayout>
|
||
|
These two statements remove the <filename>DATE</filename> and the
|
||
|
<filename>do_fetch[noexec]</filename> flag.
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section id='providing-pathnames'>
|
||
|
<title>Providing Pathnames</title>
|
||
|
|
||
|
<para>
|
||
|
When specifying pathnames for use with BitBake,
|
||
|
do not use the tilde ("~") character as a shortcut
|
||
|
for your home directory.
|
||
|
Doing so might cause BitBake to not recognize the
|
||
|
path since BitBake does not expand this character in
|
||
|
the same way a shell would.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Instead, provide a fuller path as the following
|
||
|
example illustrates:
|
||
|
<literallayout class='monospaced'>
|
||
|
BBLAYERS ?= " \
|
||
|
/home/scott-lenovo/LayerA \
|
||
|
"
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='exporting-variables-to-the-environment'>
|
||
|
<title>Exporting Variables to the Environment</title>
|
||
|
|
||
|
<para>
|
||
|
You can export variables to the environment of running
|
||
|
tasks by using the <filename>export</filename> keyword.
|
||
|
For example, in the following example, the
|
||
|
<filename>do_foo</filename> task prints "value from
|
||
|
the environment" when run:
|
||
|
<literallayout class='monospaced'>
|
||
|
export ENV_VARIABLE
|
||
|
ENV_VARIABLE = "value from the environment"
|
||
|
|
||
|
do_foo() {
|
||
|
bbplain "$ENV_VARIABLE"
|
||
|
}
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
BitBake does not expand <filename>$ENV_VARIABLE</filename>
|
||
|
in this case because it lacks the obligatory
|
||
|
<filename>{}</filename>.
|
||
|
Rather, <filename>$ENV_VARIABLE</filename> is expanded
|
||
|
by the shell.
|
||
|
</note>
|
||
|
It does not matter whether
|
||
|
<filename>export ENV_VARIABLE</filename> appears before or
|
||
|
after assignments to <filename>ENV_VARIABLE</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
It is also possible to combine <filename>export</filename>
|
||
|
with setting a value for the variable.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
export ENV_VARIABLE = "<replaceable>variable-value</replaceable>"
|
||
|
</literallayout>
|
||
|
In the output of <filename>bitbake -e</filename>, variables
|
||
|
that are exported to the environment are preceded by "export".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Among the variables commonly exported to the environment
|
||
|
are <filename>CC</filename> and <filename>CFLAGS</filename>,
|
||
|
which are picked up by many build systems.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='conditional-syntax-overrides'>
|
||
|
<title>Conditional Syntax (Overrides)</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses
|
||
|
<link linkend='var-OVERRIDES'><filename>OVERRIDES</filename></link>
|
||
|
to control what variables are overridden after BitBake
|
||
|
parses recipes and configuration files.
|
||
|
This section describes how you can use
|
||
|
<filename>OVERRIDES</filename> as conditional metadata,
|
||
|
talks about key expansion in relationship to
|
||
|
<filename>OVERRIDES</filename>, and provides some examples
|
||
|
to help with understanding.
|
||
|
</para>
|
||
|
|
||
|
<section id='conditional-metadata'>
|
||
|
<title>Conditional Metadata</title>
|
||
|
|
||
|
<para>
|
||
|
You can use <filename>OVERRIDES</filename> to conditionally select
|
||
|
a specific version of a variable and to conditionally
|
||
|
append or prepend the value of a variable.
|
||
|
<note>
|
||
|
Overrides can only use lower-case characters.
|
||
|
Additionally, underscores are not permitted in override names
|
||
|
as they are used to separate overrides from each other and
|
||
|
from the variable name.
|
||
|
</note>
|
||
|
<itemizedlist>
|
||
|
<listitem><para><emphasis>Selecting a Variable:</emphasis>
|
||
|
The <filename>OVERRIDES</filename> variable is
|
||
|
a colon-character-separated list that contains items
|
||
|
for which you want to satisfy conditions.
|
||
|
Thus, if you have a variable that is conditional on “arm”, and “arm”
|
||
|
is in <filename>OVERRIDES</filename>, then the “arm”-specific
|
||
|
version of the variable is used rather than the non-conditional
|
||
|
version.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
OVERRIDES = "architecture:os:machine"
|
||
|
TEST = "default"
|
||
|
TEST_os = "osspecific"
|
||
|
TEST_nooverride = "othercondvalue"
|
||
|
</literallayout>
|
||
|
In this example, the <filename>OVERRIDES</filename>
|
||
|
variable lists three overrides:
|
||
|
"architecture", "os", and "machine".
|
||
|
The variable <filename>TEST</filename> by itself has a default
|
||
|
value of "default".
|
||
|
You select the os-specific version of the <filename>TEST</filename>
|
||
|
variable by appending the "os" override to the variable
|
||
|
(i.e.<filename>TEST_os</filename>).
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
To better understand this, consider a practical example
|
||
|
that assumes an OpenEmbedded metadata-based Linux
|
||
|
kernel recipe file.
|
||
|
The following lines from the recipe file first set
|
||
|
the kernel branch variable <filename>KBRANCH</filename>
|
||
|
to a default value, then conditionally override that
|
||
|
value based on the architecture of the build:
|
||
|
<literallayout class='monospaced'>
|
||
|
KBRANCH = "standard/base"
|
||
|
KBRANCH_qemuarm = "standard/arm-versatile-926ejs"
|
||
|
KBRANCH_qemumips = "standard/mti-malta32"
|
||
|
KBRANCH_qemuppc = "standard/qemuppc"
|
||
|
KBRANCH_qemux86 = "standard/common-pc/base"
|
||
|
KBRANCH_qemux86-64 = "standard/common-pc-64/base"
|
||
|
KBRANCH_qemumips64 = "standard/mti-malta64"
|
||
|
</literallayout>
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis>Appending and Prepending:</emphasis>
|
||
|
BitBake also supports append and prepend operations to
|
||
|
variable values based on whether a specific item is
|
||
|
listed in <filename>OVERRIDES</filename>.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
DEPENDS = "glibc ncurses"
|
||
|
OVERRIDES = "machine:local"
|
||
|
DEPENDS_append_machine = " libmad"
|
||
|
</literallayout>
|
||
|
In this example, <filename>DEPENDS</filename> becomes
|
||
|
"glibc ncurses libmad".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Again, using an OpenEmbedded metadata-based
|
||
|
kernel recipe file as an example, the
|
||
|
following lines will conditionally append to the
|
||
|
<filename>KERNEL_FEATURES</filename> variable based
|
||
|
on the architecture:
|
||
|
<literallayout class='monospaced'>
|
||
|
KERNEL_FEATURES_append = " ${KERNEL_EXTRA_FEATURES}"
|
||
|
KERNEL_FEATURES_append_qemux86=" cfg/sound.scc cfg/paravirt_kvm.scc"
|
||
|
KERNEL_FEATURES_append_qemux86-64=" cfg/sound.scc cfg/paravirt_kvm.scc"
|
||
|
</literallayout>
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis>Setting a Variable for a Single Task:</emphasis>
|
||
|
BitBake supports setting a variable just for the
|
||
|
duration of a single task.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO_task-configure = "val 1"
|
||
|
FOO_task-compile = "val 2"
|
||
|
</literallayout>
|
||
|
In the previous example, <filename>FOO</filename>
|
||
|
has the value "val 1" while the
|
||
|
<filename>do_configure</filename> task is executed,
|
||
|
and the value "val 2" while the
|
||
|
<filename>do_compile</filename> task is executed.
|
||
|
</para>
|
||
|
|
||
|
<para>Internally, this is implemented by prepending
|
||
|
the task (e.g. "task-compile:") to the value of
|
||
|
<link linkend='var-OVERRIDES'><filename>OVERRIDES</filename></link>
|
||
|
for the local datastore of the <filename>do_compile</filename>
|
||
|
task.</para>
|
||
|
|
||
|
<para>You can also use this syntax with other combinations
|
||
|
(e.g. "<filename>_prepend</filename>") as shown in the
|
||
|
following example:
|
||
|
<literallayout class='monospaced'>
|
||
|
EXTRA_OEMAKE_prepend_task-compile = "${PARALLEL_MAKE} "
|
||
|
</literallayout>
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='key-expansion'>
|
||
|
<title>Key Expansion</title>
|
||
|
|
||
|
<para>
|
||
|
Key expansion happens when the BitBake datastore is finalized
|
||
|
just before BitBake expands overrides.
|
||
|
To better understand this, consider the following example:
|
||
|
<literallayout class='monospaced'>
|
||
|
A${B} = "X"
|
||
|
B = "2"
|
||
|
A2 = "Y"
|
||
|
</literallayout>
|
||
|
In this case, after all the parsing is complete, and
|
||
|
before any overrides are handled, BitBake expands
|
||
|
<filename>${B}</filename> into "2".
|
||
|
This expansion causes <filename>A2</filename>, which was
|
||
|
set to "Y" before the expansion, to become "X".
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='variable-interaction-worked-examples'>
|
||
|
<title>Examples</title>
|
||
|
|
||
|
<para>
|
||
|
Despite the previous explanations that show the different forms of
|
||
|
variable definitions, it can be hard to work
|
||
|
out exactly what happens when variable operators, conditional
|
||
|
overrides, and unconditional overrides are combined.
|
||
|
This section presents some common scenarios along
|
||
|
with explanations for variable interactions that
|
||
|
typically confuse users.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
There is often confusion concerning the order in which
|
||
|
overrides and various "append" operators take effect.
|
||
|
Recall that an append or prepend operation using "_append"
|
||
|
and "_prepend" does not result in an immediate assignment
|
||
|
as would "+=", ".=", "=+", or "=.".
|
||
|
Consider the following example:
|
||
|
<literallayout class='monospaced'>
|
||
|
OVERRIDES = "foo"
|
||
|
A = "Z"
|
||
|
A_foo_append = "X"
|
||
|
</literallayout>
|
||
|
For this case, <filename>A</filename> is
|
||
|
unconditionally set to "Z" and "X" is
|
||
|
unconditionally and immediately appended to the variable
|
||
|
<filename>A_foo</filename>.
|
||
|
Because overrides have not been applied yet,
|
||
|
<filename>A_foo</filename> is set to "X" due to the append
|
||
|
and <filename>A</filename> simply equals "Z".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Applying overrides, however, changes things.
|
||
|
Since "foo" is listed in <filename>OVERRIDES</filename>,
|
||
|
the conditional variable <filename>A</filename> is replaced
|
||
|
with the "foo" version, which is equal to "X".
|
||
|
So effectively, <filename>A_foo</filename> replaces <filename>A</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This next example changes the order of the override and
|
||
|
the append:
|
||
|
<literallayout class='monospaced'>
|
||
|
OVERRIDES = "foo"
|
||
|
A = "Z"
|
||
|
A_append_foo = "X"
|
||
|
</literallayout>
|
||
|
For this case, before overrides are handled,
|
||
|
<filename>A</filename> is set to "Z" and <filename>A_append_foo</filename>
|
||
|
is set to "X".
|
||
|
Once the override for "foo" is applied, however,
|
||
|
<filename>A</filename> gets appended with "X".
|
||
|
Consequently, <filename>A</filename> becomes "ZX".
|
||
|
Notice that spaces are not appended.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This next example has the order of the appends and overrides reversed
|
||
|
back as in the first example:
|
||
|
<literallayout class='monospaced'>
|
||
|
OVERRIDES = "foo"
|
||
|
A = "Y"
|
||
|
A_foo_append = "Z"
|
||
|
A_foo_append = "X"
|
||
|
</literallayout>
|
||
|
For this case, before any overrides are resolved,
|
||
|
<filename>A</filename> is set to "Y" using an immediate assignment.
|
||
|
After this immediate assignment, <filename>A_foo</filename> is set
|
||
|
to "Z", and then further appended with
|
||
|
"X" leaving the variable set to "ZX".
|
||
|
Finally, applying the override for "foo" results in the conditional
|
||
|
variable <filename>A</filename> becoming "ZX" (i.e.
|
||
|
<filename>A</filename> is replaced with <filename>A_foo</filename>).
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This final example mixes in some varying operators:
|
||
|
<literallayout class='monospaced'>
|
||
|
A = "1"
|
||
|
A_append = "2"
|
||
|
A_append = "3"
|
||
|
A += "4"
|
||
|
A .= "5"
|
||
|
</literallayout>
|
||
|
For this case, the type of append operators are affecting the
|
||
|
order of assignments as BitBake passes through the code
|
||
|
multiple times.
|
||
|
Initially, <filename>A</filename> is set to "1 45" because
|
||
|
of the three statements that use immediate operators.
|
||
|
After these assignments are made, BitBake applies the
|
||
|
"_append" operations.
|
||
|
Those operations result in <filename>A</filename> becoming "1 4523".
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='sharing-functionality'>
|
||
|
<title>Sharing Functionality</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake allows for metadata sharing through include files
|
||
|
(<filename>.inc</filename>) and class files
|
||
|
(<filename>.bbclass</filename>).
|
||
|
For example, suppose you have a piece of common functionality
|
||
|
such as a task definition that you want to share between
|
||
|
more than one recipe.
|
||
|
In this case, creating a <filename>.bbclass</filename>
|
||
|
file that contains the common functionality and then using
|
||
|
the <filename>inherit</filename> directive in your recipes to
|
||
|
inherit the class would be a common way to share the task.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This section presents the mechanisms BitBake provides to
|
||
|
allow you to share functionality between recipes.
|
||
|
Specifically, the mechanisms include <filename>include</filename>,
|
||
|
<filename>inherit</filename>, <filename>INHERIT</filename>, and
|
||
|
<filename>require</filename> directives.
|
||
|
</para>
|
||
|
|
||
|
<section id='locating-include-and-class-files'>
|
||
|
<title>Locating Include and Class Files</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses the
|
||
|
<link linkend='var-BBPATH'><filename>BBPATH</filename></link>
|
||
|
variable to locate needed include and class files.
|
||
|
Additionally, BitBake searches the current directory for
|
||
|
<filename>include</filename> and <filename>require</filename>
|
||
|
directives.
|
||
|
<note>
|
||
|
The <filename>BBPATH</filename> variable is analogous to
|
||
|
the environment variable <filename>PATH</filename>.
|
||
|
</note>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
In order for include and class files to be found by BitBake,
|
||
|
they need to be located in a "classes" subdirectory that can
|
||
|
be found in <filename>BBPATH</filename>.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='inherit-directive'>
|
||
|
<title><filename>inherit</filename> Directive</title>
|
||
|
|
||
|
<para>
|
||
|
When writing a recipe or class file, you can use the
|
||
|
<filename>inherit</filename> directive to inherit the
|
||
|
functionality of a class (<filename>.bbclass</filename>).
|
||
|
BitBake only supports this directive when used within recipe
|
||
|
and class files (i.e. <filename>.bb</filename> and
|
||
|
<filename>.bbclass</filename>).
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The <filename>inherit</filename> directive is a rudimentary
|
||
|
means of specifying functionality contained in class files
|
||
|
that your recipes require.
|
||
|
For example, you can easily abstract out the tasks involved in
|
||
|
building a package that uses Autoconf and Automake and put
|
||
|
those tasks into a class file and then have your recipe
|
||
|
inherit that class file.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
As an example, your recipes could use the following directive
|
||
|
to inherit an <filename>autotools.bbclass</filename> file.
|
||
|
The class file would contain common functionality for using
|
||
|
Autotools that could be shared across recipes:
|
||
|
<literallayout class='monospaced'>
|
||
|
inherit autotools
|
||
|
</literallayout>
|
||
|
In this case, BitBake would search for the directory
|
||
|
<filename>classes/autotools.bbclass</filename>
|
||
|
in <filename>BBPATH</filename>.
|
||
|
<note>
|
||
|
You can override any values and functions of the
|
||
|
inherited class within your recipe by doing so
|
||
|
after the "inherit" statement.
|
||
|
</note>
|
||
|
If you want to use the directive to inherit
|
||
|
multiple classes, separate them with spaces.
|
||
|
The following example shows how to inherit both the
|
||
|
<filename>buildhistory</filename> and <filename>rm_work</filename>
|
||
|
classes:
|
||
|
<literallayout class='monospaced'>
|
||
|
inherit buildhistory rm_work
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
An advantage with the inherit directive as compared to both
|
||
|
the
|
||
|
<link linkend='include-directive'>include</link> and
|
||
|
<link linkend='require-inclusion'>require</link> directives
|
||
|
is that you can inherit class files conditionally.
|
||
|
You can accomplish this by using a variable expression
|
||
|
after the <filename>inherit</filename> statement.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
inherit ${VARNAME}
|
||
|
</literallayout>
|
||
|
If <filename>VARNAME</filename> is going to be set, it needs
|
||
|
to be set before the <filename>inherit</filename> statement
|
||
|
is parsed.
|
||
|
One way to achieve a conditional inherit in this case is to use
|
||
|
overrides:
|
||
|
<literallayout class='monospaced'>
|
||
|
VARIABLE = ""
|
||
|
VARIABLE_someoverride = "myclass"
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Another method is by using anonymous Python.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
python () {
|
||
|
if condition == value:
|
||
|
d.setVar('VARIABLE', 'myclass')
|
||
|
else:
|
||
|
d.setVar('VARIABLE', '')
|
||
|
}
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Alternatively, you could use an in-line Python expression
|
||
|
in the following form:
|
||
|
<literallayout class='monospaced'>
|
||
|
inherit ${@'classname' if condition else ''}
|
||
|
inherit ${@functionname(params)}
|
||
|
</literallayout>
|
||
|
In all cases, if the expression evaluates to an empty
|
||
|
string, the statement does not trigger a syntax error
|
||
|
because it becomes a no-op.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='include-directive'>
|
||
|
<title><filename>include</filename> Directive</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake understands the <filename>include</filename>
|
||
|
directive.
|
||
|
This directive causes BitBake to parse whatever file you specify,
|
||
|
and to insert that file at that location.
|
||
|
The directive is much like its equivalent in Make except
|
||
|
that if the path specified on the include line is a relative
|
||
|
path, BitBake locates the first file it can find
|
||
|
within <filename>BBPATH</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The include directive is a more generic method of including
|
||
|
functionality as compared to the
|
||
|
<link linkend='inherit-directive'>inherit</link> directive,
|
||
|
which is restricted to class (i.e. <filename>.bbclass</filename>)
|
||
|
files.
|
||
|
The include directive is applicable for any other kind of
|
||
|
shared or encapsulated functionality or configuration that
|
||
|
does not suit a <filename>.bbclass</filename> file.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
As an example, suppose you needed a recipe to include some
|
||
|
self-test definitions:
|
||
|
<literallayout class='monospaced'>
|
||
|
include test_defs.inc
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
The <filename>include</filename> directive does not
|
||
|
produce an error when the file cannot be found.
|
||
|
Consequently, it is recommended that if the file you
|
||
|
are including is expected to exist, you should use
|
||
|
<link linkend='require-inclusion'><filename>require</filename></link>
|
||
|
instead of <filename>include</filename>.
|
||
|
Doing so makes sure that an error is produced if the
|
||
|
file cannot be found.
|
||
|
</note>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='require-inclusion'>
|
||
|
<title><filename>require</filename> Directive</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake understands the <filename>require</filename>
|
||
|
directive.
|
||
|
This directive behaves just like the
|
||
|
<filename>include</filename> directive with the exception that
|
||
|
BitBake raises a parsing error if the file to be included cannot
|
||
|
be found.
|
||
|
Thus, any file you require is inserted into the file that is
|
||
|
being parsed at the location of the directive.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The require directive, like the include directive previously
|
||
|
described, is a more generic method of including
|
||
|
functionality as compared to the
|
||
|
<link linkend='inherit-directive'>inherit</link> directive,
|
||
|
which is restricted to class (i.e. <filename>.bbclass</filename>)
|
||
|
files.
|
||
|
The require directive is applicable for any other kind of
|
||
|
shared or encapsulated functionality or configuration that
|
||
|
does not suit a <filename>.bbclass</filename> file.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Similar to how BitBake handles
|
||
|
<link linkend='include-directive'><filename>include</filename></link>,
|
||
|
if the path specified
|
||
|
on the require line is a relative path, BitBake locates
|
||
|
the first file it can find within <filename>BBPATH</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
As an example, suppose you have two versions of a recipe
|
||
|
(e.g. <filename>foo_1.2.2.bb</filename> and
|
||
|
<filename>foo_2.0.0.bb</filename>) where
|
||
|
each version contains some identical functionality that could be
|
||
|
shared.
|
||
|
You could create an include file named <filename>foo.inc</filename>
|
||
|
that contains the common definitions needed to build "foo".
|
||
|
You need to be sure <filename>foo.inc</filename> is located in the
|
||
|
same directory as your two recipe files as well.
|
||
|
Once these conditions are set up, you can share the functionality
|
||
|
using a <filename>require</filename> directive from within each
|
||
|
recipe:
|
||
|
<literallayout class='monospaced'>
|
||
|
require foo.inc
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='inherit-configuration-directive'>
|
||
|
<title><filename>INHERIT</filename> Configuration Directive</title>
|
||
|
|
||
|
<para>
|
||
|
When creating a configuration file (<filename>.conf</filename>),
|
||
|
you can use the
|
||
|
<link linkend='var-INHERIT'><filename>INHERIT</filename></link>
|
||
|
configuration directive to inherit a class.
|
||
|
BitBake only supports this directive when used within
|
||
|
a configuration file.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
As an example, suppose you needed to inherit a class
|
||
|
file called <filename>abc.bbclass</filename> from a
|
||
|
configuration file as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
INHERIT += "abc"
|
||
|
</literallayout>
|
||
|
This configuration directive causes the named
|
||
|
class to be inherited at the point of the directive
|
||
|
during parsing.
|
||
|
As with the <filename>inherit</filename> directive, the
|
||
|
<filename>.bbclass</filename> file must be located in a
|
||
|
"classes" subdirectory in one of the directories specified
|
||
|
in <filename>BBPATH</filename>.
|
||
|
<note>
|
||
|
Because <filename>.conf</filename> files are parsed
|
||
|
first during BitBake's execution, using
|
||
|
<filename>INHERIT</filename> to inherit a class effectively
|
||
|
inherits the class globally (i.e. for all recipes).
|
||
|
</note>
|
||
|
If you want to use the directive to inherit
|
||
|
multiple classes, you can provide them on the same line in the
|
||
|
<filename>local.conf</filename> file.
|
||
|
Use spaces to separate the classes.
|
||
|
The following example shows how to inherit both the
|
||
|
<filename>autotools</filename> and <filename>pkgconfig</filename>
|
||
|
classes:
|
||
|
<literallayout class='monospaced'>
|
||
|
INHERIT += "autotools pkgconfig"
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='functions'>
|
||
|
<title>Functions</title>
|
||
|
|
||
|
<para>
|
||
|
As with most languages, functions are the building blocks that
|
||
|
are used to build up operations into tasks.
|
||
|
BitBake supports these types of functions:
|
||
|
<itemizedlist>
|
||
|
<listitem><para><emphasis>Shell Functions:</emphasis>
|
||
|
Functions written in shell script and executed either
|
||
|
directly as functions, tasks, or both.
|
||
|
They can also be called by other shell functions.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis>BitBake-Style Python Functions:</emphasis>
|
||
|
Functions written in Python and executed by BitBake or other
|
||
|
Python functions using <filename>bb.build.exec_func()</filename>.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis>Python Functions:</emphasis>
|
||
|
Functions written in Python and executed by Python.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis>Anonymous Python Functions:</emphasis>
|
||
|
Python functions executed automatically during
|
||
|
parsing.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
Regardless of the type of function, you can only
|
||
|
define them in class (<filename>.bbclass</filename>)
|
||
|
and recipe (<filename>.bb</filename> or <filename>.inc</filename>)
|
||
|
files.
|
||
|
</para>
|
||
|
|
||
|
<section id='shell-functions'>
|
||
|
<title>Shell Functions</title>
|
||
|
|
||
|
<para>
|
||
|
Functions written in shell script and executed either
|
||
|
directly as functions, tasks, or both.
|
||
|
They can also be called by other shell functions.
|
||
|
Here is an example shell function definition:
|
||
|
<literallayout class='monospaced'>
|
||
|
some_function () {
|
||
|
echo "Hello World"
|
||
|
}
|
||
|
</literallayout>
|
||
|
When you create these types of functions in your recipe
|
||
|
or class files, you need to follow the shell programming
|
||
|
rules.
|
||
|
The scripts are executed by <filename>/bin/sh</filename>,
|
||
|
which may not be a bash shell but might be something
|
||
|
such as <filename>dash</filename>.
|
||
|
You should not use Bash-specific script (bashisms).
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Overrides and override-style operators like
|
||
|
<filename>_append</filename> and
|
||
|
<filename>_prepend</filename> can also be applied to
|
||
|
shell functions.
|
||
|
Most commonly, this application would be used in a
|
||
|
<filename>.bbappend</filename> file to modify functions in
|
||
|
the main recipe.
|
||
|
It can also be used to modify functions inherited from
|
||
|
classes.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
As an example, consider the following:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_foo() {
|
||
|
bbplain first
|
||
|
fn
|
||
|
}
|
||
|
|
||
|
fn_prepend() {
|
||
|
bbplain second
|
||
|
}
|
||
|
|
||
|
fn() {
|
||
|
bbplain third
|
||
|
}
|
||
|
|
||
|
do_foo_append() {
|
||
|
bbplain fourth
|
||
|
}
|
||
|
</literallayout>
|
||
|
Running <filename>do_foo</filename>
|
||
|
prints the following:
|
||
|
<literallayout class='monospaced'>
|
||
|
recipename do_foo: first
|
||
|
recipename do_foo: second
|
||
|
recipename do_foo: third
|
||
|
recipename do_foo: fourth
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
Overrides and override-style operators can
|
||
|
be applied to any shell function, not just
|
||
|
<link linkend='tasks'>tasks</link>.
|
||
|
</note>
|
||
|
You can use the <filename>bitbake -e</filename> <replaceable>recipename</replaceable>
|
||
|
command to view the final assembled function
|
||
|
after all overrides have been applied.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='bitbake-style-python-functions'>
|
||
|
<title>BitBake-Style Python Functions</title>
|
||
|
|
||
|
<para>
|
||
|
These functions are written in Python and executed by
|
||
|
BitBake or other Python functions using
|
||
|
<filename>bb.build.exec_func()</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
An example BitBake function is:
|
||
|
<literallayout class='monospaced'>
|
||
|
python some_python_function () {
|
||
|
d.setVar("TEXT", "Hello World")
|
||
|
print d.getVar("TEXT")
|
||
|
}
|
||
|
</literallayout>
|
||
|
Because the Python "bb" and "os" modules are already
|
||
|
imported, you do not need to import these modules.
|
||
|
Also in these types of functions, the datastore ("d")
|
||
|
is a global variable and is always automatically
|
||
|
available.
|
||
|
<note>
|
||
|
Variable expressions (e.g. <filename>${X}</filename>)
|
||
|
are no longer expanded within Python functions.
|
||
|
This behavior is intentional in order to allow you
|
||
|
to freely set variable values to expandable expressions
|
||
|
without having them expanded prematurely.
|
||
|
If you do wish to expand a variable within a Python
|
||
|
function, use <filename>d.getVar("X")</filename>.
|
||
|
Or, for more complicated expressions, use
|
||
|
<filename>d.expand()</filename>.
|
||
|
</note>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Similar to shell functions, you can also apply overrides
|
||
|
and override-style operators to BitBake-style Python
|
||
|
functions.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
As an example, consider the following:
|
||
|
<literallayout class='monospaced'>
|
||
|
python do_foo_prepend() {
|
||
|
bb.plain("first")
|
||
|
}
|
||
|
|
||
|
python do_foo() {
|
||
|
bb.plain("second")
|
||
|
}
|
||
|
|
||
|
python do_foo_append() {
|
||
|
bb.plain("third")
|
||
|
}
|
||
|
</literallayout>
|
||
|
Running <filename>do_foo</filename> prints
|
||
|
the following:
|
||
|
<literallayout class='monospaced'>
|
||
|
recipename do_foo: first
|
||
|
recipename do_foo: second
|
||
|
recipename do_foo: third
|
||
|
</literallayout>
|
||
|
You can use the <filename>bitbake -e</filename> <replaceable>recipename</replaceable>
|
||
|
command to view the final assembled function
|
||
|
after all overrides have been applied.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='python-functions'>
|
||
|
<title>Python Functions</title>
|
||
|
|
||
|
<para>
|
||
|
These functions are written in Python and are executed by
|
||
|
other Python code.
|
||
|
Examples of Python functions are utility functions
|
||
|
that you intend to call from in-line Python or
|
||
|
from within other Python functions.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
def get_depends(d):
|
||
|
if d.getVar('SOMECONDITION'):
|
||
|
return "dependencywithcond"
|
||
|
else:
|
||
|
return "dependency"
|
||
|
SOMECONDITION = "1"
|
||
|
DEPENDS = "${@get_depends(d)}"
|
||
|
</literallayout>
|
||
|
This would result in <filename>DEPENDS</filename>
|
||
|
containing <filename>dependencywithcond</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Here are some things to know about Python functions:
|
||
|
<itemizedlist>
|
||
|
<listitem><para>Python functions can take parameters.
|
||
|
</para></listitem>
|
||
|
<listitem><para>The BitBake datastore is not
|
||
|
automatically available.
|
||
|
Consequently, you must pass it in as a
|
||
|
parameter to the function.
|
||
|
</para></listitem>
|
||
|
<listitem><para>The "bb" and "os" Python modules are
|
||
|
automatically available.
|
||
|
You do not need to import them.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='bitbake-style-python-functions-versus-python-functions'>
|
||
|
<title>Bitbake-Style Python Functions Versus Python Functions</title>
|
||
|
|
||
|
<para>
|
||
|
Following are some important differences between
|
||
|
BitBake-style Python functions and regular Python
|
||
|
functions defined with "def":
|
||
|
<itemizedlist>
|
||
|
<listitem><para>
|
||
|
Only BitBake-style Python functions can be
|
||
|
<link linkend='tasks'>tasks</link>.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
Overrides and override-style operators can only
|
||
|
be applied to BitBake-style Python functions.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
Only regular Python functions can take arguments
|
||
|
and return values.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<link linkend='variable-flags'>Variable flags</link>
|
||
|
such as <filename>[dirs]</filename>,
|
||
|
<filename>[cleandirs]</filename>, and
|
||
|
<filename>[lockfiles]</filename> can be used
|
||
|
on BitBake-style Python functions, but not on
|
||
|
regular Python functions.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
BitBake-style Python functions generate a separate
|
||
|
<filename>${</filename><link linkend='var-T'><filename>T</filename></link><filename>}/run.</filename><replaceable>function-name</replaceable><filename>.</filename><replaceable>pid</replaceable>
|
||
|
script that is executed to run the function, and also
|
||
|
generate a log file in
|
||
|
<filename>${T}/log.</filename><replaceable>function-name</replaceable><filename>.</filename><replaceable>pid</replaceable>
|
||
|
if they are executed as tasks.</para>
|
||
|
|
||
|
<para>
|
||
|
Regular Python functions execute "inline" and do not
|
||
|
generate any files in <filename>${T}</filename>.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
Regular Python functions are called with the usual
|
||
|
Python syntax.
|
||
|
BitBake-style Python functions are usually tasks and
|
||
|
are called directly by BitBake, but can also be called
|
||
|
manually from Python code by using the
|
||
|
<filename>bb.build.exec_func()</filename> function.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
bb.build.exec_func("my_bitbake_style_function", d)
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
<filename>bb.build.exec_func()</filename> can also
|
||
|
be used to run shell functions from Python code.
|
||
|
If you want to run a shell function before a Python
|
||
|
function within the same task, then you can use a
|
||
|
parent helper Python function that starts by running
|
||
|
the shell function with
|
||
|
<filename>bb.build.exec_func()</filename> and then
|
||
|
runs the Python code.
|
||
|
</note></para>
|
||
|
|
||
|
<para>To detect errors from functions executed with
|
||
|
<filename>bb.build.exec_func()</filename>, you
|
||
|
can catch the <filename>bb.build.FuncFailed</filename>
|
||
|
exception.
|
||
|
<note>
|
||
|
Functions in metadata (recipes and classes) should
|
||
|
not themselves raise
|
||
|
<filename>bb.build.FuncFailed</filename>.
|
||
|
Rather, <filename>bb.build.FuncFailed</filename>
|
||
|
should be viewed as a general indicator that the
|
||
|
called function failed by raising an exception.
|
||
|
For example, an exception raised by
|
||
|
<filename>bb.fatal()</filename> will be caught inside
|
||
|
<filename>bb.build.exec_func()</filename>, and a
|
||
|
<filename>bb.build.FuncFailed</filename> will be raised
|
||
|
in response.
|
||
|
</note>
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Due to their simplicity, you should prefer regular Python functions
|
||
|
over BitBake-style Python functions unless you need a feature specific
|
||
|
to BitBake-style Python functions.
|
||
|
Regular Python functions in metadata are a more recent invention than
|
||
|
BitBake-style Python functions, and older code tends to use
|
||
|
<filename>bb.build.exec_func()</filename> more often.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='anonymous-python-functions'>
|
||
|
<title>Anonymous Python Functions</title>
|
||
|
|
||
|
<para>
|
||
|
Sometimes it is useful to set variables or perform
|
||
|
other operations programmatically during parsing.
|
||
|
To do this, you can define special Python functions,
|
||
|
called anonymous Python functions, that run at the
|
||
|
end of parsing.
|
||
|
For example, the following conditionally sets a variable
|
||
|
based on the value of another variable:
|
||
|
<literallayout class='monospaced'>
|
||
|
python () {
|
||
|
if d.getVar('SOMEVAR') == 'value':
|
||
|
d.setVar('ANOTHERVAR', 'value2')
|
||
|
}
|
||
|
</literallayout>
|
||
|
An equivalent way to mark a function as an anonymous
|
||
|
function is to give it the name "__anonymous", rather
|
||
|
than no name.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Anonymous Python functions always run at the end
|
||
|
of parsing, regardless of where they are defined.
|
||
|
If a recipe contains many anonymous functions, they
|
||
|
run in the same order as they are defined within the
|
||
|
recipe.
|
||
|
As an example, consider the following snippet:
|
||
|
<literallayout class='monospaced'>
|
||
|
python () {
|
||
|
d.setVar('FOO', 'foo 2')
|
||
|
}
|
||
|
|
||
|
FOO = "foo 1"
|
||
|
|
||
|
python () {
|
||
|
d.appendVar('BAR', ' bar 2')
|
||
|
}
|
||
|
|
||
|
BAR = "bar 1"
|
||
|
</literallayout>
|
||
|
The previous example is conceptually equivalent to the
|
||
|
following snippet:
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO = "foo 1"
|
||
|
BAR = "bar 1"
|
||
|
FOO = "foo 2"
|
||
|
BAR += "bar 2"
|
||
|
</literallayout>
|
||
|
<filename>FOO</filename> ends up with the value "foo 2",
|
||
|
and <filename>BAR</filename> with the value "bar 1 bar 2".
|
||
|
Just as in the second snippet, the values set for the
|
||
|
variables within the anonymous functions become available
|
||
|
to tasks, which always run after parsing.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Overrides and override-style operators such as
|
||
|
"<filename>_append</filename>" are applied before
|
||
|
anonymous functions run.
|
||
|
In the following example, <filename>FOO</filename> ends
|
||
|
up with the value "foo from anonymous":
|
||
|
<literallayout class='monospaced'>
|
||
|
FOO = "foo"
|
||
|
FOO_append = " from outside"
|
||
|
|
||
|
python () {
|
||
|
d.setVar("FOO", "foo from anonymous")
|
||
|
}
|
||
|
</literallayout>
|
||
|
For methods you can use with anonymous Python functions,
|
||
|
see the
|
||
|
"<link linkend='functions-you-can-call-from-within-python'>Functions You Can Call From Within Python</link>"
|
||
|
section.
|
||
|
For a different method to run Python code during parsing,
|
||
|
see the
|
||
|
"<link linkend='inline-python-variable-expansion'>Inline Python Variable Expansion</link>"
|
||
|
section.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='flexible-inheritance-for-class-functions'>
|
||
|
<title>Flexible Inheritance for Class Functions</title>
|
||
|
|
||
|
<para>
|
||
|
Through coding techniques and the use of
|
||
|
<filename>EXPORT_FUNCTIONS</filename>, BitBake supports
|
||
|
exporting a function from a class such that the
|
||
|
class function appears as the default implementation
|
||
|
of the function, but can still be called if a recipe
|
||
|
inheriting the class needs to define its own version of
|
||
|
the function.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
To understand the benefits of this feature, consider
|
||
|
the basic scenario where a class defines a task function
|
||
|
and your recipe inherits the class.
|
||
|
In this basic scenario, your recipe inherits the task
|
||
|
function as defined in the class.
|
||
|
If desired, your recipe can add to the start and end of the
|
||
|
function by using the "_prepend" or "_append" operations
|
||
|
respectively, or it can redefine the function completely.
|
||
|
However, if it redefines the function, there is
|
||
|
no means for it to call the class version of the function.
|
||
|
<filename>EXPORT_FUNCTIONS</filename> provides a mechanism
|
||
|
that enables the recipe's version of the function to call
|
||
|
the original version of the function.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
To make use of this technique, you need the following
|
||
|
things in place:
|
||
|
<itemizedlist>
|
||
|
<listitem><para>
|
||
|
The class needs to define the function as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
<replaceable>classname</replaceable><filename>_</filename><replaceable>functionname</replaceable>
|
||
|
</literallayout>
|
||
|
For example, if you have a class file
|
||
|
<filename>bar.bbclass</filename> and a function named
|
||
|
<filename>do_foo</filename>, the class must define the function
|
||
|
as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
bar_do_foo
|
||
|
</literallayout>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
The class needs to contain the <filename>EXPORT_FUNCTIONS</filename>
|
||
|
statement as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
EXPORT_FUNCTIONS <replaceable>functionname</replaceable>
|
||
|
</literallayout>
|
||
|
For example, continuing with the same example, the
|
||
|
statement in the <filename>bar.bbclass</filename> would be
|
||
|
as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
EXPORT_FUNCTIONS do_foo
|
||
|
</literallayout>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
You need to call the function appropriately from within your
|
||
|
recipe.
|
||
|
Continuing with the same example, if your recipe
|
||
|
needs to call the class version of the function,
|
||
|
it should call <filename>bar_do_foo</filename>.
|
||
|
Assuming <filename>do_foo</filename> was a shell function
|
||
|
and <filename>EXPORT_FUNCTIONS</filename> was used as above,
|
||
|
the recipe's function could conditionally call the
|
||
|
class version of the function as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_foo() {
|
||
|
if [ somecondition ] ; then
|
||
|
bar_do_foo
|
||
|
else
|
||
|
# Do something else
|
||
|
fi
|
||
|
}
|
||
|
</literallayout>
|
||
|
To call your modified version of the function as defined
|
||
|
in your recipe, call it as <filename>do_foo</filename>.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
With these conditions met, your single recipe
|
||
|
can freely choose between the original function
|
||
|
as defined in the class file and the modified function in your recipe.
|
||
|
If you do not set up these conditions, you are limited to using one function
|
||
|
or the other.
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='tasks'>
|
||
|
<title>Tasks</title>
|
||
|
|
||
|
<para>
|
||
|
Tasks are BitBake execution units that make up the
|
||
|
steps that BitBake can run for a given recipe.
|
||
|
Tasks are only supported in recipes and classes
|
||
|
(i.e. in <filename>.bb</filename> files and files
|
||
|
included or inherited from <filename>.bb</filename>
|
||
|
files).
|
||
|
By convention, tasks have names that start with "do_".
|
||
|
</para>
|
||
|
|
||
|
<section id='promoting-a-function-to-a-task'>
|
||
|
<title>Promoting a Function to a Task</title>
|
||
|
|
||
|
<para>
|
||
|
Tasks are either
|
||
|
<link linkend='shell-functions'>shell functions</link> or
|
||
|
<link linkend='bitbake-style-python-functions'>BitBake-style Python functions</link>
|
||
|
that have been promoted to tasks by using the
|
||
|
<filename>addtask</filename> command.
|
||
|
The <filename>addtask</filename> command can also
|
||
|
optionally describe dependencies between the
|
||
|
task and other tasks.
|
||
|
Here is an example that shows how to define a task
|
||
|
and declare some dependencies:
|
||
|
<literallayout class='monospaced'>
|
||
|
python do_printdate () {
|
||
|
import time
|
||
|
print time.strftime('%Y%m%d', time.gmtime())
|
||
|
}
|
||
|
addtask printdate after do_fetch before do_build
|
||
|
</literallayout>
|
||
|
The first argument to <filename>addtask</filename>
|
||
|
is the name of the function to promote to
|
||
|
a task.
|
||
|
If the name does not start with "do_", "do_" is
|
||
|
implicitly added, which enforces the convention that
|
||
|
all task names start with "do_".
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
In the previous example, the
|
||
|
<filename>do_printdate</filename> task becomes a
|
||
|
dependency of the <filename>do_build</filename>
|
||
|
task, which is the default task (i.e. the task run by
|
||
|
the <filename>bitbake</filename> command unless
|
||
|
another task is specified explicitly).
|
||
|
Additionally, the <filename>do_printdate</filename>
|
||
|
task becomes dependent upon the
|
||
|
<filename>do_fetch</filename> task.
|
||
|
Running the <filename>do_build</filename> task
|
||
|
results in the <filename>do_printdate</filename>
|
||
|
task running first.
|
||
|
<note>
|
||
|
If you try out the previous example, you might see that
|
||
|
the <filename>do_printdate</filename> task is only run
|
||
|
the first time you build the recipe with
|
||
|
the <filename>bitbake</filename> command.
|
||
|
This is because BitBake considers the task "up-to-date"
|
||
|
after that initial run.
|
||
|
If you want to force the task to always be rerun for
|
||
|
experimentation purposes, you can make BitBake always
|
||
|
consider the task "out-of-date" by using the
|
||
|
<filename>[</filename><link linkend='variable-flags'><filename>nostamp</filename></link><filename>]</filename>
|
||
|
variable flag, as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_printdate[nostamp] = "1"
|
||
|
</literallayout>
|
||
|
You can also explicitly run the task and provide the
|
||
|
<filename>-f</filename> option as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
$ bitbake <replaceable>recipe</replaceable> -c printdate -f
|
||
|
</literallayout>
|
||
|
When manually selecting a task to run with the
|
||
|
<filename>bitbake</filename> <replaceable>recipe</replaceable> <filename>-c</filename> <replaceable>task</replaceable>
|
||
|
command, you can omit the "do_" prefix as part of the
|
||
|
task name.
|
||
|
</note>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
You might wonder about the practical effects of using
|
||
|
<filename>addtask</filename> without specifying any
|
||
|
dependencies as is done in the following example:
|
||
|
<literallayout class='monospaced'>
|
||
|
addtask printdate
|
||
|
</literallayout>
|
||
|
In this example, assuming dependencies have not been
|
||
|
added through some other means, the only way to run
|
||
|
the task is by explicitly selecting it with
|
||
|
<filename>bitbake</filename> <replaceable>recipe</replaceable> <filename>-c printdate</filename>.
|
||
|
You can use the
|
||
|
<filename>do_listtasks</filename> task to list all tasks
|
||
|
defined in a recipe as shown in the following example:
|
||
|
<literallayout class='monospaced'>
|
||
|
$ bitbake <replaceable>recipe</replaceable> -c listtasks
|
||
|
</literallayout>
|
||
|
For more information on task dependencies, see the
|
||
|
"<link linkend='dependencies'>Dependencies</link>"
|
||
|
section.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
See the
|
||
|
"<link linkend='variable-flags'>Variable Flags</link>"
|
||
|
section for information on variable flags you can use with
|
||
|
tasks.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='deleting-a-task'>
|
||
|
<title>Deleting a Task</title>
|
||
|
|
||
|
<para>
|
||
|
As well as being able to add tasks, you can delete them.
|
||
|
Simply use the <filename>deltask</filename> command to
|
||
|
delete a task.
|
||
|
For example, to delete the example task used in the previous
|
||
|
sections, you would use:
|
||
|
<literallayout class='monospaced'>
|
||
|
deltask printdate
|
||
|
</literallayout>
|
||
|
If you delete a task using the <filename>deltask</filename>
|
||
|
command and the task has dependencies, the dependencies are
|
||
|
not reconnected.
|
||
|
For example, suppose you have three tasks named
|
||
|
<filename>do_a</filename>, <filename>do_b</filename>, and
|
||
|
<filename>do_c</filename>.
|
||
|
Furthermore, <filename>do_c</filename> is dependent on
|
||
|
<filename>do_b</filename>, which in turn is dependent on
|
||
|
<filename>do_a</filename>.
|
||
|
Given this scenario, if you use <filename>deltask</filename>
|
||
|
to delete <filename>do_b</filename>, the implicit dependency
|
||
|
relationship between <filename>do_c</filename> and
|
||
|
<filename>do_a</filename> through <filename>do_b</filename>
|
||
|
no longer exists, and <filename>do_c</filename> dependencies
|
||
|
are not updated to include <filename>do_a</filename>.
|
||
|
Thus, <filename>do_c</filename> is free to run before
|
||
|
<filename>do_a</filename>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
If you want dependencies such as these to remain intact, use
|
||
|
the <filename>[noexec]</filename> varflag to disable the task
|
||
|
instead of using the <filename>deltask</filename> command to
|
||
|
delete it:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_b[noexec] = "1"
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='passing-information-into-the-build-task-environment'>
|
||
|
<title>Passing Information Into the Build Task Environment</title>
|
||
|
|
||
|
<para>
|
||
|
When running a task, BitBake tightly controls the shell execution
|
||
|
environment of the build tasks to make
|
||
|
sure unwanted contamination from the build machine cannot
|
||
|
influence the build.
|
||
|
<note>
|
||
|
By default, BitBake cleans the environment to include only those
|
||
|
things exported or listed in its whitelist to ensure that the build
|
||
|
environment is reproducible and consistent.
|
||
|
You can prevent this "cleaning" by setting the
|
||
|
<link linkend='var-BB_PRESERVE_ENV'><filename>BB_PRESERVE_ENV</filename></link>
|
||
|
variable.
|
||
|
</note>
|
||
|
Consequently, if you do want something to get passed into the
|
||
|
build task environment, you must take these two steps:
|
||
|
<orderedlist>
|
||
|
<listitem><para>
|
||
|
Tell BitBake to load what you want from the environment
|
||
|
into the datastore.
|
||
|
You can do so through the
|
||
|
<link linkend='var-BB_ENV_WHITELIST'><filename>BB_ENV_WHITELIST</filename></link>
|
||
|
and
|
||
|
<link linkend='var-BB_ENV_EXTRAWHITE'><filename>BB_ENV_EXTRAWHITE</filename></link>
|
||
|
variables.
|
||
|
For example, assume you want to prevent the build system from
|
||
|
accessing your <filename>$HOME/.ccache</filename>
|
||
|
directory.
|
||
|
The following command "whitelists" the environment variable
|
||
|
<filename>CCACHE_DIR</filename> causing BitBack to allow that
|
||
|
variable into the datastore:
|
||
|
<literallayout class='monospaced'>
|
||
|
export BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE CCACHE_DIR"
|
||
|
</literallayout></para></listitem>
|
||
|
<listitem><para>
|
||
|
Tell BitBake to export what you have loaded into the
|
||
|
datastore to the task environment of every running task.
|
||
|
Loading something from the environment into the datastore
|
||
|
(previous step) only makes it available in the datastore.
|
||
|
To export it to the task environment of every running task,
|
||
|
use a command similar to the following in your local configuration
|
||
|
file <filename>local.conf</filename> or your
|
||
|
distribution configuration file:
|
||
|
<literallayout class='monospaced'>
|
||
|
export CCACHE_DIR
|
||
|
</literallayout>
|
||
|
<note>
|
||
|
A side effect of the previous steps is that BitBake
|
||
|
records the variable as a dependency of the build process
|
||
|
in things like the setscene checksums.
|
||
|
If doing so results in unnecessary rebuilds of tasks, you can
|
||
|
whitelist the variable so that the setscene code
|
||
|
ignores the dependency when it creates checksums.
|
||
|
</note></para></listitem>
|
||
|
</orderedlist>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Sometimes, it is useful to be able to obtain information
|
||
|
from the original execution environment.
|
||
|
Bitbake saves a copy of the original environment into
|
||
|
a special variable named
|
||
|
<link linkend='var-BB_ORIGENV'><filename>BB_ORIGENV</filename></link>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The <filename>BB_ORIGENV</filename> variable returns a datastore
|
||
|
object that can be queried using the standard datastore operators
|
||
|
such as <filename>getVar(, False)</filename>.
|
||
|
The datastore object is useful, for example, to find the original
|
||
|
<filename>DISPLAY</filename> variable.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
origenv = d.getVar("BB_ORIGENV", False)
|
||
|
bar = origenv.getVar("BAR", False)
|
||
|
</literallayout>
|
||
|
The previous example returns <filename>BAR</filename> from the original
|
||
|
execution environment.
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='variable-flags'>
|
||
|
<title>Variable Flags</title>
|
||
|
|
||
|
<para>
|
||
|
Variable flags (varflags) help control a task's functionality
|
||
|
and dependencies.
|
||
|
BitBake reads and writes varflags to the datastore using the following
|
||
|
command forms:
|
||
|
<literallayout class='monospaced'>
|
||
|
<replaceable>variable</replaceable> = d.getVarFlags("<replaceable>variable</replaceable>")
|
||
|
self.d.setVarFlags("FOO", {"func": True})
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
When working with varflags, the same syntax, with the exception of
|
||
|
overrides, applies.
|
||
|
In other words, you can set, append, and prepend varflags just like
|
||
|
variables.
|
||
|
See the
|
||
|
"<link linkend='variable-flag-syntax'>Variable Flag Syntax</link>"
|
||
|
section for details.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
BitBake has a defined set of varflags available for recipes and
|
||
|
classes.
|
||
|
Tasks support a number of these flags which control various
|
||
|
functionality of the task:
|
||
|
<itemizedlist>
|
||
|
<listitem><para><emphasis><filename>[cleandirs]</filename>:</emphasis>
|
||
|
Empty directories that should be created before the
|
||
|
task runs.
|
||
|
Directories that already exist are removed and recreated
|
||
|
to empty them.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[depends]</filename>:</emphasis>
|
||
|
Controls inter-task dependencies.
|
||
|
See the
|
||
|
<link linkend='var-DEPENDS'><filename>DEPENDS</filename></link>
|
||
|
variable and the
|
||
|
"<link linkend='inter-task-dependencies'>Inter-Task Dependencies</link>"
|
||
|
section for more information.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[deptask]</filename>:</emphasis>
|
||
|
Controls task build-time dependencies.
|
||
|
See the
|
||
|
<link linkend='var-DEPENDS'><filename>DEPENDS</filename></link>
|
||
|
variable and the
|
||
|
"<link linkend='build-dependencies'>Build Dependencies</link>"
|
||
|
section for more information.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[dirs]</filename>:</emphasis>
|
||
|
Directories that should be created before the task runs.
|
||
|
Directories that already exist are left as is.
|
||
|
The last directory listed is used as the
|
||
|
current working directory for the task.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[lockfiles]</filename>:</emphasis>
|
||
|
Specifies one or more lockfiles to lock while the task
|
||
|
executes.
|
||
|
Only one task may hold a lockfile, and any task that
|
||
|
attempts to lock an already locked file will block until
|
||
|
the lock is released.
|
||
|
You can use this variable flag to accomplish mutual
|
||
|
exclusion.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[noexec]</filename>:</emphasis>
|
||
|
When set to "1", marks the task as being empty, with
|
||
|
no execution required.
|
||
|
You can use the <filename>[noexec]</filename> flag to set up
|
||
|
tasks as dependency placeholders, or to disable tasks defined
|
||
|
elsewhere that are not needed in a particular recipe.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[nostamp]</filename>:</emphasis>
|
||
|
When set to "1", tells BitBake to not generate a stamp
|
||
|
file for a task, which implies the task should always
|
||
|
be executed.
|
||
|
<note><title>Caution</title>
|
||
|
Any task that depends (possibly indirectly) on a
|
||
|
<filename>[nostamp]</filename> task will always be
|
||
|
executed as well.
|
||
|
This can cause unnecessary rebuilding if you are
|
||
|
not careful.
|
||
|
</note>
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[postfuncs]</filename>:</emphasis>
|
||
|
List of functions to call after the completion of the task.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[prefuncs]</filename>:</emphasis>
|
||
|
List of functions to call before the task executes.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[rdepends]</filename>:</emphasis>
|
||
|
Controls inter-task runtime dependencies.
|
||
|
See the
|
||
|
<link linkend='var-RDEPENDS'><filename>RDEPENDS</filename></link>
|
||
|
variable, the
|
||
|
<link linkend='var-RRECOMMENDS'><filename>RRECOMMENDS</filename></link>
|
||
|
variable, and the
|
||
|
"<link linkend='inter-task-dependencies'>Inter-Task Dependencies</link>"
|
||
|
section for more information.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[rdeptask]</filename>:</emphasis>
|
||
|
Controls task runtime dependencies.
|
||
|
See the
|
||
|
<link linkend='var-RDEPENDS'><filename>RDEPENDS</filename></link>
|
||
|
variable, the
|
||
|
<link linkend='var-RRECOMMENDS'><filename>RRECOMMENDS</filename></link>
|
||
|
variable, and the
|
||
|
"<link linkend='runtime-dependencies'>Runtime Dependencies</link>"
|
||
|
section for more information.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[recideptask]</filename>:</emphasis>
|
||
|
When set in conjunction with
|
||
|
<filename>recrdeptask</filename>, specifies a task that
|
||
|
should be inspected for additional dependencies.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[recrdeptask]</filename>:</emphasis>
|
||
|
Controls task recursive runtime dependencies.
|
||
|
See the
|
||
|
<link linkend='var-RDEPENDS'><filename>RDEPENDS</filename></link>
|
||
|
variable, the
|
||
|
<link linkend='var-RRECOMMENDS'><filename>RRECOMMENDS</filename></link>
|
||
|
variable, and the
|
||
|
"<link linkend='recursive-dependencies'>Recursive Dependencies</link>"
|
||
|
section for more information.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[stamp-extra-info]</filename>:</emphasis>
|
||
|
Extra stamp information to append to the task's stamp.
|
||
|
As an example, OpenEmbedded uses this flag to allow
|
||
|
machine-specific tasks.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[umask]</filename>:</emphasis>
|
||
|
The umask to run the task under.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Several varflags are useful for controlling how signatures are
|
||
|
calculated for variables.
|
||
|
For more information on this process, see the
|
||
|
"<link linkend='checksums'>Checksums (Signatures)</link>"
|
||
|
section.
|
||
|
<itemizedlist>
|
||
|
<listitem><para><emphasis><filename>[vardeps]</filename>:</emphasis>
|
||
|
Specifies a space-separated list of additional
|
||
|
variables to add to a variable's dependencies
|
||
|
for the purposes of calculating its signature.
|
||
|
Adding variables to this list is useful, for example, when
|
||
|
a function refers to a variable in a manner that
|
||
|
does not allow BitBake to automatically determine
|
||
|
that the variable is referred to.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[vardepsexclude]</filename>:</emphasis>
|
||
|
Specifies a space-separated list of variables
|
||
|
that should be excluded from a variable's dependencies
|
||
|
for the purposes of calculating its signature.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[vardepvalue]</filename>:</emphasis>
|
||
|
If set, instructs BitBake to ignore the actual
|
||
|
value of the variable and instead use the specified
|
||
|
value when calculating the variable's signature.
|
||
|
</para></listitem>
|
||
|
<listitem><para><emphasis><filename>[vardepvalueexclude]</filename>:</emphasis>
|
||
|
Specifies a pipe-separated list of strings to exclude
|
||
|
from the variable's value when calculating the
|
||
|
variable's signature.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='events'>
|
||
|
<title>Events</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake allows installation of event handlers within recipe
|
||
|
and class files.
|
||
|
Events are triggered at certain points during operation, such
|
||
|
as the beginning of operation against a given recipe
|
||
|
(i.e. <filename>*.bb</filename>), the start of a given task,
|
||
|
a task failure, a task success, and so forth.
|
||
|
The intent is to make it easy to do things like email
|
||
|
notification on build failures.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Following is an example event handler that prints the name
|
||
|
of the event and the content of the
|
||
|
<filename>FILE</filename> variable:
|
||
|
<literallayout class='monospaced'>
|
||
|
addhandler myclass_eventhandler
|
||
|
python myclass_eventhandler() {
|
||
|
from bb.event import getName
|
||
|
print("The name of the Event is %s" % getName(e))
|
||
|
print("The file we run for is %s" % d.getVar('FILE'))
|
||
|
}
|
||
|
myclass_eventhandler[eventmask] = "bb.event.BuildStarted bb.event.BuildCompleted"
|
||
|
</literallayout>
|
||
|
In the previous example, an eventmask has been set so that
|
||
|
the handler only sees the "BuildStarted" and "BuildCompleted"
|
||
|
events.
|
||
|
This event handler gets called every time an event matching
|
||
|
the eventmask is triggered.
|
||
|
A global variable "e" is defined, which represents the current
|
||
|
event.
|
||
|
With the <filename>getName(e)</filename> method, you can get
|
||
|
the name of the triggered event.
|
||
|
The global datastore is available as "d".
|
||
|
In legacy code, you might see "e.data" used to get the datastore.
|
||
|
However, realize that "e.data" is deprecated and you should use
|
||
|
"d" going forward.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The context of the datastore is appropriate to the event
|
||
|
in question.
|
||
|
For example, "BuildStarted" and "BuildCompleted" events run
|
||
|
before any tasks are executed so would be in the global
|
||
|
configuration datastore namespace.
|
||
|
No recipe-specific metadata exists in that namespace.
|
||
|
The "BuildStarted" and "BuildCompleted" events also run in
|
||
|
the main cooker/server process rather than any worker context.
|
||
|
Thus, any changes made to the datastore would be seen by other
|
||
|
cooker/server events within the current build but not seen
|
||
|
outside of that build or in any worker context.
|
||
|
Task events run in the actual tasks in question consequently
|
||
|
have recipe-specific and task-specific contents.
|
||
|
These events run in the worker context and are discarded at
|
||
|
the end of task execution.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
During a standard build, the following common events might
|
||
|
occur.
|
||
|
The following events are the most common kinds of events that
|
||
|
most metadata might have an interest in viewing:
|
||
|
<itemizedlist>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.ConfigParsed()</filename>:
|
||
|
Fired when the base configuration; which consists of
|
||
|
<filename>bitbake.conf</filename>,
|
||
|
<filename>base.bbclass</filename> and any global
|
||
|
<filename>INHERIT</filename> statements; has been parsed.
|
||
|
You can see multiple such events when each of the
|
||
|
workers parse the base configuration or if the server
|
||
|
changes configuration and reparses.
|
||
|
Any given datastore only has one such event executed
|
||
|
against it, however.
|
||
|
If
|
||
|
<link linkende='var-BB_INVALIDCONF'><filename>BB_INVALIDCONF</filename></link>
|
||
|
is set in the datastore by the event handler, the
|
||
|
configuration is reparsed and a new event triggered,
|
||
|
allowing the metadata to update configuration.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.HeartbeatEvent()</filename>:
|
||
|
Fires at regular time intervals of one second.
|
||
|
You can configure the interval time using the
|
||
|
<filename>BB_HEARTBEAT_EVENT</filename> variable.
|
||
|
The event's "time" attribute is the
|
||
|
<filename>time.time()</filename> value when the
|
||
|
event is triggered.
|
||
|
This event is useful for activities such as
|
||
|
system state monitoring.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.ParseStarted()</filename>:
|
||
|
Fired when BitBake is about to start parsing recipes.
|
||
|
This event's "total" attribute represents the number of
|
||
|
recipes BitBake plans to parse.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.ParseProgress()</filename>:
|
||
|
Fired as parsing progresses.
|
||
|
This event's "current" attribute is the number of
|
||
|
recipes parsed as well as the "total" attribute.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.ParseCompleted()</filename>:
|
||
|
Fired when parsing is complete.
|
||
|
This event's "cached", "parsed", "skipped", "virtuals",
|
||
|
"masked", and "errors" attributes provide statistics
|
||
|
for the parsing results.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.BuildStarted()</filename>:
|
||
|
Fired when a new build starts.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.build.TaskStarted()</filename>:
|
||
|
Fired when a task starts.
|
||
|
This event's "taskfile" attribute points to the recipe
|
||
|
from which the task originates.
|
||
|
The "taskname" attribute, which is the task's name,
|
||
|
includes the <filename>do_</filename> prefix, and the
|
||
|
"logfile" attribute point to where the task's output is
|
||
|
stored.
|
||
|
Finally, the "time" attribute is the task's execution start
|
||
|
time.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.build.TaskInvalid()</filename>:
|
||
|
Fired if BitBake tries to execute a task that does not exist.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.build.TaskFailedSilent()</filename>:
|
||
|
Fired for setscene tasks that fail and should not be
|
||
|
presented to the user verbosely.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.build.TaskFailed()</filename>:
|
||
|
Fired for normal tasks that fail.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.build.TaskSucceeded()</filename>:
|
||
|
Fired when a task successfully completes.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.BuildCompleted()</filename>:
|
||
|
Fired when a build finishes.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.cooker.CookerExit()</filename>:
|
||
|
Fired when the BitBake server/cooker shuts down.
|
||
|
This event is usually only seen by the UIs as a
|
||
|
sign they should also shutdown.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This next list of example events occur based on specific
|
||
|
requests to the server.
|
||
|
These events are often used to communicate larger pieces of
|
||
|
information from the BitBake server to other parts of
|
||
|
BitBake such as user interfaces:
|
||
|
<itemizedlist>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.TreeDataPreparationStarted()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.TreeDataPreparationProgress()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.TreeDataPreparationCompleted()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.DepTreeGenerated()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.CoreBaseFilesFound()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.ConfigFilePathFound()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.FilesMatchingFound()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.ConfigFilesFound()</filename>
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
<filename>bb.event.TargetsTreeGenerated()</filename>
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='variants-class-extension-mechanism'>
|
||
|
<title>Variants - Class Extension Mechanism</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake supports two features that facilitate creating
|
||
|
from a single recipe file multiple incarnations of that
|
||
|
recipe file where all incarnations are buildable.
|
||
|
These features are enabled through the
|
||
|
<link linkend='var-BBCLASSEXTEND'><filename>BBCLASSEXTEND</filename></link>
|
||
|
and
|
||
|
<link linkend='var-BBVERSIONS'><filename>BBVERSIONS</filename></link>
|
||
|
variables.
|
||
|
<note>
|
||
|
The mechanism for this class extension is extremely
|
||
|
specific to the implementation.
|
||
|
Usually, the recipe's
|
||
|
<link linkend='var-PROVIDES'><filename>PROVIDES</filename></link>,
|
||
|
<link linkend='var-PN'><filename>PN</filename></link>, and
|
||
|
<link linkend='var-DEPENDS'><filename>DEPENDS</filename></link>
|
||
|
variables would need to be modified by the extension class.
|
||
|
For specific examples, see the OE-Core
|
||
|
<filename>native</filename>, <filename>nativesdk</filename>,
|
||
|
and <filename>multilib</filename> classes.
|
||
|
</note>
|
||
|
<itemizedlist>
|
||
|
<listitem><para><emphasis><filename>BBCLASSEXTEND</filename>:</emphasis>
|
||
|
This variable is a space separated list of classes used to "extend" the
|
||
|
recipe for each variant.
|
||
|
Here is an example that results in a second incarnation of the current
|
||
|
recipe being available.
|
||
|
This second incarnation will have the "native" class inherited.
|
||
|
<literallayout class='monospaced'>
|
||
|
BBCLASSEXTEND = "native"
|
||
|
</literallayout></para></listitem>
|
||
|
<listitem><para><emphasis><filename>BBVERSIONS</filename>:</emphasis>
|
||
|
This variable allows a single recipe to build multiple versions of a
|
||
|
project from a single recipe file.
|
||
|
You can also specify conditional metadata
|
||
|
(using the
|
||
|
<link linkend='var-OVERRIDES'><filename>OVERRIDES</filename></link>
|
||
|
mechanism) for a single version, or an optionally named range of versions.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
BBVERSIONS = "1.0 2.0 git"
|
||
|
SRC_URI_git = "git://someurl/somepath.git"
|
||
|
|
||
|
BBVERSIONS = "1.0.[0-6]:1.0.0+ \ 1.0.[7-9]:1.0.7+"
|
||
|
SRC_URI_append_1.0.7+ = "file://some_patch_which_the_new_versions_need.patch;patch=1"
|
||
|
</literallayout>
|
||
|
The name of the range defaults to the original version of the
|
||
|
recipe.
|
||
|
For example, in OpenEmbedded, the recipe file
|
||
|
<filename>foo_1.0.0+.bb</filename> creates a default name range
|
||
|
of <filename>1.0.0+</filename>.
|
||
|
This is useful because the range name is not only placed
|
||
|
into overrides, but it is also made available for the metadata to use
|
||
|
in the variable that defines the base recipe versions for use in
|
||
|
<filename>file://</filename> search paths
|
||
|
(<link linkend='var-FILESPATH'><filename>FILESPATH</filename></link>).
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='dependencies'>
|
||
|
<title>Dependencies</title>
|
||
|
|
||
|
<para>
|
||
|
To allow for efficient parallel processing, BitBake handles
|
||
|
dependencies at the task level.
|
||
|
Dependencies can exist both between tasks within a single recipe
|
||
|
and between tasks in different recipes.
|
||
|
Following are examples of each:
|
||
|
<itemizedlist>
|
||
|
<listitem><para>For tasks within a single recipe, a
|
||
|
recipe's <filename>do_configure</filename>
|
||
|
task might need to complete before its
|
||
|
<filename>do_compile</filename> task can run.
|
||
|
</para></listitem>
|
||
|
<listitem><para>For tasks in different recipes, one
|
||
|
recipe's <filename>do_configure</filename>
|
||
|
task might require another recipe's
|
||
|
<filename>do_populate_sysroot</filename>
|
||
|
task to finish first such that the libraries and headers
|
||
|
provided by the other recipe are available.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This section describes several ways to declare dependencies.
|
||
|
Remember, even though dependencies are declared in different ways, they
|
||
|
are all simply dependencies between tasks.
|
||
|
</para>
|
||
|
|
||
|
<section id='dependencies-internal-to-the-bb-file'>
|
||
|
<title>Dependencies Internal to the <filename>.bb</filename> File</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses the <filename>addtask</filename> directive
|
||
|
to manage dependencies that are internal to a given recipe
|
||
|
file.
|
||
|
You can use the <filename>addtask</filename> directive to
|
||
|
indicate when a task is dependent on other tasks or when
|
||
|
other tasks depend on that recipe.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
addtask printdate after do_fetch before do_build
|
||
|
</literallayout>
|
||
|
In this example, the <filename>do_printdate</filename>
|
||
|
task depends on the completion of the
|
||
|
<filename>do_fetch</filename> task, and the
|
||
|
<filename>do_build</filename> task depends on the
|
||
|
completion of the <filename>do_printdate</filename>
|
||
|
task.
|
||
|
<note><para>
|
||
|
For a task to run, it must be a direct or indirect
|
||
|
dependency of some other task that is scheduled to
|
||
|
run.</para>
|
||
|
|
||
|
<para>For illustration, here are some examples:
|
||
|
<itemizedlist>
|
||
|
<listitem><para>
|
||
|
The directive
|
||
|
<filename>addtask mytask before do_configure</filename>
|
||
|
causes <filename>do_mytask</filename> to run before
|
||
|
<filename>do_configure</filename> runs.
|
||
|
Be aware that <filename>do_mytask</filename> still only
|
||
|
runs if its <link linkend='checksums'>input checksum</link>
|
||
|
has changed since the last time it was run.
|
||
|
Changes to the input checksum of
|
||
|
<filename>do_mytask</filename> also indirectly cause
|
||
|
<filename>do_configure</filename> to run.
|
||
|
</para></listitem>
|
||
|
<listitem><para>
|
||
|
The directive
|
||
|
<filename>addtask mytask after do_configure</filename>
|
||
|
by itself never causes <filename>do_mytask</filename>
|
||
|
to run.
|
||
|
<filename>do_mytask</filename> can still be run manually
|
||
|
as follows:
|
||
|
<literallayout class='monospaced'>
|
||
|
$ bitbake <replaceable>recipe</replaceable> -c mytask
|
||
|
</literallayout>
|
||
|
Declaring <filename>do_mytask</filename> as a dependency
|
||
|
of some other task that is scheduled to run also causes
|
||
|
it to run.
|
||
|
Regardless, the task runs after
|
||
|
<filename>do_configure</filename>.
|
||
|
</para></listitem>
|
||
|
</itemizedlist></para>
|
||
|
</note>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='build-dependencies'>
|
||
|
<title>Build Dependencies</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses the
|
||
|
<link linkend='var-DEPENDS'><filename>DEPENDS</filename></link>
|
||
|
variable to manage build time dependencies.
|
||
|
The <filename>[deptask]</filename> varflag for tasks
|
||
|
signifies the task of each
|
||
|
item listed in <filename>DEPENDS</filename> that must
|
||
|
complete before that task can be executed.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_configure[deptask] = "do_populate_sysroot"
|
||
|
</literallayout>
|
||
|
In this example, the <filename>do_populate_sysroot</filename>
|
||
|
task of each item in <filename>DEPENDS</filename> must complete before
|
||
|
<filename>do_configure</filename> can execute.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='runtime-dependencies'>
|
||
|
<title>Runtime Dependencies</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses the
|
||
|
<link linkend='var-PACKAGES'><filename>PACKAGES</filename></link>,
|
||
|
<link linkend='var-RDEPENDS'><filename>RDEPENDS</filename></link>, and
|
||
|
<link linkend='var-RRECOMMENDS'><filename>RRECOMMENDS</filename></link>
|
||
|
variables to manage runtime dependencies.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The <filename>PACKAGES</filename> variable lists runtime
|
||
|
packages.
|
||
|
Each of those packages can have <filename>RDEPENDS</filename> and
|
||
|
<filename>RRECOMMENDS</filename> runtime dependencies.
|
||
|
The <filename>[rdeptask]</filename> flag for tasks is used to
|
||
|
signify the task of each
|
||
|
item runtime dependency which must have completed before that
|
||
|
task can be executed.
|
||
|
<literallayout class='monospaced'>
|
||
|
do_package_qa[rdeptask] = "do_packagedata"
|
||
|
</literallayout>
|
||
|
In the previous example, the <filename>do_packagedata</filename>
|
||
|
task of each item in <filename>RDEPENDS</filename> must have
|
||
|
completed before <filename>do_package_qa</filename> can execute.
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='recursive-dependencies'>
|
||
|
<title>Recursive Dependencies</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses the <filename>[recrdeptask]</filename> flag to manage
|
||
|
recursive task dependencies.
|
||
|
BitBake looks through the build-time and runtime
|
||
|
dependencies of the current recipe, looks through
|
||
|
the task's inter-task
|
||
|
dependencies, and then adds dependencies for the
|
||
|
listed task.
|
||
|
Once BitBake has accomplished this, it recursively works through
|
||
|
the dependencies of those tasks.
|
||
|
Iterative passes continue until all dependencies are discovered
|
||
|
and added.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The <filename>[recrdeptask]</filename> flag is most commonly
|
||
|
used in high-level
|
||
|
recipes that need to wait for some task to finish "globally".
|
||
|
For example, <filename>image.bbclass</filename> has the following:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_rootfs[recrdeptask] += "do_packagedata"
|
||
|
</literallayout>
|
||
|
This statement says that the <filename>do_packagedata</filename>
|
||
|
task of the current recipe and all recipes reachable
|
||
|
(by way of dependencies) from the
|
||
|
image recipe must run before the <filename>do_rootfs</filename>
|
||
|
task can run.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
You might want to not only have BitBake look for
|
||
|
dependencies of those tasks, but also have BitBake look
|
||
|
for build-time and runtime dependencies of the dependent
|
||
|
tasks as well.
|
||
|
If that is the case, you need to reference the task name
|
||
|
itself in the task list:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_a[recrdeptask] = "do_a do_b"
|
||
|
</literallayout>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='inter-task-dependencies'>
|
||
|
<title>Inter-Task Dependencies</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses the <filename>[depends]</filename>
|
||
|
flag in a more generic form
|
||
|
to manage inter-task dependencies.
|
||
|
This more generic form allows for inter-dependency
|
||
|
checks for specific tasks rather than checks for
|
||
|
the data in <filename>DEPENDS</filename>.
|
||
|
Here is an example:
|
||
|
<literallayout class='monospaced'>
|
||
|
do_patch[depends] = "quilt-native:do_populate_sysroot"
|
||
|
</literallayout>
|
||
|
In this example, the <filename>do_populate_sysroot</filename>
|
||
|
task of the target <filename>quilt-native</filename>
|
||
|
must have completed before the
|
||
|
<filename>do_patch</filename> task can execute.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The <filename>[rdepends]</filename> flag works in a similar
|
||
|
way but takes targets
|
||
|
in the runtime namespace instead of the build-time dependency
|
||
|
namespace.
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='functions-you-can-call-from-within-python'>
|
||
|
<title>Functions You Can Call From Within Python</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake provides many functions you can call from
|
||
|
within Python functions.
|
||
|
This section lists the most commonly used functions,
|
||
|
and mentions where to find others.
|
||
|
</para>
|
||
|
|
||
|
<section id='functions-for-accessing-datastore-variables'>
|
||
|
<title>Functions for Accessing Datastore Variables</title>
|
||
|
|
||
|
<para>
|
||
|
It is often necessary to access variables in the
|
||
|
BitBake datastore using Python functions.
|
||
|
The Bitbake datastore has an API that allows you this
|
||
|
access.
|
||
|
Here is a list of available operations:
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
<informaltable frame='none'>
|
||
|
<tgroup cols='2' align='left' colsep='1' rowsep='1'>
|
||
|
<colspec colname='c1' colwidth='1*'/>
|
||
|
<colspec colname='c2' colwidth='1*'/>
|
||
|
<thead>
|
||
|
<row>
|
||
|
<entry align="left"><emphasis>Operation</emphasis></entry>
|
||
|
<entry align="left"><emphasis>Description</emphasis></entry>
|
||
|
</row>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.getVar("X", expand)</filename></entry>
|
||
|
<entry align="left">Returns the value of variable "X".
|
||
|
Using "expand=True" expands the value.
|
||
|
Returns "None" if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.setVar("X", "value")</filename></entry>
|
||
|
<entry align="left">Sets the variable "X" to "value".</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.appendVar("X", "value")</filename></entry>
|
||
|
<entry align="left">Adds "value" to the end of the variable "X".
|
||
|
Acts like <filename>d.setVar("X", "value")</filename>
|
||
|
if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.prependVar("X", "value")</filename></entry>
|
||
|
<entry align="left">Adds "value" to the start of the variable "X".
|
||
|
Acts like <filename>d.setVar("X", "value")</filename>
|
||
|
if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.delVar("X")</filename></entry>
|
||
|
<entry align="left">Deletes the variable "X" from the datastore.
|
||
|
Does nothing if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.renameVar("X", "Y")</filename></entry>
|
||
|
<entry align="left">Renames the variable "X" to "Y".
|
||
|
Does nothing if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.getVarFlag("X", flag, expand)</filename></entry>
|
||
|
<entry align="left">Returns the value of variable "X".
|
||
|
Using "expand=True" expands the value.
|
||
|
Returns "None" if either the variable "X" or the named flag
|
||
|
does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.setVarFlag("X", flag, "value")</filename></entry>
|
||
|
<entry align="left">Sets the named flag for variable "X" to "value".</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.appendVarFlag("X", flag, "value")</filename></entry>
|
||
|
<entry align="left">Appends "value" to the named flag on the
|
||
|
variable "X".
|
||
|
Acts like <filename>d.setVarFlag("X", flag, "value")</filename>
|
||
|
if the named flag does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.prependVarFlag("X", flag, "value")</filename></entry>
|
||
|
<entry align="left">Prepends "value" to the named flag on
|
||
|
the variable "X".
|
||
|
Acts like <filename>d.setVarFlag("X", flag, "value")</filename>
|
||
|
if the named flag does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.delVarFlag("X", flag)</filename></entry>
|
||
|
<entry align="left">Deletes the named flag on the variable
|
||
|
"X" from the datastore.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.setVarFlags("X", flagsdict)</filename></entry>
|
||
|
<entry align="left">Sets the flags specified in
|
||
|
the <filename>flagsdict()</filename> parameter.
|
||
|
<filename>setVarFlags</filename> does not clear previous flags.
|
||
|
Think of this operation as <filename>addVarFlags</filename>.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.getVarFlags("X")</filename></entry>
|
||
|
<entry align="left">Returns a <filename>flagsdict</filename>
|
||
|
of the flags for the variable "X".
|
||
|
Returns "None" if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.delVarFlags("X")</filename></entry>
|
||
|
<entry align="left">Deletes all the flags for the variable "X".
|
||
|
Does nothing if the variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
<row>
|
||
|
<entry align="left"><filename>d.expand(expression)</filename></entry>
|
||
|
<entry align="left">Expands variable references in the specified
|
||
|
string expression.
|
||
|
References to variables that do not exist are left as is.
|
||
|
For example, <filename>d.expand("foo ${X}")</filename>
|
||
|
expands to the literal string "foo ${X}" if the
|
||
|
variable "X" does not exist.</entry>
|
||
|
</row>
|
||
|
</tbody>
|
||
|
</tgroup>
|
||
|
</informaltable>
|
||
|
</para>
|
||
|
</section>
|
||
|
|
||
|
<section id='other-functions'>
|
||
|
<title>Other Functions</title>
|
||
|
|
||
|
<para>
|
||
|
You can find many other functions that can be called
|
||
|
from Python by looking at the source code of the
|
||
|
<filename>bb</filename> module, which is in
|
||
|
<filename>bitbake/lib/bb</filename>.
|
||
|
For example,
|
||
|
<filename>bitbake/lib/bb/utils.py</filename> includes
|
||
|
the commonly used functions
|
||
|
<filename>bb.utils.contains()</filename> and
|
||
|
<filename>bb.utils.mkdirhier()</filename>, which come
|
||
|
with docstrings.
|
||
|
</para>
|
||
|
</section>
|
||
|
</section>
|
||
|
|
||
|
<section id='task-checksums-and-setscene'>
|
||
|
<title>Task Checksums and Setscene</title>
|
||
|
|
||
|
<para>
|
||
|
BitBake uses checksums (or signatures) along with the setscene
|
||
|
to determine if a task needs to be run.
|
||
|
This section describes the process.
|
||
|
To help understand how BitBake does this, the section assumes an
|
||
|
OpenEmbedded metadata-based example.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This list is a place holder of content existed from previous work
|
||
|
on the manual.
|
||
|
Some or all of it probably needs integrated into the subsections
|
||
|
that make up this section.
|
||
|
For now, I have just provided a short glossary-like description
|
||
|
for each variable.
|
||
|
Ultimately, this list goes away.
|
||
|
<itemizedlist>
|
||
|
<listitem><para><filename>STAMP</filename>:
|
||
|
The base path to create stamp files.</para></listitem>
|
||
|
<listitem><para><filename>STAMPCLEAN</filename>
|
||
|
Again, the base path to create stamp files but can use wildcards
|
||
|
for matching a range of files for clean operations.
|
||
|
</para></listitem>
|
||
|
<listitem><para><filename>BB_STAMP_WHITELIST</filename>
|
||
|
Lists stamp files that are looked at when the stamp policy
|
||
|
is "whitelist".
|
||
|
</para></listitem>
|
||
|
<listitem><para><filename>BB_STAMP_POLICY</filename>
|
||
|
Defines the mode for comparing timestamps of stamp files.
|
||
|
</para></listitem>
|
||
|
<listitem><para><filename>BB_HASHCHECK_FUNCTION</filename>
|
||
|
Specifies the name of the function to call during
|
||
|
the "setscene" part of the task's execution in order
|
||
|
to validate the list of task hashes.
|
||
|
</para></listitem>
|
||
|
<listitem><para><filename>BB_SETSCENE_VERIFY_FUNCTION2</filename>
|
||
|
Specifies a function to call that verifies the list of
|
||
|
planned task execution before the main task execution
|
||
|
happens.
|
||
|
</para></listitem>
|
||
|
<listitem><para><filename>BB_SETSCENE_DEPVALID</filename>
|
||
|
Specifies a function BitBake calls that determines
|
||
|
whether BitBake requires a setscene dependency to
|
||
|
be met.
|
||
|
</para></listitem>
|
||
|
<listitem><para><filename>BB_TASKHASH</filename>
|
||
|
Within an executing task, this variable holds the hash
|
||
|
of the task as returned by the currently enabled
|
||
|
signature generator.
|
||
|
</para></listitem>
|
||
|
</itemizedlist>
|
||
|
</para>
|
||
|
</section>
|
||
|
</chapter>
|