blob: 7f51674a92a39f534a72a6878c183995e46bde9e [file] [log] [blame]
.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
************
Common Tasks
************
This chapter describes fundamental procedures such as creating layers,
adding new software packages, extending or customizing images, porting
work to new hardware (adding a new machine), and so forth. You will find
that the procedures documented here occur often in the development cycle
using the Yocto Project.
Understanding and Creating Layers
=================================
The OpenEmbedded build system supports organizing
:term:`Metadata` into multiple layers.
Layers allow you to isolate different types of customizations from each
other. For introductory information on the Yocto Project Layer Model,
see the
":ref:`overview-manual/yp-intro:the yocto project layer model`"
section in the Yocto Project Overview and Concepts Manual.
Creating Your Own Layer
-----------------------
It is very easy to create your own layers to use with the OpenEmbedded
build system. The Yocto Project ships with tools that speed up creating
layers. This section describes the steps you perform by hand to create
layers so that you can better understand them. For information about the
layer-creation tools, see the
":ref:`bsp-guide/bsp:creating a new bsp layer using the \`\`bitbake-layers\`\` script`"
section in the Yocto Project Board Support Package (BSP) Developer's
Guide and the ":ref:`dev-manual/common-tasks:creating a general layer using the \`\`bitbake-layers\`\` script`"
section further down in this manual.
Follow these general steps to create your layer without using tools:
1. *Check Existing Layers:* Before creating a new layer, you should be
sure someone has not already created a layer containing the Metadata
you need. You can see the :oe_layerindex:`OpenEmbedded Metadata Index <>`
for a list of layers from the OpenEmbedded community that can be used in
the Yocto Project. You could find a layer that is identical or close
to what you need.
2. *Create a Directory:* Create the directory for your layer. When you
create the layer, be sure to create the directory in an area not
associated with the Yocto Project :term:`Source Directory`
(e.g. the cloned ``poky`` repository).
While not strictly required, prepend the name of the directory with
the string "meta-". For example::
meta-mylayer
meta-GUI_xyz
meta-mymachine
With rare exceptions, a layer's name follows this form::
meta-root_name
Following this layer naming convention can save
you trouble later when tools, components, or variables "assume" your
layer name begins with "meta-". A notable example is in configuration
files as shown in the following step where layer names without the
"meta-" string are appended to several variables used in the
configuration.
3. *Create a Layer Configuration File:* Inside your new layer folder,
you need to create a ``conf/layer.conf`` file. It is easiest to take
an existing layer configuration file and copy that to your layer's
``conf`` directory and then modify the file as needed.
The ``meta-yocto-bsp/conf/layer.conf`` file in the Yocto Project
:yocto_git:`Source Repositories </poky/tree/meta-yocto-bsp/conf>`
demonstrates the required syntax. For your layer, you need to replace
"yoctobsp" with a unique identifier for your layer (e.g. "machinexyz"
for a layer named "meta-machinexyz")::
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "yoctobsp"
BBFILE_PATTERN_yoctobsp = "^${LAYERDIR}/"
BBFILE_PRIORITY_yoctobsp = "5"
LAYERVERSION_yoctobsp = "4"
LAYERSERIES_COMPAT_yoctobsp = "dunfell"
Following is an explanation of the layer configuration file:
- :term:`BBPATH`: Adds the layer's
root directory to BitBake's search path. Through the use of the
:term:`BBPATH` variable, BitBake locates class files (``.bbclass``),
configuration files, and files that are included with ``include``
and ``require`` statements. For these cases, BitBake uses the
first file that matches the name found in :term:`BBPATH`. This is
similar to the way the ``PATH`` variable is used for binaries. It
is recommended, therefore, that you use unique class and
configuration filenames in your custom layer.
- :term:`BBFILES`: Defines the
location for all recipes in the layer.
- :term:`BBFILE_COLLECTIONS`:
Establishes the current layer through a unique identifier that is
used throughout the OpenEmbedded build system to refer to the
layer. In this example, the identifier "yoctobsp" is the
representation for the container layer named "meta-yocto-bsp".
- :term:`BBFILE_PATTERN`:
Expands immediately during parsing to provide the directory of the
layer.
- :term:`BBFILE_PRIORITY`:
Establishes a priority to use for recipes in the layer when the
OpenEmbedded build finds recipes of the same name in different
layers.
- :term:`LAYERVERSION`:
Establishes a version number for the layer. You can use this
version number to specify this exact version of the layer as a
dependency when using the
:term:`LAYERDEPENDS`
variable.
- :term:`LAYERDEPENDS`:
Lists all layers on which this layer depends (if any).
- :term:`LAYERSERIES_COMPAT`:
Lists the :yocto_wiki:`Yocto Project </Releases>`
releases for which the current version is compatible. This
variable is a good way to indicate if your particular layer is
current.
4. *Add Content:* Depending on the type of layer, add the content. If
the layer adds support for a machine, add the machine configuration
in a ``conf/machine/`` file within the layer. If the layer adds
distro policy, add the distro configuration in a ``conf/distro/``
file within the layer. If the layer introduces new recipes, put the
recipes you need in ``recipes-*`` subdirectories within the layer.
.. note::
For an explanation of layer hierarchy that is compliant with the
Yocto Project, see the ":ref:`bsp-guide/bsp:example filesystem layout`"
section in the Yocto Project Board Support Package (BSP) Developer's Guide.
5. *Optionally Test for Compatibility:* If you want permission to use
the Yocto Project Compatibility logo with your layer or application
that uses your layer, perform the steps to apply for compatibility.
See the
":ref:`dev-manual/common-tasks:making sure your layer is compatible with yocto project`"
section for more information.
Following Best Practices When Creating Layers
---------------------------------------------
To create layers that are easier to maintain and that will not impact
builds for other machines, you should consider the information in the
following list:
- *Avoid "Overlaying" Entire Recipes from Other Layers in Your
Configuration:* In other words, do not copy an entire recipe into
your layer and then modify it. Rather, use an append file
(``.bbappend``) to override only those parts of the original recipe
you need to modify.
- *Avoid Duplicating Include Files:* Use append files (``.bbappend``)
for each recipe that uses an include file. Or, if you are introducing
a new recipe that requires the included file, use the path relative
to the original layer directory to refer to the file. For example,
use ``require recipes-core/``\ `package`\ ``/``\ `file`\ ``.inc`` instead
of ``require`` `file`\ ``.inc``. If you're finding you have to overlay
the include file, it could indicate a deficiency in the include file
in the layer to which it originally belongs. If this is the case, you
should try to address that deficiency instead of overlaying the
include file. For example, you could address this by getting the
maintainer of the include file to add a variable or variables to make
it easy to override the parts needing to be overridden.
- *Structure Your Layers:* Proper use of overrides within append files
and placement of machine-specific files within your layer can ensure
that a build is not using the wrong Metadata and negatively impacting
a build for a different machine. Following are some examples:
- *Modify Variables to Support a Different Machine:* Suppose you
have a layer named ``meta-one`` that adds support for building
machine "one". To do so, you use an append file named
``base-files.bbappend`` and create a dependency on "foo" by
altering the :term:`DEPENDS`
variable::
DEPENDS = "foo"
The dependency is created during any
build that includes the layer ``meta-one``. However, you might not
want this dependency for all machines. For example, suppose you
are building for machine "two" but your ``bblayers.conf`` file has
the ``meta-one`` layer included. During the build, the
``base-files`` for machine "two" will also have the dependency on
``foo``.
To make sure your changes apply only when building machine "one",
use a machine override with the :term:`DEPENDS` statement::
DEPENDS:one = "foo"
You should follow the same strategy when using ``:append``
and ``:prepend`` operations::
DEPENDS:append:one = " foo"
DEPENDS:prepend:one = "foo "
As an actual example, here's a
snippet from the generic kernel include file ``linux-yocto.inc``,
wherein the kernel compile and link options are adjusted in the
case of a subset of the supported architectures::
DEPENDS:append:aarch64 = " libgcc"
KERNEL_CC:append:aarch64 = " ${TOOLCHAIN_OPTIONS}"
KERNEL_LD:append:aarch64 = " ${TOOLCHAIN_OPTIONS}"
DEPENDS:append:nios2 = " libgcc"
KERNEL_CC:append:nios2 = " ${TOOLCHAIN_OPTIONS}"
KERNEL_LD:append:nios2 = " ${TOOLCHAIN_OPTIONS}"
DEPENDS:append:arc = " libgcc"
KERNEL_CC:append:arc = " ${TOOLCHAIN_OPTIONS}"
KERNEL_LD:append:arc = " ${TOOLCHAIN_OPTIONS}"
KERNEL_FEATURES:append:qemuall=" features/debug/printk.scc"
.. note::
Avoiding "+=" and "=+" and using machine-specific ``:append``
and ``:prepend`` operations is recommended as well.
- *Place Machine-Specific Files in Machine-Specific Locations:* When
you have a base recipe, such as ``base-files.bb``, that contains a
:term:`SRC_URI` statement to a
file, you can use an append file to cause the build to use your
own version of the file. For example, an append file in your layer
at ``meta-one/recipes-core/base-files/base-files.bbappend`` could
extend :term:`FILESPATH` using :term:`FILESEXTRAPATHS` as follows::
FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
The build for machine "one" will pick up your machine-specific file as
long as you have the file in
``meta-one/recipes-core/base-files/base-files/``. However, if you
are building for a different machine and the ``bblayers.conf``
file includes the ``meta-one`` layer and the location of your
machine-specific file is the first location where that file is
found according to :term:`FILESPATH`, builds for all machines will
also use that machine-specific file.
You can make sure that a machine-specific file is used for a
particular machine by putting the file in a subdirectory specific
to the machine. For example, rather than placing the file in
``meta-one/recipes-core/base-files/base-files/`` as shown above,
put it in ``meta-one/recipes-core/base-files/base-files/one/``.
Not only does this make sure the file is used only when building
for machine "one", but the build process locates the file more
quickly.
In summary, you need to place all files referenced from
:term:`SRC_URI` in a machine-specific subdirectory within the layer in
order to restrict those files to machine-specific builds.
- *Perform Steps to Apply for Yocto Project Compatibility:* If you want
permission to use the Yocto Project Compatibility logo with your
layer or application that uses your layer, perform the steps to apply
for compatibility. See the
":ref:`dev-manual/common-tasks:making sure your layer is compatible with yocto project`"
section for more information.
- *Follow the Layer Naming Convention:* Store custom layers in a Git
repository that use the ``meta-layer_name`` format.
- *Group Your Layers Locally:* Clone your repository alongside other
cloned ``meta`` directories from the :term:`Source Directory`.
Making Sure Your Layer is Compatible With Yocto Project
-------------------------------------------------------
When you create a layer used with the Yocto Project, it is advantageous
to make sure that the layer interacts well with existing Yocto Project
layers (i.e. the layer is compatible with the Yocto Project). Ensuring
compatibility makes the layer easy to be consumed by others in the Yocto
Project community and could allow you permission to use the Yocto
Project Compatible Logo.
.. note::
Only Yocto Project member organizations are permitted to use the
Yocto Project Compatible Logo. The logo is not available for general
use. For information on how to become a Yocto Project member
organization, see the :yocto_home:`Yocto Project Website <>`.
The Yocto Project Compatibility Program consists of a layer application
process that requests permission to use the Yocto Project Compatibility
Logo for your layer and application. The process consists of two parts:
1. Successfully passing a script (``yocto-check-layer``) that when run
against your layer, tests it against constraints based on experiences
of how layers have worked in the real world and where pitfalls have
been found. Getting a "PASS" result from the script is required for
successful compatibility registration.
2. Completion of an application acceptance form, which you can find at
:yocto_home:`/webform/yocto-project-compatible-registration`.
To be granted permission to use the logo, you need to satisfy the
following:
- Be able to check the box indicating that you got a "PASS" when
running the script against your layer.
- Answer "Yes" to the questions on the form or have an acceptable
explanation for any questions answered "No".
- Be a Yocto Project Member Organization.
The remainder of this section presents information on the registration
form and on the ``yocto-check-layer`` script.
Yocto Project Compatible Program Application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use the form to apply for your layer's approval. Upon successful
application, you can use the Yocto Project Compatibility Logo with your
layer and the application that uses your layer.
To access the form, use this link:
:yocto_home:`/webform/yocto-project-compatible-registration`.
Follow the instructions on the form to complete your application.
The application consists of the following sections:
- *Contact Information:* Provide your contact information as the fields
require. Along with your information, provide the released versions
of the Yocto Project for which your layer is compatible.
- *Acceptance Criteria:* Provide "Yes" or "No" answers for each of the
items in the checklist. There is space at the bottom of the form for
any explanations for items for which you answered "No".
- *Recommendations:* Provide answers for the questions regarding Linux
kernel use and build success.
``yocto-check-layer`` Script
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``yocto-check-layer`` script provides you a way to assess how
compatible your layer is with the Yocto Project. You should run this
script prior to using the form to apply for compatibility as described
in the previous section. You need to achieve a "PASS" result in order to
have your application form successfully processed.
The script divides tests into three areas: COMMON, BSP, and DISTRO. For
example, given a distribution layer (DISTRO), the layer must pass both
the COMMON and DISTRO related tests. Furthermore, if your layer is a BSP
layer, the layer must pass the COMMON and BSP set of tests.
To execute the script, enter the following commands from your build
directory::
$ source oe-init-build-env
$ yocto-check-layer your_layer_directory
Be sure to provide the actual directory for your
layer as part of the command.
Entering the command causes the script to determine the type of layer
and then to execute a set of specific tests against the layer. The
following list overviews the test:
- ``common.test_readme``: Tests if a ``README`` file exists in the
layer and the file is not empty.
- ``common.test_parse``: Tests to make sure that BitBake can parse the
files without error (i.e. ``bitbake -p``).
- ``common.test_show_environment``: Tests that the global or per-recipe
environment is in order without errors (i.e. ``bitbake -e``).
- ``common.test_world``: Verifies that ``bitbake world`` works.
- ``common.test_signatures``: Tests to be sure that BSP and DISTRO
layers do not come with recipes that change signatures.
- ``common.test_layerseries_compat``: Verifies layer compatibility is
set properly.
- ``bsp.test_bsp_defines_machines``: Tests if a BSP layer has machine
configurations.
- ``bsp.test_bsp_no_set_machine``: Tests to ensure a BSP layer does not
set the machine when the layer is added.
- ``bsp.test_machine_world``: Verifies that ``bitbake world`` works
regardless of which machine is selected.
- ``bsp.test_machine_signatures``: Verifies that building for a
particular machine affects only the signature of tasks specific to
that machine.
- ``distro.test_distro_defines_distros``: Tests if a DISTRO layer has
distro configurations.
- ``distro.test_distro_no_set_distros``: Tests to ensure a DISTRO layer
does not set the distribution when the layer is added.
Enabling Your Layer
-------------------
Before the OpenEmbedded build system can use your new layer, you need to
enable it. To enable your layer, simply add your layer's path to the
:term:`BBLAYERS` variable in your ``conf/bblayers.conf`` file, which is
found in the :term:`Build Directory`.
The following example shows how to enable a layer named
``meta-mylayer``::
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/user/poky/meta \
/home/user/poky/meta-poky \
/home/user/poky/meta-yocto-bsp \
/home/user/poky/meta-mylayer \
"
BitBake parses each ``conf/layer.conf`` file from the top down as
specified in the :term:`BBLAYERS` variable within the ``conf/bblayers.conf``
file. During the processing of each ``conf/layer.conf`` file, BitBake
adds the recipes, classes and configurations contained within the
particular layer to the source directory.
Appending Other Layers Metadata With Your Layer
-----------------------------------------------
A recipe that appends Metadata to another recipe is called a BitBake
append file. A BitBake append file uses the ``.bbappend`` file type
suffix, while the corresponding recipe to which Metadata is being
appended uses the ``.bb`` file type suffix.
You can use a ``.bbappend`` file in your layer to make additions or
changes to the content of another layer's recipe without having to copy
the other layer's recipe into your layer. Your ``.bbappend`` file
resides in your layer, while the main ``.bb`` recipe file to which you
are appending Metadata resides in a different layer.
Being able to append information to an existing recipe not only avoids
duplication, but also automatically applies recipe changes from a
different layer into your layer. If you were copying recipes, you would
have to manually merge changes as they occur.
When you create an append file, you must use the same root name as the
corresponding recipe file. For example, the append file
``someapp_3.1.bbappend`` must apply to ``someapp_3.1.bb``. This
means the original recipe and append filenames are version
number-specific. If the corresponding recipe is renamed to update to a
newer version, you must also rename and possibly update the
corresponding ``.bbappend`` as well. During the build process, BitBake
displays an error on starting if it detects a ``.bbappend`` file that
does not have a corresponding recipe with a matching name. See the
:term:`BB_DANGLINGAPPENDS_WARNONLY`
variable for information on how to handle this error.
Overlaying a File Using Your Layer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As an example, consider the main formfactor recipe and a corresponding
formfactor append file both from the :term:`Source Directory`.
Here is the main
formfactor recipe, which is named ``formfactor_0.0.bb`` and located in
the "meta" layer at ``meta/recipes-bsp/formfactor``::
SUMMARY = "Device formfactor information"
DESCRIPTION = "A formfactor configuration file provides information about the \
target hardware for which the image is being built and information that the \
build system cannot obtain from other sources such as the kernel."
SECTION = "base"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
PR = "r45"
SRC_URI = "file://config file://machconfig"
S = "${WORKDIR}"
PACKAGE_ARCH = "${MACHINE_ARCH}"
INHIBIT_DEFAULT_DEPS = "1"
do_install() {
# Install file only if it has contents
install -d ${D}${sysconfdir}/formfactor/
install -m 0644 ${S}/config ${D}${sysconfdir}/formfactor/
if [ -s "${S}/machconfig" ]; then
install -m 0644 ${S}/machconfig ${D}${sysconfdir}/formfactor/
fi
}
In the main recipe, note the :term:`SRC_URI`
variable, which tells the OpenEmbedded build system where to find files
during the build.
Following is the append file, which is named ``formfactor_0.0.bbappend``
and is from the Raspberry Pi BSP Layer named ``meta-raspberrypi``. The
file is in the layer at ``recipes-bsp/formfactor``::
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
By default, the build system uses the
:term:`FILESPATH` variable to
locate files. This append file extends the locations by setting the
:term:`FILESEXTRAPATHS`
variable. Setting this variable in the ``.bbappend`` file is the most
reliable and recommended method for adding directories to the search
path used by the build system to find files.
The statement in this example extends the directories to include
``${``\ :term:`THISDIR`\ ``}/${``\ :term:`PN`\ ``}``,
which resolves to a directory named ``formfactor`` in the same directory
in which the append file resides (i.e.
``meta-raspberrypi/recipes-bsp/formfactor``. This implies that you must
have the supporting directory structure set up that will contain any
files or patches you will be including from the layer.
Using the immediate expansion assignment operator ``:=`` is important
because of the reference to :term:`THISDIR`. The trailing colon character is
important as it ensures that items in the list remain colon-separated.
.. note::
BitBake automatically defines the :term:`THISDIR` variable. You should
never set this variable yourself. Using ":prepend" as part of the
:term:`FILESEXTRAPATHS` ensures your path will be searched prior to other
paths in the final list.
Also, not all append files add extra files. Many append files simply
allow to add build options (e.g. ``systemd``). For these cases, your
append file would not even use the :term:`FILESEXTRAPATHS` statement.
The end result of this ``.bbappend`` file is that on a Raspberry Pi, where
``rpi`` will exist in the list of :term:`OVERRIDES`, the file
``meta-raspberrypi/recipes-bsp/formfactor/formfactor/rpi/machconfig`` will be
used during :ref:`ref-tasks-fetch` and the test for a non-zero file size in
:ref:`ref-tasks-install` will return true, and the file will be installed.
Prioritizing Your Layer
-----------------------
Each layer is assigned a priority value. Priority values control which
layer takes precedence if there are recipe files with the same name in
multiple layers. For these cases, the recipe file from the layer with a
higher priority number takes precedence. Priority values also affect the
order in which multiple ``.bbappend`` files for the same recipe are
applied. You can either specify the priority manually, or allow the
build system to calculate it based on the layer's dependencies.
To specify the layer's priority manually, use the
:term:`BBFILE_PRIORITY`
variable and append the layer's root name::
BBFILE_PRIORITY_mylayer = "1"
.. note::
It is possible for a recipe with a lower version number
:term:`PV` in a layer that has a higher
priority to take precedence.
Also, the layer priority does not currently affect the precedence
order of ``.conf`` or ``.bbclass`` files. Future versions of BitBake
might address this.
Managing Layers
---------------
You can use the BitBake layer management tool ``bitbake-layers`` to
provide a view into the structure of recipes across a multi-layer
project. Being able to generate output that reports on configured layers
with their paths and priorities and on ``.bbappend`` files and their
applicable recipes can help to reveal potential problems.
For help on the BitBake layer management tool, use the following
command::
$ bitbake-layers --help
NOTE: Starting bitbake server...
usage: bitbake-layers [-d] [-q] [-F] [--color COLOR] [-h] <subcommand> ...
BitBake layers utility
optional arguments:
-d, --debug Enable debug output
-q, --quiet Print only errors
-F, --force Force add without recipe parse verification
--color COLOR Colorize output (where COLOR is auto, always, never)
-h, --help show this help message and exit
subcommands:
<subcommand>
layerindex-fetch Fetches a layer from a layer index along with its
dependent layers, and adds them to conf/bblayers.conf.
layerindex-show-depends
Find layer dependencies from layer index.
add-layer Add one or more layers to bblayers.conf.
remove-layer Remove one or more layers from bblayers.conf.
flatten flatten layer configuration into a separate output
directory.
show-layers show current configured layers.
show-overlayed list overlayed recipes (where the same recipe exists
in another layer)
show-recipes list available recipes, showing the layer they are
provided by
show-appends list bbappend files and recipe files they apply to
show-cross-depends Show dependencies between recipes that cross layer
boundaries.
create-layer Create a basic layer
Use bitbake-layers <subcommand> --help to get help on a specific command
The following list describes the available commands:
- ``help:`` Displays general help or help on a specified command.
- ``show-layers:`` Shows the current configured layers.
- ``show-overlayed:`` Lists overlayed recipes. A recipe is overlayed
when a recipe with the same name exists in another layer that has a
higher layer priority.
- ``show-recipes:`` Lists available recipes and the layers that
provide them.
- ``show-appends:`` Lists ``.bbappend`` files and the recipe files to
which they apply.
- ``show-cross-depends:`` Lists dependency relationships between
recipes that cross layer boundaries.
- ``add-layer:`` Adds a layer to ``bblayers.conf``.
- ``remove-layer:`` Removes a layer from ``bblayers.conf``
- ``flatten:`` Flattens the layer configuration into a separate
output directory. Flattening your layer configuration builds a
"flattened" directory that contains the contents of all layers, with
any overlayed recipes removed and any ``.bbappend`` files appended to
the corresponding recipes. You might have to perform some manual
cleanup of the flattened layer as follows:
- Non-recipe files (such as patches) are overwritten. The flatten
command shows a warning for these files.
- Anything beyond the normal layer setup has been added to the
``layer.conf`` file. Only the lowest priority layer's
``layer.conf`` is used.
- Overridden and appended items from ``.bbappend`` files need to be
cleaned up. The contents of each ``.bbappend`` end up in the
flattened recipe. However, if there are appended or changed
variable values, you need to tidy these up yourself. Consider the
following example. Here, the ``bitbake-layers`` command adds the
line ``#### bbappended ...`` so that you know where the following
lines originate::
...
DESCRIPTION = "A useful utility"
...
EXTRA_OECONF = "--enable-something"
...
#### bbappended from meta-anotherlayer ####
DESCRIPTION = "Customized utility"
EXTRA_OECONF += "--enable-somethingelse"
Ideally, you would tidy up these utilities as follows::
...
DESCRIPTION = "Customized utility"
...
EXTRA_OECONF = "--enable-something --enable-somethingelse"
...
- ``layerindex-fetch``: Fetches a layer from a layer index, along
with its dependent layers, and adds the layers to the
``conf/bblayers.conf`` file.
- ``layerindex-show-depends``: Finds layer dependencies from the
layer index.
- ``create-layer``: Creates a basic layer.
Creating a General Layer Using the ``bitbake-layers`` Script
------------------------------------------------------------
The ``bitbake-layers`` script with the ``create-layer`` subcommand
simplifies creating a new general layer.
.. note::
- For information on BSP layers, see the ":ref:`bsp-guide/bsp:bsp layers`"
section in the Yocto
Project Board Specific (BSP) Developer's Guide.
- In order to use a layer with the OpenEmbedded build system, you
need to add the layer to your ``bblayers.conf`` configuration
file. See the ":ref:`dev-manual/common-tasks:adding a layer using the \`\`bitbake-layers\`\` script`"
section for more information.
The default mode of the script's operation with this subcommand is to
create a layer with the following:
- A layer priority of 6.
- A ``conf`` subdirectory that contains a ``layer.conf`` file.
- A ``recipes-example`` subdirectory that contains a further
subdirectory named ``example``, which contains an ``example.bb``
recipe file.
- A ``COPYING.MIT``, which is the license statement for the layer. The
script assumes you want to use the MIT license, which is typical for
most layers, for the contents of the layer itself.
- A ``README`` file, which is a file describing the contents of your
new layer.
In its simplest form, you can use the following command form to create a
layer. The command creates a layer whose name corresponds to
"your_layer_name" in the current directory::
$ bitbake-layers create-layer your_layer_name
As an example, the following command creates a layer named ``meta-scottrif``
in your home directory::
$ cd /usr/home
$ bitbake-layers create-layer meta-scottrif
NOTE: Starting bitbake server...
Add your new layer with 'bitbake-layers add-layer meta-scottrif'
If you want to set the priority of the layer to other than the default
value of "6", you can either use the ``--priority`` option or you
can edit the
:term:`BBFILE_PRIORITY` value
in the ``conf/layer.conf`` after the script creates it. Furthermore, if
you want to give the example recipe file some name other than the
default, you can use the ``--example-recipe-name`` option.
The easiest way to see how the ``bitbake-layers create-layer`` command
works is to experiment with the script. You can also read the usage
information by entering the following::
$ bitbake-layers create-layer --help
NOTE: Starting bitbake server...
usage: bitbake-layers create-layer [-h] [--priority PRIORITY]
[--example-recipe-name EXAMPLERECIPE]
layerdir
Create a basic layer
positional arguments:
layerdir Layer directory to create
optional arguments:
-h, --help show this help message and exit
--priority PRIORITY, -p PRIORITY
Layer directory to create
--example-recipe-name EXAMPLERECIPE, -e EXAMPLERECIPE
Filename of the example recipe
Adding a Layer Using the ``bitbake-layers`` Script
--------------------------------------------------
Once you create your general layer, you must add it to your
``bblayers.conf`` file. Adding the layer to this configuration file
makes the OpenEmbedded build system aware of your layer so that it can
search it for metadata.
Add your layer by using the ``bitbake-layers add-layer`` command::
$ bitbake-layers add-layer your_layer_name
Here is an example that adds a
layer named ``meta-scottrif`` to the configuration file. Following the
command that adds the layer is another ``bitbake-layers`` command that
shows the layers that are in your ``bblayers.conf`` file::
$ bitbake-layers add-layer meta-scottrif
NOTE: Starting bitbake server...
Parsing recipes: 100% |##########################################################| Time: 0:00:49
Parsing of 1441 .bb files complete (0 cached, 1441 parsed). 2055 targets, 56 skipped, 0 masked, 0 errors.
$ bitbake-layers show-layers
NOTE: Starting bitbake server...
layer path priority
==========================================================================
meta /home/scottrif/poky/meta 5
meta-poky /home/scottrif/poky/meta-poky 5
meta-yocto-bsp /home/scottrif/poky/meta-yocto-bsp 5
workspace /home/scottrif/poky/build/workspace 99
meta-scottrif /home/scottrif/poky/build/meta-scottrif 6
Adding the layer to this file
enables the build system to locate the layer during the build.
.. note::
During a build, the OpenEmbedded build system looks in the layers
from the top of the list down to the bottom in that order.
Customizing Images
==================
You can customize images to satisfy particular requirements. This
section describes several methods and provides guidelines for each.
Customizing Images Using ``local.conf``
---------------------------------------
Probably the easiest way to customize an image is to add a package by
way of the ``local.conf`` configuration file. Because it is limited to
local use, this method generally only allows you to add packages and is
not as flexible as creating your own customized image. When you add
packages using local variables this way, you need to realize that these
variable changes are in effect for every build and consequently affect
all images, which might not be what you require.
To add a package to your image using the local configuration file, use
the :term:`IMAGE_INSTALL` variable with the ``:append`` operator::
IMAGE_INSTALL:append = " strace"
Use of the syntax is important -
specifically, the space between the quote and the package name, which is
``strace`` in this example. This space is required since the ``:append``
operator does not add the space.
Furthermore, you must use ``:append`` instead of the ``+=`` operator if
you want to avoid ordering issues. The reason for this is because doing
so unconditionally appends to the variable and avoids ordering problems
due to the variable being set in image recipes and ``.bbclass`` files
with operators like ``?=``. Using ``:append`` ensures the operation
takes effect.
As shown in its simplest use, ``IMAGE_INSTALL:append`` affects all
images. It is possible to extend the syntax so that the variable applies
to a specific image only. Here is an example::
IMAGE_INSTALL:append:pn-core-image-minimal = " strace"
This example adds ``strace`` to the ``core-image-minimal`` image only.
You can add packages using a similar approach through the
:term:`CORE_IMAGE_EXTRA_INSTALL` variable. If you use this variable, only
``core-image-*`` images are affected.
Customizing Images Using Custom ``IMAGE_FEATURES`` and ``EXTRA_IMAGE_FEATURES``
-------------------------------------------------------------------------------
Another method for customizing your image is to enable or disable
high-level image features by using the
:term:`IMAGE_FEATURES` and
:term:`EXTRA_IMAGE_FEATURES`
variables. Although the functions for both variables are nearly
equivalent, best practices dictate using :term:`IMAGE_FEATURES` from within
a recipe and using :term:`EXTRA_IMAGE_FEATURES` from within your
``local.conf`` file, which is found in the
:term:`Build Directory`.
To understand how these features work, the best reference is
``meta/classes/image.bbclass``. This class lists out the available
:term:`IMAGE_FEATURES` of which most map to package groups while some, such
as ``debug-tweaks`` and ``read-only-rootfs``, resolve as general
configuration settings.
In summary, the file looks at the contents of the :term:`IMAGE_FEATURES`
variable and then maps or configures the feature accordingly. Based on
this information, the build system automatically adds the appropriate
packages or configurations to the
:term:`IMAGE_INSTALL` variable.
Effectively, you are enabling extra features by extending the class or
creating a custom class for use with specialized image ``.bb`` files.
Use the :term:`EXTRA_IMAGE_FEATURES` variable from within your local
configuration file. Using a separate area from which to enable features
with this variable helps you avoid overwriting the features in the image
recipe that are enabled with :term:`IMAGE_FEATURES`. The value of
:term:`EXTRA_IMAGE_FEATURES` is added to :term:`IMAGE_FEATURES` within
``meta/conf/bitbake.conf``.
To illustrate how you can use these variables to modify your image,
consider an example that selects the SSH server. The Yocto Project ships
with two SSH servers you can use with your images: Dropbear and OpenSSH.
Dropbear is a minimal SSH server appropriate for resource-constrained
environments, while OpenSSH is a well-known standard SSH server
implementation. By default, the ``core-image-sato`` image is configured
to use Dropbear. The ``core-image-full-cmdline`` and ``core-image-lsb``
images both include OpenSSH. The ``core-image-minimal`` image does not
contain an SSH server.
You can customize your image and change these defaults. Edit the
:term:`IMAGE_FEATURES` variable in your recipe or use the
:term:`EXTRA_IMAGE_FEATURES` in your ``local.conf`` file so that it
configures the image you are working with to include
``ssh-server-dropbear`` or ``ssh-server-openssh``.
.. note::
See the ":ref:`ref-manual/features:image features`" section in the Yocto
Project Reference Manual for a complete list of image features that ship
with the Yocto Project.
Customizing Images Using Custom .bb Files
-----------------------------------------
You can also customize an image by creating a custom recipe that defines
additional software as part of the image. The following example shows
the form for the two lines you need::
IMAGE_INSTALL = "packagegroup-core-x11-base package1 package2"
inherit core-image
Defining the software using a custom recipe gives you total control over
the contents of the image. It is important to use the correct names of
packages in the :term:`IMAGE_INSTALL` variable. You must use the
OpenEmbedded notation and not the Debian notation for the names (e.g.
``glibc-dev`` instead of ``libc6-dev``).
The other method for creating a custom image is to base it on an
existing image. For example, if you want to create an image based on
``core-image-sato`` but add the additional package ``strace`` to the
image, copy the ``meta/recipes-sato/images/core-image-sato.bb`` to a new
``.bb`` and add the following line to the end of the copy::
IMAGE_INSTALL += "strace"
Customizing Images Using Custom Package Groups
----------------------------------------------
For complex custom images, the best approach for customizing an image is
to create a custom package group recipe that is used to build the image
or images. A good example of a package group recipe is
``meta/recipes-core/packagegroups/packagegroup-base.bb``.
If you examine that recipe, you see that the :term:`PACKAGES` variable lists
the package group packages to produce. The ``inherit packagegroup``
statement sets appropriate default values and automatically adds
``-dev``, ``-dbg``, and ``-ptest`` complementary packages for each
package specified in the :term:`PACKAGES` statement.
.. note::
The ``inherit packagegroup`` line should be located near the top of the
recipe, certainly before the :term:`PACKAGES` statement.
For each package you specify in :term:`PACKAGES`, you can use :term:`RDEPENDS`
and :term:`RRECOMMENDS` entries to provide a list of packages the parent
task package should contain. You can see examples of these further down
in the ``packagegroup-base.bb`` recipe.
Here is a short, fabricated example showing the same basic pieces for a
hypothetical packagegroup defined in ``packagegroup-custom.bb``, where
the variable :term:`PN` is the standard way to abbreviate the reference to
the full packagegroup name ``packagegroup-custom``::
DESCRIPTION = "My Custom Package Groups"
inherit packagegroup
PACKAGES = "\
${PN}-apps \
${PN}-tools \
"
RDEPENDS:${PN}-apps = "\
dropbear \
portmap \
psplash"
RDEPENDS:${PN}-tools = "\
oprofile \
oprofileui-server \
lttng-tools"
RRECOMMENDS:${PN}-tools = "\
kernel-module-oprofile"
In the previous example, two package group packages are created with
their dependencies and their recommended package dependencies listed:
``packagegroup-custom-apps``, and ``packagegroup-custom-tools``. To
build an image using these package group packages, you need to add
``packagegroup-custom-apps`` and/or ``packagegroup-custom-tools`` to
:term:`IMAGE_INSTALL`. For other forms of image dependencies see the other
areas of this section.
Customizing an Image Hostname
-----------------------------
By default, the configured hostname (i.e. ``/etc/hostname``) in an image
is the same as the machine name. For example, if
:term:`MACHINE` equals "qemux86", the
configured hostname written to ``/etc/hostname`` is "qemux86".
You can customize this name by altering the value of the "hostname"
variable in the ``base-files`` recipe using either an append file or a
configuration file. Use the following in an append file::
hostname = "myhostname"
Use the following in a configuration file::
hostname:pn-base-files = "myhostname"
Changing the default value of the variable "hostname" can be useful in
certain situations. For example, suppose you need to do extensive
testing on an image and you would like to easily identify the image
under test from existing images with typical default hostnames. In this
situation, you could change the default hostname to "testme", which
results in all the images using the name "testme". Once testing is
complete and you do not need to rebuild the image for test any longer,
you can easily reset the default hostname.
Another point of interest is that if you unset the variable, the image
will have no default hostname in the filesystem. Here is an example that
unsets the variable in a configuration file::
hostname:pn-base-files = ""
Having no default hostname in the filesystem is suitable for
environments that use dynamic hostnames such as virtual machines.
Writing a New Recipe
====================
Recipes (``.bb`` files) are fundamental components in the Yocto Project
environment. Each software component built by the OpenEmbedded build
system requires a recipe to define the component. This section describes
how to create, write, and test a new recipe.
.. note::
For information on variables that are useful for recipes and for
information about recipe naming issues, see the
":ref:`ref-manual/varlocality:recipes`" section of the Yocto Project
Reference Manual.
Overview
--------
The following figure shows the basic process for creating a new recipe.
The remainder of the section provides details for the steps.
.. image:: figures/recipe-workflow.png
:align: center
Locate or Automatically Create a Base Recipe
--------------------------------------------
You can always write a recipe from scratch. However, there are three choices
that can help you quickly get started with a new recipe:
- ``devtool add``: A command that assists in creating a recipe and an
environment conducive to development.
- ``recipetool create``: A command provided by the Yocto Project that
automates creation of a base recipe based on the source files.
- *Existing Recipes:* Location and modification of an existing recipe
that is similar in function to the recipe you need.
.. note::
For information on recipe syntax, see the
":ref:`dev-manual/common-tasks:recipe syntax`" section.
Creating the Base Recipe Using ``devtool add``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``devtool add`` command uses the same logic for auto-creating the
recipe as ``recipetool create``, which is listed below. Additionally,
however, ``devtool add`` sets up an environment that makes it easy for
you to patch the source and to make changes to the recipe as is often
necessary when adding a recipe to build a new piece of software to be
included in a build.
You can find a complete description of the ``devtool add`` command in
the ":ref:`sdk-manual/extensible:a closer look at \`\`devtool add\`\``" section
in the Yocto Project Application Development and the Extensible Software
Development Kit (eSDK) manual.
Creating the Base Recipe Using ``recipetool create``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``recipetool create`` automates creation of a base recipe given a set of
source code files. As long as you can extract or point to the source
files, the tool will construct a recipe and automatically configure all
pre-build information into the recipe. For example, suppose you have an
application that builds using Autotools. Creating the base recipe using
``recipetool`` results in a recipe that has the pre-build dependencies,
license requirements, and checksums configured.
To run the tool, you just need to be in your
:term:`Build Directory` and have sourced the
build environment setup script (i.e.
:ref:`structure-core-script`).
To get help on the tool, use the following command::
$ recipetool -h
NOTE: Starting bitbake server...
usage: recipetool [-d] [-q] [--color COLOR] [-h] <subcommand> ...
OpenEmbedded recipe tool
options:
-d, --debug Enable debug output
-q, --quiet Print only errors
--color COLOR Colorize output (where COLOR is auto, always, never)
-h, --help show this help message and exit
subcommands:
create Create a new recipe
newappend Create a bbappend for the specified target in the specified
layer
setvar Set a variable within a recipe
appendfile Create/update a bbappend to replace a target file
appendsrcfiles Create/update a bbappend to add or replace source files
appendsrcfile Create/update a bbappend to add or replace a source file
Use recipetool <subcommand> --help to get help on a specific command
Running ``recipetool create -o OUTFILE`` creates the base recipe and
locates it properly in the layer that contains your source files.
Following are some syntax examples:
- Use this syntax to generate a recipe based on source. Once generated,
the recipe resides in the existing source code layer::
recipetool create -o OUTFILE source
- Use this syntax to generate a recipe using code that
you extract from source. The extracted code is placed in its own layer
defined by :term:`EXTERNALSRC`.
::
recipetool create -o OUTFILE -x EXTERNALSRC source
- Use this syntax to generate a recipe based on source. The options
direct ``recipetool`` to generate debugging information. Once generated,
the recipe resides in the existing source code layer::
recipetool create -d -o OUTFILE source
Locating and Using a Similar Recipe
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before writing a recipe from scratch, it is often useful to discover
whether someone else has already written one that meets (or comes close
to meeting) your needs. The Yocto Project and OpenEmbedded communities
maintain many recipes that might be candidates for what you are doing.
You can find a good central index of these recipes in the
:oe_layerindex:`OpenEmbedded Layer Index <>`.
Working from an existing recipe or a skeleton recipe is the best way to
get started. Here are some points on both methods:
- *Locate and modify a recipe that is close to what you want to do:*
This method works when you are familiar with the current recipe
space. The method does not work so well for those new to the Yocto
Project or writing recipes.
Some risks associated with this method are using a recipe that has
areas totally unrelated to what you are trying to accomplish with
your recipe, not recognizing areas of the recipe that you might have
to add from scratch, and so forth. All these risks stem from
unfamiliarity with the existing recipe space.
- *Use and modify the following skeleton recipe:* If for some reason
you do not want to use ``recipetool`` and you cannot find an existing
recipe that is close to meeting your needs, you can use the following
structure to provide the fundamental areas of a new recipe.
::
DESCRIPTION = ""
HOMEPAGE = ""
LICENSE = ""
SECTION = ""
DEPENDS = ""
LIC_FILES_CHKSUM = ""
SRC_URI = ""
Storing and Naming the Recipe
-----------------------------
Once you have your base recipe, you should put it in your own layer and
name it appropriately. Locating it correctly ensures that the
OpenEmbedded build system can find it when you use BitBake to process
the recipe.
- *Storing Your Recipe:* The OpenEmbedded build system locates your
recipe through the layer's ``conf/layer.conf`` file and the
:term:`BBFILES` variable. This
variable sets up a path from which the build system can locate
recipes. Here is the typical use::
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
Consequently, you need to be sure you locate your new recipe inside
your layer such that it can be found.
You can find more information on how layers are structured in the
":ref:`dev-manual/common-tasks:understanding and creating layers`" section.
- *Naming Your Recipe:* When you name your recipe, you need to follow
this naming convention::
basename_version.bb
Use lower-cased characters and do not include the reserved suffixes
``-native``, ``-cross``, ``-initial``, or ``-dev`` casually (i.e. do not use
them as part of your recipe name unless the string applies). Here are some
examples:
.. code-block:: none
cups_1.7.0.bb
gawk_4.0.2.bb
irssi_0.8.16-rc1.bb
Running a Build on the Recipe
-----------------------------
Creating a new recipe is usually an iterative process that requires
using BitBake to process the recipe multiple times in order to
progressively discover and add information to the recipe file.
Assuming you have sourced the build environment setup script (i.e.
:ref:`structure-core-script`) and you are in
the :term:`Build Directory`, use
BitBake to process your recipe. All you need to provide is the
``basename`` of the recipe as described in the previous section::
$ bitbake basename
During the build, the OpenEmbedded build system creates a temporary work
directory for each recipe
(``${``\ :term:`WORKDIR`\ ``}``)
where it keeps extracted source files, log files, intermediate
compilation and packaging files, and so forth.
The path to the per-recipe temporary work directory depends on the
context in which it is being built. The quickest way to find this path
is to have BitBake return it by running the following::
$ bitbake -e basename | grep ^WORKDIR=
As an example, assume a Source Directory
top-level folder named ``poky``, a default Build Directory at
``poky/build``, and a ``qemux86-poky-linux`` machine target system.
Furthermore, suppose your recipe is named ``foo_1.3.0.bb``. In this
case, the work directory the build system uses to build the package
would be as follows::
poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0
Inside this directory you can find sub-directories such as ``image``,
``packages-split``, and ``temp``. After the build, you can examine these
to determine how well the build went.
.. note::
You can find log files for each task in the recipe's ``temp``
directory (e.g. ``poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0/temp``).
Log files are named ``log.taskname`` (e.g. ``log.do_configure``,
``log.do_fetch``, and ``log.do_compile``).
You can find more information about the build process in
":doc:`/overview-manual/development-environment`"
chapter of the Yocto Project Overview and Concepts Manual.
Fetching Code
-------------
The first thing your recipe must do is specify how to fetch the source
files. Fetching is controlled mainly through the
:term:`SRC_URI` variable. Your recipe
must have a :term:`SRC_URI` variable that points to where the source is
located. For a graphical representation of source locations, see the
":ref:`overview-manual/concepts:sources`" section in
the Yocto Project Overview and Concepts Manual.
The :ref:`ref-tasks-fetch` task uses
the prefix of each entry in the :term:`SRC_URI` variable value to determine
which :ref:`fetcher <bitbake:bitbake-user-manual/bitbake-user-manual-fetching:fetchers>` to use to get your
source files. It is the :term:`SRC_URI` variable that triggers the fetcher.
The :ref:`ref-tasks-patch` task uses
the variable after source is fetched to apply patches. The OpenEmbedded
build system uses
:term:`FILESOVERRIDES` for
scanning directory locations for local files in :term:`SRC_URI`.
The :term:`SRC_URI` variable in your recipe must define each unique location
for your source files. It is good practice to not hard-code version
numbers in a URL used in :term:`SRC_URI`. Rather than hard-code these
values, use ``${``\ :term:`PV`\ ``}``,
which causes the fetch process to use the version specified in the
recipe filename. Specifying the version in this manner means that
upgrading the recipe to a future version is as simple as renaming the
recipe to match the new version.
Here is a simple example from the
``meta/recipes-devtools/strace/strace_5.5.bb`` recipe where the source
comes from a single tarball. Notice the use of the
:term:`PV` variable::
SRC_URI = "https://strace.io/files/${PV}/strace-${PV}.tar.xz \
Files mentioned in :term:`SRC_URI` whose names end in a typical archive
extension (e.g. ``.tar``, ``.tar.gz``, ``.tar.bz2``, ``.zip``, and so
forth), are automatically extracted during the
:ref:`ref-tasks-unpack` task. For
another example that specifies these types of files, see the
":ref:`dev-manual/common-tasks:autotooled package`" section.
Another way of specifying source is from an SCM. For Git repositories,
you must specify :term:`SRCREV` and
you should specify :term:`PV` to include
the revision with :term:`SRCPV`. Here
is an example from the recipe
``meta/recipes-kernel/blktrace/blktrace_git.bb``::
SRCREV = "d6918c8832793b4205ed3bfede78c2f915c23385"
PR = "r6"
PV = "1.0.5+git${SRCPV}"
SRC_URI = "git://git.kernel.dk/blktrace.git \
file://ldflags.patch"
If your :term:`SRC_URI` statement includes URLs pointing to individual files
fetched from a remote server other than a version control system,
BitBake attempts to verify the files against checksums defined in your
recipe to ensure they have not been tampered with or otherwise modified
since the recipe was written. Two checksums are used:
``SRC_URI[md5sum]`` and ``SRC_URI[sha256sum]``.
If your :term:`SRC_URI` variable points to more than a single URL (excluding
SCM URLs), you need to provide the ``md5`` and ``sha256`` checksums for
each URL. For these cases, you provide a name for each URL as part of
the :term:`SRC_URI` and then reference that name in the subsequent checksum
statements. Here is an example combining lines from the files
``git.inc`` and ``git_2.24.1.bb``::
SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \
${KERNELORG_MIRROR}/software/scm/git/git-manpages-${PV}.tar.gz;name=manpages"
SRC_URI[tarball.md5sum] = "166bde96adbbc11c8843d4f8f4f9811b"
SRC_URI[tarball.sha256sum] = "ad5334956301c86841eb1e5b1bb20884a6bad89a10a6762c958220c7cf64da02"
SRC_URI[manpages.md5sum] = "31c2272a8979022497ba3d4202df145d"
SRC_URI[manpages.sha256sum] = "9a7ae3a093bea39770eb96ca3e5b40bff7af0b9f6123f089d7821d0e5b8e1230"
Proper values for ``md5`` and ``sha256`` checksums might be available
with other signatures on the download page for the upstream source (e.g.
``md5``, ``sha1``, ``sha256``, ``GPG``, and so forth). Because the
OpenEmbedded build system only deals with ``sha256sum`` and ``md5sum``,
you should verify all the signatures you find by hand.
If no :term:`SRC_URI` checksums are specified when you attempt to build the
recipe, or you provide an incorrect checksum, the build will produce an
error for each missing or incorrect checksum. As part of the error
message, the build system provides the checksum string corresponding to
the fetched file. Once you have the correct checksums, you can copy and
paste them into your recipe and then run the build again to continue.
.. note::
As mentioned, if the upstream source provides signatures for
verifying the downloaded source code, you should verify those
manually before setting the checksum values in the recipe and
continuing with the build.
This final example is a bit more complicated and is from the
``meta/recipes-sato/rxvt-unicode/rxvt-unicode_9.20.bb`` recipe. The
example's :term:`SRC_URI` statement identifies multiple files as the source
files for the recipe: a tarball, a patch file, a desktop file, and an
icon.
::
SRC_URI = "http://dist.schmorp.de/rxvt-unicode/Attic/rxvt-unicode-${PV}.tar.bz2 \
file://xwc.patch \
file://rxvt.desktop \
file://rxvt.png"
When you specify local files using the ``file://`` URI protocol, the
build system fetches files from the local machine. The path is relative
to the :term:`FILESPATH` variable
and searches specific directories in a certain order:
``${``\ :term:`BP`\ ``}``,
``${``\ :term:`BPN`\ ``}``, and
``files``. The directories are assumed to be subdirectories of the
directory in which the recipe or append file resides. For another
example that specifies these types of files, see the
":ref:`dev-manual/common-tasks:single .c file package (hello world!)`" section.
The previous example also specifies a patch file. Patch files are files
whose names usually end in ``.patch`` or ``.diff`` but can end with
compressed suffixes such as ``diff.gz`` and ``patch.bz2``, for example.
The build system automatically applies patches as described in the
":ref:`dev-manual/common-tasks:patching code`" section.
Unpacking Code
--------------
During the build, the
:ref:`ref-tasks-unpack` task unpacks
the source with ``${``\ :term:`S`\ ``}``
pointing to where it is unpacked.
If you are fetching your source files from an upstream source archived
tarball and the tarball's internal structure matches the common
convention of a top-level subdirectory named
``${``\ :term:`BPN`\ ``}-${``\ :term:`PV`\ ``}``,
then you do not need to set :term:`S`. However, if :term:`SRC_URI` specifies to
fetch source from an archive that does not use this convention, or from
an SCM like Git or Subversion, your recipe needs to define :term:`S`.
If processing your recipe using BitBake successfully unpacks the source
files, you need to be sure that the directory pointed to by ``${S}``
matches the structure of the source.
Patching Code
-------------
Sometimes it is necessary to patch code after it has been fetched. Any
files mentioned in :term:`SRC_URI` whose names end in ``.patch`` or
``.diff`` or compressed versions of these suffixes (e.g. ``diff.gz`` are
treated as patches. The
:ref:`ref-tasks-patch` task
automatically applies these patches.
The build system should be able to apply patches with the "-p1" option
(i.e. one directory level in the path will be stripped off). If your
patch needs to have more directory levels stripped off, specify the
number of levels using the "striplevel" option in the :term:`SRC_URI` entry
for the patch. Alternatively, if your patch needs to be applied in a
specific subdirectory that is not specified in the patch file, use the
"patchdir" option in the entry.
As with all local files referenced in
:term:`SRC_URI` using ``file://``,
you should place patch files in a directory next to the recipe either
named the same as the base name of the recipe
(:term:`BP` and
:term:`BPN`) or "files".
Licensing
---------
Your recipe needs to have both the
:term:`LICENSE` and
:term:`LIC_FILES_CHKSUM`
variables:
- :term:`LICENSE`: This variable specifies the license for the software.
If you do not know the license under which the software you are
building is distributed, you should go to the source code and look
for that information. Typical files containing this information
include ``COPYING``, :term:`LICENSE`, and ``README`` files. You could
also find the information near the top of a source file. For example,
given a piece of software licensed under the GNU General Public
License version 2, you would set :term:`LICENSE` as follows::
LICENSE = "GPLv2"
The licenses you specify within :term:`LICENSE` can have any name as long
as you do not use spaces, since spaces are used as separators between
license names. For standard licenses, use the names of the files in
``meta/files/common-licenses/`` or the :term:`SPDXLICENSEMAP` flag names
defined in ``meta/conf/licenses.conf``.
- :term:`LIC_FILES_CHKSUM`: The OpenEmbedded build system uses this
variable to make sure the license text has not changed. If it has,
the build produces an error and it affords you the chance to figure
it out and correct the problem.
You need to specify all applicable licensing files for the software.
At the end of the configuration step, the build process will compare
the checksums of the files to be sure the text has not changed. Any
differences result in an error with the message containing the
current checksum. For more explanation and examples of how to set the
:term:`LIC_FILES_CHKSUM` variable, see the
":ref:`dev-manual/common-tasks:tracking license changes`" section.
To determine the correct checksum string, you can list the
appropriate files in the :term:`LIC_FILES_CHKSUM` variable with incorrect
md5 strings, attempt to build the software, and then note the
resulting error messages that will report the correct md5 strings.
See the ":ref:`dev-manual/common-tasks:fetching code`" section for
additional information.
Here is an example that assumes the software has a ``COPYING`` file::
LIC_FILES_CHKSUM = "file://COPYING;md5=xxx"
When you try to build the
software, the build system will produce an error and give you the
correct string that you can substitute into the recipe file for a
subsequent build.
Dependencies
------------
Most software packages have a short list of other packages that they
require, which are called dependencies. These dependencies fall into two
main categories: build-time dependencies, which are required when the
software is built; and runtime dependencies, which are required to be
installed on the target in order for the software to run.
Within a recipe, you specify build-time dependencies using the
:term:`DEPENDS` variable. Although there are nuances,
items specified in :term:`DEPENDS` should be names of other
recipes. It is important that you specify all build-time dependencies
explicitly.
Another consideration is that configure scripts might automatically
check for optional dependencies and enable corresponding functionality
if those dependencies are found. If you wish to make a recipe that is
more generally useful (e.g. publish the recipe in a layer for others to
use), instead of hard-disabling the functionality, you can use the
:term:`PACKAGECONFIG` variable to allow functionality and the
corresponding dependencies to be enabled and disabled easily by other
users of the recipe.
Similar to build-time dependencies, you specify runtime dependencies
through a variable -
:term:`RDEPENDS`, which is
package-specific. All variables that are package-specific need to have
the name of the package added to the end as an override. Since the main
package for a recipe has the same name as the recipe, and the recipe's
name can be found through the
``${``\ :term:`PN`\ ``}`` variable, then
you specify the dependencies for the main package by setting
``RDEPENDS:${PN}``. If the package were named ``${PN}-tools``, then you
would set ``RDEPENDS:${PN}-tools``, and so forth.
Some runtime dependencies will be set automatically at packaging time.
These dependencies include any shared library dependencies (i.e. if a
package "example" contains "libexample" and another package "mypackage"
contains a binary that links to "libexample" then the OpenEmbedded build
system will automatically add a runtime dependency to "mypackage" on
"example"). See the
":ref:`overview-manual/concepts:automatically added runtime dependencies`"
section in the Yocto Project Overview and Concepts Manual for further
details.
Configuring the Recipe
----------------------
Most software provides some means of setting build-time configuration
options before compilation. Typically, setting these options is
accomplished by running a configure script with options, or by modifying
a build configuration file.
.. note::
As of Yocto Project Release 1.7, some of the core recipes that
package binary configuration scripts now disable the scripts due to
the scripts previously requiring error-prone path substitution. The
OpenEmbedded build system uses ``pkg-config`` now, which is much more
robust. You can find a list of the ``*-config`` scripts that are disabled
in the ":ref:`migration-1.7-binary-configuration-scripts-disabled`" section
in the Yocto Project Reference Manual.
A major part of build-time configuration is about checking for
build-time dependencies and possibly enabling optional functionality as
a result. You need to specify any build-time dependencies for the
software you are building in your recipe's
:term:`DEPENDS` value, in terms of
other recipes that satisfy those dependencies. You can often find
build-time or runtime dependencies described in the software's
documentation.
The following list provides configuration items of note based on how
your software is built:
- *Autotools:* If your source files have a ``configure.ac`` file, then
your software is built using Autotools. If this is the case, you just
need to modify the configuration.
When using Autotools, your recipe needs to inherit the
:ref:`autotools <ref-classes-autotools>` class
and your recipe does not have to contain a
:ref:`ref-tasks-configure` task.
However, you might still want to make some adjustments. For example,
you can set
:term:`EXTRA_OECONF` or
:term:`PACKAGECONFIG_CONFARGS`
to pass any needed configure options that are specific to the recipe.
- *CMake:* If your source files have a ``CMakeLists.txt`` file, then
your software is built using CMake. If this is the case, you just
need to modify the configuration.
When you use CMake, your recipe needs to inherit the
:ref:`cmake <ref-classes-cmake>` class and your
recipe does not have to contain a
:ref:`ref-tasks-configure` task.
You can make some adjustments by setting
:term:`EXTRA_OECMAKE` to
pass any needed configure options that are specific to the recipe.
.. note::
If you need to install one or more custom CMake toolchain files
that are supplied by the application you are building, install the
files to ``${D}${datadir}/cmake/Modules`` during ``do_install``.
- *Other:* If your source files do not have a ``configure.ac`` or
``CMakeLists.txt`` file, then your software is built using some
method other than Autotools or CMake. If this is the case, you
normally need to provide a
:ref:`ref-tasks-configure` task
in your recipe unless, of course, there is nothing to configure.
Even if your software is not being built by Autotools or CMake, you
still might not need to deal with any configuration issues. You need
to determine if configuration is even a required step. You might need
to modify a Makefile or some configuration file used for the build to
specify necessary build options. Or, perhaps you might need to run a
provided, custom configure script with the appropriate options.
For the case involving a custom configure script, you would run
``./configure --help`` and look for the options you need to set.
Once configuration succeeds, it is always good practice to look at the
``log.do_configure`` file to ensure that the appropriate options have
been enabled and no additional build-time dependencies need to be added
to :term:`DEPENDS`. For example, if the configure script reports that it
found something not mentioned in :term:`DEPENDS`, or that it did not find
something that it needed for some desired optional functionality, then
you would need to add those to :term:`DEPENDS`. Looking at the log might
also reveal items being checked for, enabled, or both that you do not
want, or items not being found that are in :term:`DEPENDS`, in which case
you would need to look at passing extra options to the configure script
as needed. For reference information on configure options specific to
the software you are building, you can consult the output of the
``./configure --help`` command within ``${S}`` or consult the software's
upstream documentation.
Using Headers to Interface with Devices
---------------------------------------
If your recipe builds an application that needs to communicate with some
device or needs an API into a custom kernel, you will need to provide
appropriate header files. Under no circumstances should you ever modify
the existing
``meta/recipes-kernel/linux-libc-headers/linux-libc-headers.inc`` file.
These headers are used to build ``libc`` and must not be compromised
with custom or machine-specific header information. If you customize
``libc`` through modified headers all other applications that use
``libc`` thus become affected.
.. note::
Never copy and customize the ``libc`` header file (i.e.
``meta/recipes-kernel/linux-libc-headers/linux-libc-headers.inc``).
The correct way to interface to a device or custom kernel is to use a
separate package that provides the additional headers for the driver or
other unique interfaces. When doing so, your application also becomes
responsible for creating a dependency on that specific provider.
Consider the following:
- Never modify ``linux-libc-headers.inc``. Consider that file to be
part of the ``libc`` system, and not something you use to access the
kernel directly. You should access ``libc`` through specific ``libc``
calls.
- Applications that must talk directly to devices should either provide
necessary headers themselves, or establish a dependency on a special
headers package that is specific to that driver.
For example, suppose you want to modify an existing header that adds I/O
control or network support. If the modifications are used by a small
number programs, providing a unique version of a header is easy and has
little impact. When doing so, bear in mind the guidelines in the
previous list.
.. note::
If for some reason your changes need to modify the behavior of the ``libc``,
and subsequently all other applications on the system, use a ``.bbappend``
to modify the ``linux-kernel-headers.inc`` file. However, take care to not
make the changes machine specific.
Consider a case where your kernel is older and you need an older
``libc`` ABI. The headers installed by your recipe should still be a
standard mainline kernel, not your own custom one.
When you use custom kernel headers you need to get them from
:term:`STAGING_KERNEL_DIR`,
which is the directory with kernel headers that are required to build
out-of-tree modules. Your recipe will also need the following::
do_configure[depends] += "virtual/kernel:do_shared_workdir"
Compilation
-----------
During a build, the ``do_compile`` task happens after source is fetched,
unpacked, and configured. If the recipe passes through ``do_compile``
successfully, nothing needs to be done.
However, if the compile step fails, you need to diagnose the failure.
Here are some common issues that cause failures.
.. note::
For cases where improper paths are detected for configuration files
or for when libraries/headers cannot be found, be sure you are using
the more robust ``pkg-config``. See the note in section
":ref:`dev-manual/common-tasks:Configuring the Recipe`" for additional information.
- *Parallel build failures:* These failures manifest themselves as
intermittent errors, or errors reporting that a file or directory
that should be created by some other part of the build process could
not be found. This type of failure can occur even if, upon
inspection, the file or directory does exist after the build has
failed, because that part of the build process happened in the wrong
order.
To fix the problem, you need to either satisfy the missing dependency
in the Makefile or whatever script produced the Makefile, or (as a
workaround) set :term:`PARALLEL_MAKE` to an empty string::
PARALLEL_MAKE = ""
For information on parallel Makefile issues, see the
":ref:`dev-manual/common-tasks:debugging parallel make races`" section.
- *Improper host path usage:* This failure applies to recipes building
for the target or ``nativesdk`` only. The failure occurs when the
compilation process uses improper headers, libraries, or other files
from the host system when cross-compiling for the target.
To fix the problem, examine the ``log.do_compile`` file to identify
the host paths being used (e.g. ``/usr/include``, ``/usr/lib``, and
so forth) and then either add configure options, apply a patch, or do
both.
- *Failure to find required libraries/headers:* If a build-time
dependency is missing because it has not been declared in
:term:`DEPENDS`, or because the
dependency exists but the path used by the build process to find the
file is incorrect and the configure step did not detect it, the
compilation process could fail. For either of these failures, the
compilation process notes that files could not be found. In these
cases, you need to go back and add additional options to the
configure script as well as possibly add additional build-time
dependencies to :term:`DEPENDS`.
Occasionally, it is necessary to apply a patch to the source to
ensure the correct paths are used. If you need to specify paths to
find files staged into the sysroot from other recipes, use the
variables that the OpenEmbedded build system provides (e.g.
:term:`STAGING_BINDIR`, :term:`STAGING_INCDIR`, :term:`STAGING_DATADIR`, and so
forth).
Installing
----------
During ``do_install``, the task copies the built files along with their
hierarchy to locations that would mirror their locations on the target
device. The installation process copies files from the
``${``\ :term:`S`\ ``}``,
``${``\ :term:`B`\ ``}``, and
``${``\ :term:`WORKDIR`\ ``}``
directories to the ``${``\ :term:`D`\ ``}``
directory to create the structure as it should appear on the target
system.
How your software is built affects what you must do to be sure your
software is installed correctly. The following list describes what you
must do for installation depending on the type of build system used by
the software being built:
- *Autotools and CMake:* If the software your recipe is building uses
Autotools or CMake, the OpenEmbedded build system understands how to
install the software. Consequently, you do not have to have a
``do_install`` task as part of your recipe. You just need to make
sure the install portion of the build completes with no issues.
However, if you wish to install additional files not already being
installed by ``make install``, you should do this using a
``do_install:append`` function using the install command as described
in the "Manual" bulleted item later in this list.
- *Other (using* ``make install``\ *)*: You need to define a ``do_install``
function in your recipe. The function should call
``oe_runmake install`` and will likely need to pass in the
destination directory as well. How you pass that path is dependent on
how the ``Makefile`` being run is written (e.g. ``DESTDIR=${D}``,
``PREFIX=${D}``, ``INSTALLROOT=${D}``, and so forth).
For an example recipe using ``make install``, see the
":ref:`dev-manual/common-tasks:makefile-based package`" section.
- *Manual:* You need to define a ``do_install`` function in your
recipe. The function must first use ``install -d`` to create the
directories under
``${``\ :term:`D`\ ``}``. Once the
directories exist, your function can use ``install`` to manually
install the built software into the directories.
You can find more information on ``install`` at
https://www.gnu.org/software/coreutils/manual/html_node/install-invocation.html.
For the scenarios that do not use Autotools or CMake, you need to track
the installation and diagnose and fix any issues until everything
installs correctly. You need to look in the default location of
``${D}``, which is ``${WORKDIR}/image``, to be sure your files have been
installed correctly.
.. note::
- During the installation process, you might need to modify some of
the installed files to suit the target layout. For example, you
might need to replace hard-coded paths in an initscript with
values of variables provided by the build system, such as
replacing ``/usr/bin/`` with ``${bindir}``. If you do perform such
modifications during ``do_install``, be sure to modify the
destination file after copying rather than before copying.
Modifying after copying ensures that the build system can
re-execute ``do_install`` if needed.
- ``oe_runmake install``, which can be run directly or can be run
indirectly by the
:ref:`autotools <ref-classes-autotools>` and
:ref:`cmake <ref-classes-cmake>` classes,
runs ``make install`` in parallel. Sometimes, a Makefile can have
missing dependencies between targets that can result in race
conditions. If you experience intermittent failures during
``do_install``, you might be able to work around them by disabling
parallel Makefile installs by adding the following to the recipe::
PARALLEL_MAKEINST = ""
See :term:`PARALLEL_MAKEINST` for additional information.
- If you need to install one or more custom CMake toolchain files
that are supplied by the application you are building, install the
files to ``${D}${datadir}/cmake/Modules`` during
:ref:`ref-tasks-install`.
Enabling System Services
------------------------
If you want to install a service, which is a process that usually starts
on boot and runs in the background, then you must include some
additional definitions in your recipe.
If you are adding services and the service initialization script or the
service file itself is not installed, you must provide for that
installation in your recipe using a ``do_install:append`` function. If
your recipe already has a ``do_install`` function, update the function
near its end rather than adding an additional ``do_install:append``
function.
When you create the installation for your services, you need to
accomplish what is normally done by ``make install``. In other words,
make sure your installation arranges the output similar to how it is
arranged on the target system.
The OpenEmbedded build system provides support for starting services two
different ways:
- *SysVinit:* SysVinit is a system and service manager that manages the
init system used to control the very basic functions of your system.
The init program is the first program started by the Linux kernel
when the system boots. Init then controls the startup, running and
shutdown of all other programs.
To enable a service using SysVinit, your recipe needs to inherit the
:ref:`update-rc.d <ref-classes-update-rc.d>`
class. The class helps facilitate safely installing the package on
the target.
You will need to set the
:term:`INITSCRIPT_PACKAGES`,
:term:`INITSCRIPT_NAME`,
and
:term:`INITSCRIPT_PARAMS`
variables within your recipe.
- *systemd:* System Management Daemon (systemd) was designed to replace
SysVinit and to provide enhanced management of services. For more
information on systemd, see the systemd homepage at
https://freedesktop.org/wiki/Software/systemd/.
To enable a service using systemd, your recipe needs to inherit the
:ref:`systemd <ref-classes-systemd>` class. See
the ``systemd.bbclass`` file located in your :term:`Source Directory`
section for
more information.
Packaging
---------
Successful packaging is a combination of automated processes performed
by the OpenEmbedded build system and some specific steps you need to
take. The following list describes the process:
- *Splitting Files*: The ``do_package`` task splits the files produced
by the recipe into logical components. Even software that produces a
single binary might still have debug symbols, documentation, and
other logical components that should be split out. The ``do_package``
task ensures that files are split up and packaged correctly.
- *Running QA Checks*: The
:ref:`insane <ref-classes-insane>` class adds a
step to the package generation process so that output quality
assurance checks are generated by the OpenEmbedded build system. This
step performs a range of checks to be sure the build's output is free
of common problems that show up during runtime. For information on
these checks, see the
:ref:`insane <ref-classes-insane>` class and
the ":ref:`ref-manual/qa-checks:qa error and warning messages`"
chapter in the Yocto Project Reference Manual.
- *Hand-Checking Your Packages*: After you build your software, you
need to be sure your packages are correct. Examine the
``${``\ :term:`WORKDIR`\ ``}/packages-split``
directory and make sure files are where you expect them to be. If you
discover problems, you can set
:term:`PACKAGES`,
:term:`FILES`,
``do_install(:append)``, and so forth as needed.
- *Splitting an Application into Multiple Packages*: If you need to
split an application into several packages, see the
":ref:`dev-manual/common-tasks:splitting an application into multiple packages`"
section for an example.
- *Installing a Post-Installation Script*: For an example showing how
to install a post-installation script, see the
":ref:`dev-manual/common-tasks:post-installation scripts`" section.
- *Marking Package Architecture*: Depending on what your recipe is
building and how it is configured, it might be important to mark the
packages produced as being specific to a particular machine, or to
mark them as not being specific to a particular machine or
architecture at all.
By default, packages apply to any machine with the same architecture
as the target machine. When a recipe produces packages that are
machine-specific (e.g. the
:term:`MACHINE` value is passed
into the configure script or a patch is applied only for a particular
machine), you should mark them as such by adding the following to the
recipe::
PACKAGE_ARCH = "${MACHINE_ARCH}"
On the other hand, if the recipe produces packages that do not
contain anything specific to the target machine or architecture at
all (e.g. recipes that simply package script files or configuration
files), you should use the
:ref:`allarch <ref-classes-allarch>` class to
do this for you by adding this to your recipe::
inherit allarch
Ensuring that the package architecture is correct is not critical
while you are doing the first few builds of your recipe. However, it
is important in order to ensure that your recipe rebuilds (or does
not rebuild) appropriately in response to changes in configuration,
and to ensure that you get the appropriate packages installed on the
target machine, particularly if you run separate builds for more than
one target machine.
Sharing Files Between Recipes
-----------------------------
Recipes often need to use files provided by other recipes on the build
host. For example, an application linking to a common library needs
access to the library itself and its associated headers. The way this
access is accomplished is by populating a sysroot with files. Each
recipe has two sysroots in its work directory, one for target files
(``recipe-sysroot``) and one for files that are native to the build host
(``recipe-sysroot-native``).
.. note::
You could find the term "staging" used within the Yocto project
regarding files populating sysroots (e.g. the :term:`STAGING_DIR`
variable).
Recipes should never populate the sysroot directly (i.e. write files
into sysroot). Instead, files should be installed into standard
locations during the
:ref:`ref-tasks-install` task within
the ``${``\ :term:`D`\ ``}`` directory. The
reason for this limitation is that almost all files that populate the
sysroot are cataloged in manifests in order to ensure the files can be
removed later when a recipe is either modified or removed. Thus, the
sysroot is able to remain free from stale files.
A subset of the files installed by the :ref:`ref-tasks-install` task are
used by the :ref:`ref-tasks-populate_sysroot` task as defined by the the
:term:`SYSROOT_DIRS` variable to automatically populate the sysroot. It
is possible to modify the list of directories that populate the sysroot.
The following example shows how you could add the ``/opt`` directory to
the list of directories within a recipe::
SYSROOT_DIRS += "/opt"
.. note::
The `/sysroot-only` is to be used by recipes that generate artifacts
that are not included in the target filesystem, allowing them to share
these artifacts without needing to use the :term:`DEPLOY_DIR`.
For a more complete description of the :ref:`ref-tasks-populate_sysroot`
task and its associated functions, see the
:ref:`staging <ref-classes-staging>` class.
Using Virtual Providers
-----------------------
Prior to a build, if you know that several different recipes provide the
same functionality, you can use a virtual provider (i.e. ``virtual/*``)
as a placeholder for the actual provider. The actual provider is
determined at build-time.
A common scenario where a virtual provider is used would be for the
kernel recipe. Suppose you have three kernel recipes whose
:term:`PN` values map to ``kernel-big``,
``kernel-mid``, and ``kernel-small``. Furthermore, each of these recipes
in some way uses a :term:`PROVIDES`
statement that essentially identifies itself as being able to provide
``virtual/kernel``. Here is one way through the
:ref:`kernel <ref-classes-kernel>` class::
PROVIDES += "${@ "virtual/kernel" if (d.getVar("KERNEL_PACKAGE_NAME") == "kernel") else "" }"
Any recipe that inherits the ``kernel`` class is
going to utilize a :term:`PROVIDES` statement that identifies that recipe as
being able to provide the ``virtual/kernel`` item.
Now comes the time to actually build an image and you need a kernel
recipe, but which one? You can configure your build to call out the
kernel recipe you want by using the :term:`PREFERRED_PROVIDER` variable. As
an example, consider the :yocto_git:`x86-base.inc
</poky/tree/meta/conf/machine/include/x86-base.inc>` include file, which is a
machine (i.e. :term:`MACHINE`) configuration file. This include file is the
reason all x86-based machines use the ``linux-yocto`` kernel. Here are the
relevant lines from the include file::
PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto"
PREFERRED_VERSION_linux-yocto ??= "4.15%"
When you use a virtual provider, you do not have to "hard code" a recipe
name as a build dependency. You can use the
:term:`DEPENDS` variable to state the
build is dependent on ``virtual/kernel`` for example::
DEPENDS = "virtual/kernel"
During the build, the OpenEmbedded build system picks
the correct recipe needed for the ``virtual/kernel`` dependency based on
the :term:`PREFERRED_PROVIDER` variable. If you want to use the small kernel
mentioned at the beginning of this section, configure your build as
follows::
PREFERRED_PROVIDER_virtual/kernel ??= "kernel-small"
.. note::
Any recipe that :term:`PROVIDES` a ``virtual/*`` item that is ultimately not
selected through :term:`PREFERRED_PROVIDER` does not get built. Preventing these
recipes from building is usually the desired behavior since this mechanism's
purpose is to select between mutually exclusive alternative providers.
The following lists specific examples of virtual providers:
- ``virtual/kernel``: Provides the name of the kernel recipe to use
when building a kernel image.
- ``virtual/bootloader``: Provides the name of the bootloader to use
when building an image.
- ``virtual/libgbm``: Provides ``gbm.pc``.
- ``virtual/egl``: Provides ``egl.pc`` and possibly ``wayland-egl.pc``.
- ``virtual/libgl``: Provides ``gl.pc`` (i.e. libGL).
- ``virtual/libgles1``: Provides ``glesv1_cm.pc`` (i.e. libGLESv1_CM).
- ``virtual/libgles2``: Provides ``glesv2.pc`` (i.e. libGLESv2).
.. note::
Virtual providers only apply to build time dependencies specified with
:term:`PROVIDES` and :term:`DEPENDS`. They do not apply to runtime
dependencies specified with :term:`RPROVIDES` and :term:`RDEPENDS`.
Properly Versioning Pre-Release Recipes
---------------------------------------
Sometimes the name of a recipe can lead to versioning problems when the
recipe is upgraded to a final release. For example, consider the
``irssi_0.8.16-rc1.bb`` recipe file in the list of example recipes in
the ":ref:`dev-manual/common-tasks:storing and naming the recipe`" section.
This recipe is at a release candidate stage (i.e. "rc1"). When the recipe is
released, the recipe filename becomes ``irssi_0.8.16.bb``. The version
change from ``0.8.16-rc1`` to ``0.8.16`` is seen as a decrease by the
build system and package managers, so the resulting packages will not
correctly trigger an upgrade.
In order to ensure the versions compare properly, the recommended
convention is to set :term:`PV` within the
recipe to "previous_version+current_version". You can use an additional
variable so that you can use the current version elsewhere. Here is an
example::
REALPV = "0.8.16-rc1"
PV = "0.8.15+${REALPV}"
Post-Installation Scripts
-------------------------
Post-installation scripts run immediately after installing a package on
the target or during image creation when a package is included in an
image. To add a post-installation script to a package, add a
``pkg_postinst:``\ `PACKAGENAME`\ ``()`` function to the recipe file
(``.bb``) and replace `PACKAGENAME` with the name of the package you want
to attach to the ``postinst`` script. To apply the post-installation
script to the main package for the recipe, which is usually what is
required, specify
``${``\ :term:`PN`\ ``}`` in place of
PACKAGENAME.
A post-installation function has the following structure::
pkg_postinst:PACKAGENAME() {
# Commands to carry out
}
The script defined in the post-installation function is called when the
root filesystem is created. If the script succeeds, the package is
marked as installed.
.. note::
Any RPM post-installation script that runs on the target should
return a 0 exit code. RPM does not allow non-zero exit codes for
these scripts, and the RPM package manager will cause the package to
fail installation on the target.
Sometimes it is necessary for the execution of a post-installation
script to be delayed until the first boot. For example, the script might
need to be executed on the device itself. To delay script execution
until boot time, you must explicitly mark post installs to defer to the
target. You can use ``pkg_postinst_ontarget()`` or call
``postinst_intercept delay_to_first_boot`` from ``pkg_postinst()``. Any
failure of a ``pkg_postinst()`` script (including exit 1) triggers an
error during the
:ref:`ref-tasks-rootfs` task.
If you have recipes that use ``pkg_postinst`` function and they require
the use of non-standard native tools that have dependencies during
rootfs construction, you need to use the
:term:`PACKAGE_WRITE_DEPS`
variable in your recipe to list these tools. If you do not use this
variable, the tools might be missing and execution of the
post-installation script is deferred until first boot. Deferring the
script to first boot is undesirable and for read-only rootfs impossible.
.. note::
There is equivalent support for pre-install, pre-uninstall, and post-uninstall
scripts by way of ``pkg_preinst``, ``pkg_prerm``, and ``pkg_postrm``,
respectively. These scrips work in exactly the same way as does
``pkg_postinst`` with the exception that they run at different times. Also,
because of when they run, they are not applicable to being run at image
creation time like ``pkg_postinst``.
Testing
-------
The final step for completing your recipe is to be sure that the
software you built runs correctly. To accomplish runtime testing, add
the build's output packages to your image and test them on the target.
For information on how to customize your image by adding specific
packages, see ":ref:`dev-manual/common-tasks:customizing images`" section.
Examples
--------
To help summarize how to write a recipe, this section provides some
examples given various scenarios:
- Recipes that use local files
- Using an Autotooled package
- Using a Makefile-based package
- Splitting an application into multiple packages
- Adding binaries to an image
Single .c File Package (Hello World!)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Building an application from a single file that is stored locally (e.g.
under ``files``) requires a recipe that has the file listed in the
:term:`SRC_URI` variable. Additionally, you need to manually write the
``do_compile`` and ``do_install`` tasks. The :term:`S` variable defines the
directory containing the source code, which is set to
:term:`WORKDIR` in this case - the
directory BitBake uses for the build.
::
SUMMARY = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"
do_compile() {
${CC} ${LDFLAGS} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
By default, the ``helloworld``, ``helloworld-dbg``, and
``helloworld-dev`` packages are built. For information on how to
customize the packaging process, see the
":ref:`dev-manual/common-tasks:splitting an application into multiple packages`"
section.
Autotooled Package
~~~~~~~~~~~~~~~~~~
Applications that use Autotools such as ``autoconf`` and ``automake``
require a recipe that has a source archive listed in :term:`SRC_URI` and
also inherit the
:ref:`autotools <ref-classes-autotools>` class,
which contains the definitions of all the steps needed to build an
Autotool-based application. The result of the build is automatically
packaged. And, if the application uses NLS for localization, packages
with local information are generated (one package per language).
Following is one example: (``hello_2.3.bb``)
::
SUMMARY = "GNU Helloworld application"
SECTION = "examples"
LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
SRC_URI = "${GNU_MIRROR}/hello/hello-${PV}.tar.gz"
inherit autotools gettext
The variable :term:`LIC_FILES_CHKSUM` is used to track source license
changes as described in the
":ref:`dev-manual/common-tasks:tracking license changes`" section in
the Yocto Project Overview and Concepts Manual. You can quickly create
Autotool-based recipes in a manner similar to the previous example.
Makefile-Based Package
~~~~~~~~~~~~~~~~~~~~~~
Applications that use GNU ``make`` also require a recipe that has the
source archive listed in :term:`SRC_URI`. You do not need to add a
``do_compile`` step since by default BitBake starts the ``make`` command
to compile the application. If you need additional ``make`` options, you
should store them in the
:term:`EXTRA_OEMAKE` or
:term:`PACKAGECONFIG_CONFARGS`
variables. BitBake passes these options into the GNU ``make``
invocation. Note that a ``do_install`` task is still required.
Otherwise, BitBake runs an empty ``do_install`` task by default.
Some applications might require extra parameters to be passed to the
compiler. For example, the application might need an additional header
path. You can accomplish this by adding to the :term:`CFLAGS` variable. The
following example shows this::
CFLAGS:prepend = "-I ${S}/include "
In the following example, ``mtd-utils`` is a makefile-based package::
SUMMARY = "Tools for managing memory technology devices"
SECTION = "base"
DEPENDS = "zlib lzo e2fsprogs util-linux"
HOMEPAGE = "http://www.linux-mtd.infradead.org/"
LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://COPYING;md5=0636e73ff0215e8d672dc4c32c317bb3 \
file://include/common.h;beginline=1;endline=17;md5=ba05b07912a44ea2bf81ce409380049c"
# Use the latest version at 26 Oct, 2013
SRCREV = "9f107132a6a073cce37434ca9cda6917dd8d866b"
SRC_URI = "git://git.infradead.org/mtd-utils.git \
file://add-exclusion-to-mkfs-jffs2-git-2.patch \
"
PV = "1.5.1+git${SRCPV}"
S = "${WORKDIR}/git"
EXTRA_OEMAKE = "'CC=${CC}' 'RANLIB=${RANLIB}' 'AR=${AR}' 'CFLAGS=${CFLAGS} -I${S}/include -DWITHOUT_XATTR' 'BUILDDIR=${S}'"
do_install () {
oe_runmake install DESTDIR=${D} SBINDIR=${sbindir} MANDIR=${mandir} INCLUDEDIR=${includedir}
}
PACKAGES =+ "mtd-utils-jffs2 mtd-utils-ubifs mtd-utils-misc"
FILES:mtd-utils-jffs2 = "${sbindir}/mkfs.jffs2 ${sbindir}/jffs2dump ${sbindir}/jffs2reader ${sbindir}/sumtool"
FILES:mtd-utils-ubifs = "${sbindir}/mkfs.ubifs ${sbindir}/ubi*"
FILES:mtd-utils-misc = "${sbindir}/nftl* ${sbindir}/ftl* ${sbindir}/rfd* ${sbindir}/doc* ${sbindir}/serve_image ${sbindir}/recv_image"
PARALLEL_MAKE = ""
BBCLASSEXTEND = "native"
Splitting an Application into Multiple Packages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can use the variables :term:`PACKAGES` and :term:`FILES` to split an
application into multiple packages.
Following is an example that uses the ``libxpm`` recipe. By default,
this recipe generates a single package that contains the library along
with a few binaries. You can modify the recipe to split the binaries
into separate packages::
require xorg-lib-common.inc
SUMMARY = "Xpm: X Pixmap extension library"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://COPYING;md5=51f4270b012ecd4ab1a164f5f4ed6cf7"
DEPENDS += "libxext libsm libxt"
PE = "1"
XORG_PN = "libXpm"
PACKAGES =+ "sxpm cxpm"
FILES:cxpm = "${bindir}/cxpm"
FILES:sxpm = "${bindir}/sxpm"
In the previous example, we want to ship the ``sxpm`` and ``cxpm``
binaries in separate packages. Since ``bindir`` would be packaged into
the main :term:`PN` package by default, we prepend the :term:`PACKAGES` variable
so additional package names are added to the start of list. This results
in the extra ``FILES:*`` variables then containing information that
define which files and directories go into which packages. Files
included by earlier packages are skipped by latter packages. Thus, the
main :term:`PN` package does not include the above listed files.
Packaging Externally Produced Binaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sometimes, you need to add pre-compiled binaries to an image. For
example, suppose that there are binaries for proprietary code,
created by a particular division of a company. Your part of the company
needs to use those binaries as part of an image that you are building
using the OpenEmbedded build system. Since you only have the binaries
and not the source code, you cannot use a typical recipe that expects to
fetch the source specified in
:term:`SRC_URI` and then compile it.
One method is to package the binaries and then install them as part of
the image. Generally, it is not a good idea to package binaries since,
among other things, it can hinder the ability to reproduce builds and
could lead to compatibility problems with ABI in the future. However,
sometimes you have no choice.
The easiest solution is to create a recipe that uses the
:ref:`bin_package <ref-classes-bin-package>` class
and to be sure that you are using default locations for build artifacts.
In most cases, the ``bin_package`` class handles "skipping" the
configure and compile steps as well as sets things up to grab packages
from the appropriate area. In particular, this class sets ``noexec`` on
both the :ref:`ref-tasks-configure`
and :ref:`ref-tasks-compile` tasks,
sets ``FILES:${PN}`` to "/" so that it picks up all files, and sets up a
:ref:`ref-tasks-install` task, which
effectively copies all files from ``${S}`` to ``${D}``. The
``bin_package`` class works well when the files extracted into ``${S}``
are already laid out in the way they should be laid out on the target.
For more information on these variables, see the
:term:`FILES`,
:term:`PN`,
:term:`S`, and
:term:`D` variables in the Yocto Project
Reference Manual's variable glossary.
.. note::
- Using :term:`DEPENDS` is a good
idea even for components distributed in binary form, and is often
necessary for shared libraries. For a shared library, listing the
library dependencies in :term:`DEPENDS` makes sure that the libraries
are available in the staging sysroot when other recipes link
against the library, which might be necessary for successful
linking.
- Using :term:`DEPENDS` also allows runtime dependencies between
packages to be added automatically. See the
":ref:`overview-manual/concepts:automatically added runtime dependencies`"
section in the Yocto Project Overview and Concepts Manual for more
information.
If you cannot use the ``bin_package`` class, you need to be sure you are
doing the following:
- Create a recipe where the
:ref:`ref-tasks-configure` and
:ref:`ref-tasks-compile` tasks do
nothing: It is usually sufficient to just not define these tasks in
the recipe, because the default implementations do nothing unless a
Makefile is found in
``${``\ :term:`S`\ ``}``.
If ``${S}`` might contain a Makefile, or if you inherit some class
that replaces ``do_configure`` and ``do_compile`` with custom
versions, then you can use the
``[``\ :ref:`noexec <bitbake-user-manual/bitbake-user-manual-metadata:variable flags>`\ ``]``
flag to turn the tasks into no-ops, as follows::
do_configure[noexec] = "1"
do_compile[noexec] = "1"
Unlike
:ref:`bitbake:bitbake-user-manual/bitbake-user-manual-metadata:deleting a task`,
using the flag preserves the dependency chain from the
:ref:`ref-tasks-fetch`,
:ref:`ref-tasks-unpack`, and
:ref:`ref-tasks-patch` tasks to the
:ref:`ref-tasks-install` task.
- Make sure your ``do_install`` task installs the binaries
appropriately.
- Ensure that you set up :term:`FILES`
(usually
``FILES:${``\ :term:`PN`\ ``}``) to
point to the files you have installed, which of course depends on
where you have installed them and whether those files are in
different locations than the defaults.
.. note::
If image prelinking is enabled (e.g. "image-prelink" is in :term:`USER_CLASSES`
which it is by default), prelink will change the binaries in the generated images
and this often catches people out. Remove that class to ensure binaries are
preserved exactly if that is necessary.
Following Recipe Style Guidelines
---------------------------------
When writing recipes, it is good to conform to existing style
guidelines. The :oe_wiki:`OpenEmbedded Styleguide </Styleguide>` wiki page
provides rough guidelines for preferred recipe style.
It is common for existing recipes to deviate a bit from this style.
However, aiming for at least a consistent style is a good idea. Some
practices, such as omitting spaces around ``=`` operators in assignments
or ordering recipe components in an erratic way, are widely seen as poor
style.
Recipe Syntax
-------------
Understanding recipe file syntax is important for writing recipes. The
following list overviews the basic items that make up a BitBake recipe
file. For more complete BitBake syntax descriptions, see the
":doc:`bitbake-user-manual/bitbake-user-manual-metadata`"
chapter of the BitBake User Manual.
- *Variable Assignments and Manipulations:* Variable assignments allow
a value to be assigned to a variable. The assignment can be static
text or might include the contents of other variables. In addition to
the assignment, appending and prepending operations are also
supported.
The following example shows some of the ways you can use variables in
recipes::
S = "${WORKDIR}/postfix-${PV}"
CFLAGS += "-DNO_ASM"
SRC_URI:append = " file://fixup.patch"
- *Functions:* Functions provide a series of actions to be performed.
You usually use functions to override the default implementation of a
task function or to complement a default function (i.e. append or
prepend to an existing function). Standard functions use ``sh`` shell
syntax, although access to OpenEmbedded variables and internal
methods are also available.
Here is an example function from the ``sed`` recipe::
do_install () {
autotools_do_install
install -d ${D}${base_bindir}
mv ${D}${bindir}/sed ${D}${base_bindir}/sed
rmdir ${D}${bindir}/
}
It is
also possible to implement new functions that are called between
existing tasks as long as the new functions are not replacing or
complementing the default functions. You can implement functions in
Python instead of shell. Both of these options are not seen in the
majority of recipes.
- *Keywords:* BitBake recipes use only a few keywords. You use keywords
to include common functions (``inherit``), load parts of a recipe
from other files (``include`` and ``require``) and export variables
to the environment (``export``).
The following example shows the use of some of these keywords::
export POSTCONF = "${STAGING_BINDIR}/postconf"
inherit autoconf
require otherfile.inc
- *Comments (#):* Any lines that begin with the hash character (``#``)
are treated as comment lines and are ignored::
# This is a comment
This next list summarizes the most important and most commonly used
parts of the recipe syntax. For more information on these parts of the
syntax, you can reference the
:doc:`bitbake:bitbake-user-manual/bitbake-user-manual-metadata` chapter
in the BitBake User Manual.
- *Line Continuation (\\):* Use the backward slash (``\``) character to
split a statement over multiple lines. Place the slash character at
the end of the line that is to be continued on the next line::
VAR = "A really long \
line"
.. note::
You cannot have any characters including spaces or tabs after the
slash character.
- *Using Variables (${VARNAME}):* Use the ``${VARNAME}`` syntax to
access the contents of a variable::
SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"
.. note::
It is important to understand that the value of a variable
expressed in this form does not get substituted automatically. The
expansion of these expressions happens on-demand later (e.g.
usually when a function that makes reference to the variable
executes). This behavior ensures that the values are most
appropriate for the context in which they are finally used. On the
rare occasion that you do need the variable expression to be
expanded immediately, you can use the
:=
operator instead of
=
when you make the assignment, but this is not generally needed.
- *Quote All Assignments ("value"):* Use double quotes around values in
all variable assignments (e.g. ``"value"``). Following is an example::
VAR1 = "${OTHERVAR}"
VAR2 = "The version is ${PV}"
- *Conditional Assignment (?=):* Conditional assignment is used to
assign a value to a variable, but only when the variable is currently
unset. Use the question mark followed by the equal sign (``?=``) to
make a "soft" assignment used for conditional assignment. Typically,
"soft" assignments are used in the ``local.conf`` file for variables
that are allowed to come through from the external environment.
Here is an example where ``VAR1`` is set to "New value" if it is
currently empty. However, if ``VAR1`` has already been set, it
remains unchanged::
VAR1 ?= "New value"
In this next example, ``VAR1`` is left with the value "Original value"::
VAR1 = "Original value"
VAR1 ?= "New value"
- *Appending (+=):* Use the plus character followed by the equals sign
(``+=``) to append values to existing variables.
.. note::
This operator adds a space between the existing content of the
variable and the new content.
Here is an example::
SRC_URI += "file://fix-makefile.patch"
- *Prepending (=+):* Use the equals sign followed by the plus character
(``=+``) to prepend values to existing variables.
.. note::
This operator adds a space between the new content and the
existing content of the variable.
Here is an example::
VAR =+ "Starts"
- *Appending (:append):* Use the ``:append`` operator to append values
to existing variables. This operator does not add any additional
space. Also, the operator is applied after all the ``+=``, and ``=+``
operators have been applied and after all ``=`` assignments have
occurred.
The following example shows the space being explicitly added to the
start to ensure the appended value is not merged with the existing
value::
SRC_URI:append = " file://fix-makefile.patch"
You can also use
the ``:append`` operator with overrides, which results in the actions
only being performed for the specified target or machine::
SRC_URI:append:sh4 = " file://fix-makefile.patch"
- *Prepending (:prepend):* Use the ``:prepend`` operator to prepend
values to existing variables. This operator does not add any
additional space. Also, the operator is applied after all the ``+=``,
and ``=+`` operators have been applied and after all ``=``
assignments have occurred.
The following example shows the space being explicitly added to the
end to ensure the prepended value is not merged with the existing
value::
CFLAGS:prepend = "-I${S}/myincludes "
You can also use the
``:prepend`` operator with overrides, which results in the actions
only being performed for the specified target or machine::
CFLAGS:prepend:sh4 = "-I${S}/myincludes "
- *Overrides:* You can use overrides to set a value conditionally,
typically based on how the recipe is being built. For example, to set
the :term:`KBRANCH` variable's
value to "standard/base" for any target
:term:`MACHINE`, except for
qemuarm where it should be set to "standard/arm-versatile-926ejs",
you would do the following::
KBRANCH = "standard/base"
KBRANCH:qemuarm = "standard/arm-versatile-926ejs"
Overrides are also used to separate
alternate values of a variable in other situations. For example, when
setting variables such as
:term:`FILES` and
:term:`RDEPENDS` that are
specific to individual packages produced by a recipe, you should
always use an override that specifies the name of the package.
- *Indentation:* Use spaces for indentation rather than tabs. For
shell functions, both currently work. However, it is a policy
decision of the Yocto Project to use tabs in shell functions. Realize
that some layers have a policy to use spaces for all indentation.
- *Using Python for Complex Operations:* For more advanced processing,
it is possible to use Python code during variable assignments (e.g.
search and replacement on a variable).
You indicate Python code using the ``${@python_code}`` syntax for the
variable assignment::
SRC_URI = "ftp://ftp.info-zip.org/pub/infozip/src/zip${@d.getVar('PV',1).replace('.', '')}.tgz
- *Shell Function Syntax:* Write shell functions as if you were writing
a shell script when you describe a list of actions to take. You
should ensure that your script works with a generic ``sh`` and that
it does not require any ``bash`` or other shell-specific
functionality. The same considerations apply to various system
utilities (e.g. ``sed``, ``grep``, ``awk``, and so forth) that you
might wish to use. If in doubt, you should check with multiple
implementations - including those from BusyBox.
Adding a New Machine
====================
Adding a new machine to the Yocto Project is a straightforward process.
This section describes how to add machines that are similar to those
that the Yocto Project already supports.
.. note::
Although well within the capabilities of the Yocto Project, adding a
totally new architecture might require changes to ``gcc``/``glibc``
and to the site information, which is beyond the scope of this
manual.
For a complete example that shows how to add a new machine, see the
":ref:`bsp-guide/bsp:creating a new bsp layer using the \`\`bitbake-layers\`\` script`"
section in the Yocto Project Board Support Package (BSP) Developer's
Guide.
Adding the Machine Configuration File
-------------------------------------
To add a new machine, you need to add a new machine configuration file
to the layer's ``conf/machine`` directory. This configuration file
provides details about the device you are adding.
The OpenEmbedded build system uses the root name of the machine
configuration file to reference the new machine. For example, given a
machine configuration file named ``crownbay.conf``, the build system
recognizes the machine as "crownbay".
The most important variables you must set in your machine configuration
file or include from a lower-level configuration file are as follows:
- :term:`TARGET_ARCH` (e.g. "arm")
- ``PREFERRED_PROVIDER_virtual/kernel``
- :term:`MACHINE_FEATURES` (e.g. "apm screen wifi")
You might also need these variables:
- :term:`SERIAL_CONSOLES` (e.g. "115200;ttyS0 115200;ttyS1")
- :term:`KERNEL_IMAGETYPE` (e.g. "zImage")
- :term:`IMAGE_FSTYPES` (e.g. "tar.gz jffs2")
You can find full details on these variables in the reference section.
You can leverage existing machine ``.conf`` files from
``meta-yocto-bsp/conf/machine/``.
Adding a Kernel for the Machine
-------------------------------
The OpenEmbedded build system needs to be able to build a kernel for the
machine. You need to either create a new kernel recipe for this machine,
or extend an existing kernel recipe. You can find several kernel recipe
examples in the Source Directory at ``meta/recipes-kernel/linux`` that
you can use as references.
If you are creating a new kernel recipe, normal recipe-writing rules
apply for setting up a :term:`SRC_URI`. Thus, you need to specify any
necessary patches and set :term:`S` to point at the source code. You need to
create a ``do_configure`` task that configures the unpacked kernel with
a ``defconfig`` file. You can do this by using a ``make defconfig``
command or, more commonly, by copying in a suitable ``defconfig`` file
and then running ``make oldconfig``. By making use of ``inherit kernel``
and potentially some of the ``linux-*.inc`` files, most other
functionality is centralized and the defaults of the class normally work
well.
If you are extending an existing kernel recipe, it is usually a matter
of adding a suitable ``defconfig`` file. The file needs to be added into
a location similar to ``defconfig`` files used for other machines in a
given kernel recipe. A possible way to do this is by listing the file in
the :term:`SRC_URI` and adding the machine to the expression in
:term:`COMPATIBLE_MACHINE`::
COMPATIBLE_MACHINE = '(qemux86|qemumips)'
For more information on ``defconfig`` files, see the
":ref:`kernel-dev/common:changing the configuration`"
section in the Yocto Project Linux Kernel Development Manual.
Adding a Formfactor Configuration File
--------------------------------------
A formfactor configuration file provides information about the target
hardware for which the image is being built and information that the
build system cannot obtain from other sources such as the kernel. Some
examples of information contained in a formfactor configuration file
include framebuffer orientation, whether or not the system has a
keyboard, the positioning of the keyboard in relation to the screen, and
the screen resolution.
The build system uses reasonable defaults in most cases. However, if
customization is necessary, you need to create a ``machconfig`` file in
the ``meta/recipes-bsp/formfactor/files`` directory. This directory
contains directories for specific machines such as ``qemuarm`` and
``qemux86``. For information about the settings available and the
defaults, see the ``meta/recipes-bsp/formfactor/files/config`` file
found in the same area.
Following is an example for "qemuarm" machine::
HAVE_TOUCHSCREEN=1
HAVE_KEYBOARD=1
DISPLAY_CAN_ROTATE=0
DISPLAY_ORIENTATION=0
#DISPLAY_WIDTH_PIXELS=640
#DISPLAY_HEIGHT_PIXELS=480
#DISPLAY_BPP=16
DISPLAY_DPI=150
DISPLAY_SUBPIXEL_ORDER=vrgb
Upgrading Recipes
=================
Over time, upstream developers publish new versions for software built
by layer recipes. It is recommended to keep recipes up-to-date with
upstream version releases.
While there are several methods to upgrade a recipe, you might
consider checking on the upgrade status of a recipe first. You can do so
using the ``devtool check-upgrade-status`` command. See the
":ref:`devtool-checking-on-the-upgrade-status-of-a-recipe`"
section in the Yocto Project Reference Manual for more information.
The remainder of this section describes three ways you can upgrade a
recipe. You can use the Automated Upgrade Helper (AUH) to set up
automatic version upgrades. Alternatively, you can use
``devtool upgrade`` to set up semi-automatic version upgrades. Finally,
you can manually upgrade a recipe by editing the recipe itself.
Using the Auto Upgrade Helper (AUH)
-----------------------------------
The AUH utility works in conjunction with the OpenEmbedded build system
in order to automatically generate upgrades for recipes based on new
versions being published upstream. Use AUH when you want to create a
service that performs the upgrades automatically and optionally sends
you an email with the results.
AUH allows you to update several recipes with a single use. You can also
optionally perform build and integration tests using images with the
results saved to your hard drive and emails of results optionally sent
to recipe maintainers. Finally, AUH creates Git commits with appropriate
commit messages in the layer's tree for the changes made to recipes.
.. note::
In some conditions, you should not use AUH to upgrade recipes
and should instead use either ``devtool upgrade`` or upgrade your
recipes manually:
- When AUH cannot complete the upgrade sequence. This situation
usually results because custom patches carried by the recipe
cannot be automatically rebased to the new version. In this case,
``devtool upgrade`` allows you to manually resolve conflicts.
- When for any reason you want fuller control over the upgrade
process. For example, when you want special arrangements for
testing.
The following steps describe how to set up the AUH utility:
1. *Be Sure the Development Host is Set Up:* You need to be sure that
your development host is set up to use the Yocto Project. For
information on how to set up your host, see the
":ref:`dev-manual/start:Preparing the Build Host`" section.
2. *Make Sure Git is Configured:* The AUH utility requires Git to be
configured because AUH uses Git to save upgrades. Thus, you must have
Git user and email configured. The following command shows your
configurations::
$ git config --list
If you do not have the user and
email configured, you can use the following commands to do so::
$ git config --global user.name some_name
$ git config --global user.email username@domain.com
3. *Clone the AUH Repository:* To use AUH, you must clone the repository
onto your development host. The following command uses Git to create
a local copy of the repository on your system::
$ git clone git://git.yoctoproject.org/auto-upgrade-helper
Cloning into 'auto-upgrade-helper'... remote: Counting objects: 768, done.
remote: Compressing objects: 100% (300/300), done.
remote: Total 768 (delta 499), reused 703 (delta 434)
Receiving objects: 100% (768/768), 191.47 KiB | 98.00 KiB/s, done.
Resolving deltas: 100% (499/499), done.
Checking connectivity... done.
AUH is not part of the :term:`OpenEmbedded-Core (OE-Core)` or
:term:`Poky` repositories.
4. *Create a Dedicated Build Directory:* Run the
:ref:`structure-core-script`
script to create a fresh build directory that you use exclusively for
running the AUH utility::
$ cd poky
$ source oe-init-build-env your_AUH_build_directory
Re-using an existing build directory and its configurations is not
recommended as existing settings could cause AUH to fail or behave
undesirably.
5. *Make Configurations in Your Local Configuration File:* Several
settings are needed in the ``local.conf`` file in the build
directory you just created for AUH. Make these following
configurations:
- If you want to enable :ref:`Build
History <dev-manual/common-tasks:maintaining build output quality>`,
which is optional, you need the following lines in the
``conf/local.conf`` file::
INHERIT =+ "buildhistory"
BUILDHISTORY_COMMIT = "1"
With this configuration and a successful
upgrade, a build history "diff" file appears in the
``upgrade-helper/work/recipe/buildhistory-diff.txt`` file found in
your build directory.
- If you want to enable testing through the
:ref:`testimage <ref-classes-testimage*>`
class, which is optional, you need to have the following set in
your ``conf/local.conf`` file::
INHERIT += "testimage"
.. note::
If your distro does not enable by default ptest, which Poky
does, you need the following in your ``local.conf`` file::
DISTRO_FEATURES:append = " ptest"
6. *Optionally Start a vncserver:* If you are running in a server
without an X11 session, you need to start a vncserver::
$ vncserver :1
$ export DISPLAY=:1
7. *Create and Edit an AUH Configuration File:* You need to have the
``upgrade-helper/upgrade-helper.conf`` configuration file in your
build directory. You can find a sample configuration file in the
:yocto_git:`AUH source repository </auto-upgrade-helper/tree/>`.
Read through the sample file and make configurations as needed. For
example, if you enabled build history in your ``local.conf`` as
described earlier, you must enable it in ``upgrade-helper.conf``.
Also, if you are using the default ``maintainers.inc`` file supplied
with Poky and located in ``meta-yocto`` and you do not set a
"maintainers_whitelist" or "global_maintainer_override" in the
``upgrade-helper.conf`` configuration, and you specify "-e all" on
the AUH command-line, the utility automatically sends out emails to
all the default maintainers. Please avoid this.
This next set of examples describes how to use the AUH:
- *Upgrading a Specific Recipe:* To upgrade a specific recipe, use the
following form::
$ upgrade-helper.py recipe_name
For example, this command upgrades the ``xmodmap`` recipe::
$ upgrade-helper.py xmodmap
- *Upgrading a Specific Recipe to a Particular Version:* To upgrade a
specific recipe to a particular version, use the following form::
$ upgrade-helper.py recipe_name -t version
For example, this command upgrades the ``xmodmap`` recipe to version 1.2.3::
$ upgrade-helper.py xmodmap -t 1.2.3
- *Upgrading all Recipes to the Latest Versions and Suppressing Email
Notifications:* To upgrade all recipes to their most recent versions
and suppress the email notifications, use the following command::
$ upgrade-helper.py all
- *Upgrading all Recipes to the Latest Versions and Send Email
Notifications:* To upgrade all recipes to their most recent versions
and send email messages to maintainers for each attempted recipe as
well as a status email, use the following command::
$ upgrade-helper.py -e all
Once you have run the AUH utility, you can find the results in the AUH
build directory::
${BUILDDIR}/upgrade-helper/timestamp
The AUH utility
also creates recipe update commits from successful upgrade attempts in
the layer tree.
You can easily set up to run the AUH utility on a regular basis by using
a cron job. See the
:yocto_git:`weeklyjob.sh </auto-upgrade-helper/tree/weeklyjob.sh>`
file distributed with the utility for an example.
Using ``devtool upgrade``
-------------------------
As mentioned earlier, an alternative method for upgrading recipes to
newer versions is to use
:doc:`devtool upgrade </ref-manual/devtool-reference>`.
You can read about ``devtool upgrade`` in general in the
":ref:`sdk-manual/extensible:use \`\`devtool upgrade\`\` to create a version of the recipe that supports a newer version of the software`"
section in the Yocto Project Application Development and the Extensible
Software Development Kit (eSDK) Manual.
To see all the command-line options available with ``devtool upgrade``,
use the following help command::
$ devtool upgrade -h
If you want to find out what version a recipe is currently at upstream
without any attempt to upgrade your local version of the recipe, you can
use the following command::
$ devtool latest-version recipe_name
As mentioned in the previous section describing AUH, ``devtool upgrade``
works in a less-automated manner than AUH. Specifically,
``devtool upgrade`` only works on a single recipe that you name on the
command line, cannot perform build and integration testing using images,
and does not automatically generate commits for changes in the source
tree. Despite all these "limitations", ``devtool upgrade`` updates the
recipe file to the new upstream version and attempts to rebase custom
patches contained by the recipe as needed.
.. note::
AUH uses much of ``devtool upgrade`` behind the scenes making AUH somewhat
of a "wrapper" application for ``devtool upgrade``.
A typical scenario involves having used Git to clone an upstream
repository that you use during build operations. Because you have built the
recipe in the past, the layer is likely added to your
configuration already. If for some reason, the layer is not added, you
could add it easily using the
":ref:`bitbake-layers <bsp-guide/bsp:creating a new bsp layer using the \`\`bitbake-layers\`\` script>`"
script. For example, suppose you use the ``nano.bb`` recipe from the
``meta-oe`` layer in the ``meta-openembedded`` repository. For this
example, assume that the layer has been cloned into following area::
/home/scottrif/meta-openembedded
The following command from your
:term:`Build Directory` adds the layer to
your build configuration (i.e. ``${BUILDDIR}/conf/bblayers.conf``)::
$ bitbake-layers add-layer /home/scottrif/meta-openembedded/meta-oe
NOTE: Starting bitbake server...
Parsing recipes: 100% |##########################################| Time: 0:00:55
Parsing of 1431 .bb files complete (0 cached, 1431 parsed). 2040 targets, 56 skipped, 0 masked, 0 errors.
Removing 12 recipes from the x86_64 sysroot: 100% |##############| Time: 0:00:00
Removing 1 recipes from the x86_64_i586 sysroot: 100% |##########| Time: 0:00:00
Removing 5 recipes from the i586 sysroot: 100% |#################| Time: 0:00:00
Removing 5 recipes from the qemux86 sysroot: 100% |##############| Time: 0:00:00
For this example, assume that the ``nano.bb`` recipe that
is upstream has a 2.9.3 version number. However, the version in the
local repository is 2.7.4. The following command from your build
directory automatically upgrades the recipe for you:
.. note::
Using the ``-V`` option is not necessary. Omitting the version number causes
``devtool upgrade`` to upgrade the recipe to the most recent version.
::
$ devtool upgrade nano -V 2.9.3
NOTE: Starting bitbake server...
NOTE: Creating workspace layer in /home/scottrif/poky/build/workspace
Parsing recipes: 100% |##########################################| Time: 0:00:46
Parsing of 1431 .bb files complete (0 cached, 1431 parsed). 2040 targets, 56 skipped, 0 masked, 0 errors.
NOTE: Extracting current version source...
NOTE: Resolving any missing task queue dependencies
.
.
.
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 74 tasks of which 72 didn't need to be rerun and all succeeded.
Adding changed files: 100% |#####################################| Time: 0:00:00
NOTE: Upgraded source extracted to /home/scottrif/poky/build/workspace/sources/nano
NOTE: New recipe is /home/scottrif/poky/build/workspace/recipes/nano/nano_2.9.3.bb
Continuing with this example, you can use ``devtool build`` to build the
newly upgraded recipe::
$ devtool build nano
NOTE: Starting bitbake server...
Loading cache: 100% |################################################################################################| Time: 0:00:01
Loaded 2040 entries from dependency cache.
Parsing recipes: 100% |##############################################################################################| Time: 0:00:00
Parsing of 1432 .bb files complete (1431 cached, 1 parsed). 2041 targets, 56 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
.
.
.
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: nano: compiling from external source tree /home/scottrif/poky/build/workspace/sources/nano
NOTE: Tasks Summary: Attempted 520 tasks of which 304 didn't need to be rerun and all succeeded.
Within the ``devtool upgrade`` workflow, you can
deploy and test your rebuilt software. For this example,
however, running ``devtool finish`` cleans up the workspace once the
source in your workspace is clean. This usually means using Git to stage
and submit commits for the changes generated by the upgrade process.
Once the tree is clean, you can clean things up in this example with the
following command from the ``${BUILDDIR}/workspace/sources/nano``
directory::
$ devtool finish nano meta-oe
NOTE: Starting bitbake server...
Loading cache: 100% |################################################################################################| Time: 0:00:00
Loaded 2040 entries from dependency cache.
Parsing recipes: 100% |##############################################################################################| Time: 0:00:01
Parsing of 1432 .bb files complete (1431 cached, 1 parsed). 2041 targets, 56 skipped, 0 masked, 0 errors.
NOTE: Adding new patch 0001-nano.bb-Stuff-I-changed-when-upgrading-nano.bb.patch
NOTE: Updating recipe nano_2.9.3.bb
NOTE: Removing file /home/scottrif/meta-openembedded/meta-oe/recipes-support/nano/nano_2.7.4.bb
NOTE: Moving recipe file to /home/scottrif/meta-openembedded/meta-oe/recipes-support/nano
NOTE: Leaving source tree /home/scottrif/poky/build/workspace/sources/nano as-is; if you no longer need it then please delete it manually
Using the ``devtool finish`` command cleans up the workspace and creates a patch
file based on your commits. The tool puts all patch files back into the
source directory in a sub-directory named ``nano`` in this case.
Manually Upgrading a Recipe
---------------------------
If for some reason you choose not to upgrade recipes using
:ref:`dev-manual/common-tasks:Using the Auto Upgrade Helper (AUH)` or
by :ref:`dev-manual/common-tasks:Using \`\`devtool upgrade\`\``,
you can manually edit the recipe files to upgrade the versions.
.. note::
Manually updating multiple recipes scales poorly and involves many
steps. The recommendation to upgrade recipe versions is through AUH
or ``devtool upgrade``, both of which automate some steps and provide
guidance for others needed for the manual process.
To manually upgrade recipe versions, follow these general steps:
1. *Change the Version:* Rename the recipe such that the version (i.e.
the :term:`PV` part of the recipe name)
changes appropriately. If the version is not part of the recipe name,
change the value as it is set for :term:`PV` within the recipe itself.
2. *Update* :term:`SRCREV` *if Needed*: If the source code your recipe builds
is fetched from Git or some other version control system, update
:term:`SRCREV` to point to the
commit hash that matches the new version.
3. *Build the Software:* Try to build the recipe using BitBake. Typical
build failures include the following:
- License statements were updated for the new version. For this
case, you need to review any changes to the license and update the
values of :term:`LICENSE` and
:term:`LIC_FILES_CHKSUM`
as needed.
.. note::
License changes are often inconsequential. For example, the
license text's copyright year might have changed.
- Custom patches carried by the older version of the recipe might
fail to apply to the new version. For these cases, you need to
review the failures. Patches might not be necessary for the new
version of the software if the upgraded version has fixed those
issues. If a patch is necessary and failing, you need to rebase it
into the new version.
4. *Optionally Attempt to Build for Several Architectures:* Once you
successfully build the new software for a given architecture, you
could test the build for other architectures by changing the
:term:`MACHINE` variable and
rebuilding the software. This optional step is especially important
if the recipe is to be released publicly.
5. *Check the Upstream Change Log or Release Notes:* Checking both these
reveals if there are new features that could break
backwards-compatibility. If so, you need to take steps to mitigate or
eliminate that situation.
6. *Optionally Create a Bootable Image and Test:* If you want, you can
test the new software by booting it onto actual hardware.
7. *Create a Commit with the Change in the Layer Repository:* After all
builds work and any testing is successful, you can create commits for
any changes in the layer holding your upgraded recipe.
Finding Temporary Source Code
=============================
You might find it helpful during development to modify the temporary
source code used by recipes to build packages. For example, suppose you
are developing a patch and you need to experiment a bit to figure out
your solution. After you have initially built the package, you can
iteratively tweak the source code, which is located in the
:term:`Build Directory`, and then you can
force a re-compile and quickly test your altered code. Once you settle
on a solution, you can then preserve your changes in the form of
patches.
During a build, the unpacked temporary source code used by recipes to
build packages is available in the Build Directory as defined by the
:term:`S` variable. Below is the default
value for the :term:`S` variable as defined in the
``meta/conf/bitbake.conf`` configuration file in the
:term:`Source Directory`::
S = "${WORKDIR}/${BP}"
You should be aware that many recipes override the
:term:`S` variable. For example, recipes that fetch their source from Git
usually set :term:`S` to ``${WORKDIR}/git``.
.. note::
The :term:`BP` represents the base recipe name, which consists of the name
and version::
BP = "${BPN}-${PV}"
The path to the work directory for the recipe
(:term:`WORKDIR`) is defined as
follows::
${TMPDIR}/work/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}
The actual directory depends on several things:
- :term:`TMPDIR`: The top-level build
output directory.
- :term:`MULTIMACH_TARGET_SYS`:
The target system identifier.
- :term:`PN`: The recipe name.
- :term:`EXTENDPE`: The epoch - (if
:term:`PE` is not specified, which is
usually the case for most recipes, then :term:`EXTENDPE` is blank).
- :term:`PV`: The recipe version.
- :term:`PR`: The recipe revision.
As an example, assume a Source Directory top-level folder named
``poky``, a default Build Directory at ``poky/build``, and a
``qemux86-poky-linux`` machine target system. Furthermore, suppose your
recipe is named ``foo_1.3.0.bb``. In this case, the work directory the
build system uses to build the package would be as follows::
poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0
Using Quilt in Your Workflow
============================
`Quilt <https://savannah.nongnu.org/projects/quilt>`__ is a powerful tool
that allows you to capture source code changes without having a clean
source tree. This section outlines the typical workflow you can use to
modify source code, test changes, and then preserve the changes in the
form of a patch all using Quilt.
.. note::
With regard to preserving changes to source files, if you clean a
recipe or have ``rm_work`` enabled, the
:ref:`devtool workflow <sdk-manual/extensible:using \`\`devtool\`\` in your sdk workflow>`
as described in the Yocto Project Application Development and the
Extensible Software Development Kit (eSDK) manual is a safer
development flow than the flow that uses Quilt.
Follow these general steps:
1. *Find the Source Code:* Temporary source code used by the
OpenEmbedded build system is kept in the
:term:`Build Directory`. See the
":ref:`dev-manual/common-tasks:finding temporary source code`" section to
learn how to locate the directory that has the temporary source code for a
particular package.
2. *Change Your Working Directory:* You need to be in the directory that
has the temporary source code. That directory is defined by the
:term:`S` variable.
3. *Create a New Patch:* Before modifying source code, you need to
create a new patch. To create a new patch file, use ``quilt new`` as
below::
$ quilt new my_changes.patch
4. *Notify Quilt and Add Files:* After creating the patch, you need to
notify Quilt about the files you plan to edit. You notify Quilt by
adding the files to the patch you just created::
$ quilt add file1.c file2.c file3.c
5. *Edit the Files:* Make your changes in the source code to the files
you added to the patch.
6. *Test Your Changes:* Once you have modified the source code, the
easiest way to test your changes is by calling the ``do_compile``
task as shown in the following example::
$ bitbake -c compile -f package
The ``-f`` or ``--force`` option forces the specified task to
execute. If you find problems with your code, you can just keep
editing and re-testing iteratively until things work as expected.
.. note::
All the modifications you make to the temporary source code disappear
once you run the ``do_clean`` or ``do_cleanall`` tasks using BitBake
(i.e. ``bitbake -c clean package`` and ``bitbake -c cleanall package``).
Modifications will also disappear if you use the ``rm_work`` feature as
described in the
":ref:`dev-manual/common-tasks:conserving disk space during builds`"
section.
7. *Generate the Patch:* Once your changes work as expected, you need to
use Quilt to generate the final patch that contains all your
modifications.
::
$ quilt refresh
At this point, the
``my_changes.patch`` file has all your edits made to the ``file1.c``,
``file2.c``, and ``file3.c`` files.
You can find the resulting patch file in the ``patches/``
subdirectory of the source (:term:`S`) directory.
8. *Copy the Patch File:* For simplicity, copy the patch file into a
directory named ``files``, which you can create in the same directory
that holds the recipe (``.bb``) file or the append (``.bbappend``)
file. Placing the patch here guarantees that the OpenEmbedded build
system will find the patch. Next, add the patch into the :term:`SRC_URI`
of the recipe. Here is an example::
SRC_URI += "file://my_changes.patch"
Using a Development Shell
=========================
When debugging certain commands or even when just editing packages,
``devshell`` can be a useful tool. When you invoke ``devshell``, all
tasks up to and including
:ref:`ref-tasks-patch` are run for the
specified target. Then, a new terminal is opened and you are placed in
``${``\ :term:`S`\ ``}``, the source
directory. In the new terminal, all the OpenEmbedded build-related
environment variables are still defined so you can use commands such as
``configure`` and ``make``. The commands execute just as if the
OpenEmbedded build system were executing them. Consequently, working
this way can be helpful when debugging a build or preparing software to
be used with the OpenEmbedded build system.
Following is an example that uses ``devshell`` on a target named
``matchbox-desktop``::
$ bitbake matchbox-desktop -c devshell
This command spawns a terminal with a shell prompt within the
OpenEmbedded build environment. The
:term:`OE_TERMINAL` variable
controls what type of shell is opened.
For spawned terminals, the following occurs:
- The ``PATH`` variable includes the cross-toolchain.
- The ``pkgconfig`` variables find the correct ``.pc`` files.
- The ``configure`` command finds the Yocto Project site files as well
as any other necessary files.
Within this environment, you can run configure or compile commands as if
they were being run by the OpenEmbedded build system itself. As noted
earlier, the working directory also automatically changes to the Source
Directory (:term:`S`).
To manually run a specific task using ``devshell``, run the
corresponding ``run.*`` script in the
``${``\ :term:`WORKDIR`\ ``}/temp``
directory (e.g., ``run.do_configure.``\ `pid`). If a task's script does
not exist, which would be the case if the task was skipped by way of the
sstate cache, you can create the task by first running it outside of the
``devshell``::
$ bitbake -c task
.. note::
- Execution of a task's ``run.*`` script and BitBake's execution of
a task are identical. In other words, running the script re-runs
the task just as it would be run using the ``bitbake -c`` command.
- Any ``run.*`` file that does not have a ``.pid`` extension is a
symbolic link (symlink) to the most recent version of that file.
Remember, that the ``devshell`` is a mechanism that allows you to get
into the BitBake task execution environment. And as such, all commands
must be called just as BitBake would call them. That means you need to
provide the appropriate options for cross-compilation and so forth as
applicable.
When you are finished using ``devshell``, exit the shell or close the
terminal window.
.. note::
- It is worth remembering that when using ``devshell`` you need to
use the full compiler name such as ``arm-poky-linux-gnueabi-gcc``
instead of just using ``gcc``. The same applies to other
applications such as ``binutils``, ``libtool`` and so forth.
BitBake sets up environment variables such as :term:`CC` to assist
applications, such as ``make`` to find the correct tools.
- It is also worth noting that ``devshell`` still works over X11
forwarding and similar situations.
Using a Development Python Shell
================================
Similar to working within a development shell as described in the
previous section, you can also spawn and work within an interactive
Python development shell. When debugging certain commands or even when
just editing packages, ``devpyshell`` can be a useful tool. When you
invoke ``devpyshell``, all tasks up to and including
:ref:`ref-tasks-patch` are run for the
specified target. Then a new terminal is opened. Additionally, key
Python objects and code are available in the same way they are to
BitBake tasks, in particular, the data store 'd'. So, commands such as
the following are useful when exploring the data store and running
functions::
pydevshell> d.getVar("STAGING_DIR")
'/media/build1/poky/build/tmp/sysroots'
pydevshell> d.getVar("STAGING_DIR")
'${TMPDIR}/sysroots'
pydevshell> d.setVar("FOO", "bar")
pydevshell> d.getVar("FOO")
'bar'
pydevshell> d.delVar("FOO")
pydevshell> d.getVar("FOO")
pydevshell> bb.build.exec_func("do_unpack", d)
pydevshell>
The commands execute just as if the OpenEmbedded build
system were executing them. Consequently, working this way can be
helpful when debugging a build or preparing software to be used with the
OpenEmbedded build system.
Following is an example that uses ``devpyshell`` on a target named
``matchbox-desktop``::
$ bitbake matchbox-desktop -c devpyshell
This command spawns a terminal and places you in an interactive Python
interpreter within the OpenEmbedded build environment. The
:term:`OE_TERMINAL` variable
controls what type of shell is opened.
When you are finished using ``devpyshell``, you can exit the shell
either by using Ctrl+d or closing the terminal window.
Building
========
This section describes various build procedures. For example, the steps
needed for a simple build, a target that uses multiple configurations,
building an image for more than one machine, and so forth.
Building a Simple Image
-----------------------
In the development environment, you need to build an image whenever you
change hardware support, add or change system libraries, or add or
change services that have dependencies. There are several methods that allow
you to build an image within the Yocto Project. This section presents
the basic steps you need to build a simple image using BitBake from a
build host running Linux.
.. note::
- For information on how to build an image using
:term:`Toaster`, see the
:doc:`/toaster-manual/index`.
- For information on how to use ``devtool`` to build images, see the
":ref:`sdk-manual/extensible:using \`\`devtool\`\` in your sdk workflow`"
section in the Yocto Project Application Development and the
Extensible Software Development Kit (eSDK) manual.
- For a quick example on how to build an image using the
OpenEmbedded build system, see the
:doc:`/brief-yoctoprojectqs/index` document.
The build process creates an entire Linux distribution from source and
places it in your :term:`Build Directory` under
``tmp/deploy/images``. For detailed information on the build process
using BitBake, see the ":ref:`overview-manual/concepts:images`" section in the
Yocto Project Overview and Concepts Manual.
The following figure and list overviews the build process:
.. image:: figures/bitbake-build-flow.png
:align: center
1. *Set up Your Host Development System to Support Development Using the
Yocto Project*: See the ":doc:`start`" section for options on how to get a
build host ready to use the Yocto Project.
2. *Initialize the Build Environment:* Initialize the build environment
by sourcing the build environment script (i.e.
:ref:`structure-core-script`)::
$ source oe-init-build-env [build_dir]
When you use the initialization script, the OpenEmbedded build system
uses ``build`` as the default :term:`Build Directory` in your current work
directory. You can use a `build_dir` argument with the script to
specify a different build directory.
.. note::
A common practice is to use a different Build Directory for
different targets. For example, ``~/build/x86`` for a ``qemux86``
target, and ``~/build/arm`` for a ``qemuarm`` target.
3. *Make Sure Your* ``local.conf`` *File is Correct*: Ensure the
``conf/local.conf`` configuration file, which is found in the Build
Directory, is set up how you want it. This file defines many aspects
of the build environment including the target machine architecture
through the :term:`MACHINE` variable, the packaging format used during
the build
(:term:`PACKAGE_CLASSES`),
and a centralized tarball download directory through the
:term:`DL_DIR` variable.
4. *Build the Image:* Build the image using the ``bitbake`` command::
$ bitbake target
.. note::
For information on BitBake, see the :doc:`bitbake:index`.
The target is the name of the recipe you want to build. Common
targets are the images in ``meta/recipes-core/images``,
``meta/recipes-sato/images``, and so forth all found in the
:term:`Source Directory`. Or, the target
can be the name of a recipe for a specific piece of software such as
BusyBox. For more details about the images the OpenEmbedded build
system supports, see the
":ref:`ref-manual/images:Images`" chapter in the Yocto
Project Reference Manual.
As an example, the following command builds the
``core-image-minimal`` image::
$ bitbake core-image-minimal
Once an
image has been built, it often needs to be installed. The images and
kernels built by the OpenEmbedded build system are placed in the
Build Directory in ``tmp/deploy/images``. For information on how to
run pre-built images such as ``qemux86`` and ``qemuarm``, see the
:doc:`/sdk-manual/index` manual. For
information about how to install these images, see the documentation
for your particular board or machine.
Building Images for Multiple Targets Using Multiple Configurations
------------------------------------------------------------------
You can use a single ``bitbake`` command to build multiple images or