| <!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> |