4a226369b7
Accidentally put in a couple different things in this one commit. Oh well. 1. New wording for how the user needs to figure out some checksums for a recipe. 2. Fixed up some note placement in the wic reference section. (From yocto-docs rev: 6c13f49c265c99ddd6dcd4ec3c3c8e66b78824e0) Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
9547 lines
489 KiB
XML
9547 lines
489 KiB
XML
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
|
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
|
|
|
<chapter id='extendpoky'>
|
|
|
|
<title>Common Tasks</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<section id="understanding-and-creating-layers">
|
|
<title>Understanding and Creating Layers</title>
|
|
|
|
<para>
|
|
The OpenEmbedded build system supports organizing
|
|
<link linkend='metadata'>Metadata</link> into multiple layers.
|
|
Layers allow you to isolate different types of customizations from
|
|
each other.
|
|
You might find it tempting to keep everything in one layer when
|
|
working on a single project.
|
|
However, the more modular your Metadata, the easier
|
|
it is to cope with future changes.
|
|
</para>
|
|
|
|
<para>
|
|
To illustrate how layers are used to keep things modular, consider
|
|
machine customizations.
|
|
These types of customizations typically reside in a special layer,
|
|
rather than a general layer, called a Board Support Package (BSP)
|
|
Layer.
|
|
Furthermore, the machine customizations should be isolated from
|
|
recipes and Metadata that support a new GUI environment,
|
|
for example.
|
|
This situation gives you a couple of layers: one for the machine
|
|
configurations, and one for the GUI environment.
|
|
It is important to understand, however, that the BSP layer can
|
|
still make machine-specific additions to recipes within the GUI
|
|
environment layer without polluting the GUI layer itself
|
|
with those machine-specific changes.
|
|
You can accomplish this through a recipe that is a BitBake append
|
|
(<filename>.bbappend</filename>) file, which is described later
|
|
in this section.
|
|
</para>
|
|
|
|
<para>
|
|
</para>
|
|
|
|
<section id='yocto-project-layers'>
|
|
<title>Layers</title>
|
|
|
|
<para>
|
|
The <link linkend='source-directory'>Source Directory</link>
|
|
contains both general layers and BSP
|
|
layers right out of the box.
|
|
You can easily identify layers that ship with a
|
|
Yocto Project release in the Source Directory by their
|
|
folder names.
|
|
Folders that represent layers typically have names that begin with
|
|
the string <filename>meta-</filename>.
|
|
<note>
|
|
It is not a requirement that a layer name begin with the
|
|
prefix <filename>meta-</filename>, but it is a commonly
|
|
accepted standard in the Yocto Project community.
|
|
</note>
|
|
For example, when you set up the Source Directory structure,
|
|
you will see several layers:
|
|
<filename>meta</filename>,
|
|
<filename>meta-skeleton</filename>,
|
|
<filename>meta-yocto</filename>, and
|
|
<filename>meta-yocto-bsp</filename>.
|
|
Each of these folders represents a distinct layer.
|
|
</para>
|
|
|
|
<para>
|
|
As another example, if you set up a local copy of the
|
|
<filename>meta-intel</filename> Git repository
|
|
and then explore the folder of that general layer,
|
|
you will discover many Intel-specific BSP layers inside.
|
|
For more information on BSP layers, see the
|
|
"<ulink url='&YOCTO_DOCS_BSP_URL;#bsp-layers'>BSP Layers</ulink>"
|
|
section in the Yocto Project Board Support Package (BSP)
|
|
Developer's Guide.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-your-own-layer'>
|
|
<title>Creating Your Own Layer</title>
|
|
|
|
<para>
|
|
It is very easy to create your own layers to use with the
|
|
OpenEmbedded build system.
|
|
The Yocto Project ships with scripts that speed up creating
|
|
general layers and BSP layers.
|
|
This section describes the steps you perform by hand to create
|
|
a layer so that you can better understand them.
|
|
For information about the layer-creation scripts, see the
|
|
"<ulink url='&YOCTO_DOCS_BSP_URL;#creating-a-new-bsp-layer-using-the-yocto-bsp-script'>Creating a New BSP Layer Using the yocto-bsp Script</ulink>"
|
|
section in the Yocto Project Board Support Package (BSP)
|
|
Developer's Guide and the
|
|
"<link linkend='creating-a-general-layer-using-the-yocto-layer-script'>Creating a General Layer Using the yocto-layer Script</link>"
|
|
section further down in this manual.
|
|
</para>
|
|
|
|
<para>
|
|
Follow these general steps to create your layer:
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Check Existing Layers:</emphasis>
|
|
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
|
|
<ulink url='http://layers.openembedded.org/layerindex/layers/'><filename>OpenEmbedded Metadata Index</filename></ulink>
|
|
for a list of layers from the OpenEmbedded community
|
|
that can be used in the Yocto Project.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Create a Directory:</emphasis>
|
|
Create the directory for your layer.
|
|
While not strictly required, prepend the name of the
|
|
folder with the string <filename>meta-</filename>.
|
|
For example:
|
|
<literallayout class='monospaced'>
|
|
meta-mylayer
|
|
meta-GUI_xyz
|
|
meta-mymachine
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Create a Layer Configuration
|
|
File:</emphasis>
|
|
Inside your new layer folder, you need to create a
|
|
<filename>conf/layer.conf</filename> file.
|
|
It is easiest to take an existing layer configuration
|
|
file and copy that to your layer's
|
|
<filename>conf</filename> directory and then modify the
|
|
file as needed.</para>
|
|
<para>The
|
|
<filename>meta-yocto-bsp/conf/layer.conf</filename> file
|
|
demonstrates the required syntax:
|
|
<literallayout class='monospaced'>
|
|
# 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 = "2"
|
|
</literallayout></para>
|
|
<para>Here is an explanation of the example:
|
|
<itemizedlist>
|
|
<listitem><para>The configuration and
|
|
classes directory is appended to
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBPATH'><filename>BBPATH</filename></ulink>.
|
|
<note>
|
|
All non-distro layers, which include all BSP
|
|
layers, are expected to append the layer
|
|
directory to the
|
|
<filename>BBPATH</filename>.
|
|
On the other hand, distro layers, such as
|
|
<filename>meta-yocto</filename>, can choose
|
|
to enforce their own precedence over
|
|
<filename>BBPATH</filename>.
|
|
For an example of that syntax, see the
|
|
<filename>layer.conf</filename> file for
|
|
the <filename>meta-yocto</filename> layer.
|
|
</note></para></listitem>
|
|
<listitem><para>The recipes for the layers are
|
|
appended to
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BBFILES'>BBFILES</ulink></filename>.
|
|
</para></listitem>
|
|
<listitem><para>The
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BBFILE_COLLECTIONS'>BBFILE_COLLECTIONS</ulink></filename>
|
|
variable is then appended with the layer name.
|
|
</para></listitem>
|
|
<listitem><para>The
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BBFILE_PATTERN'>BBFILE_PATTERN</ulink></filename>
|
|
variable is set to a regular expression and is
|
|
used to match files from
|
|
<filename>BBFILES</filename> into a particular
|
|
layer.
|
|
In this case,
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-LAYERDIR'>LAYERDIR</ulink></filename>
|
|
is used to make <filename>BBFILE_PATTERN</filename> match within the
|
|
layer's path.</para></listitem>
|
|
<listitem><para>The
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BBFILE_PRIORITY'>BBFILE_PRIORITY</ulink></filename>
|
|
variable then assigns a priority to the layer.
|
|
Applying priorities is useful in situations
|
|
where the same package might appear in multiple
|
|
layers and allows you to choose the layer
|
|
that takes precedence.</para></listitem>
|
|
<listitem><para>The
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-LAYERVERSION'>LAYERVERSION</ulink></filename>
|
|
variable optionally specifies the version of a
|
|
layer as a single number.</para></listitem>
|
|
</itemizedlist></para>
|
|
<para>Note the use of the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-LAYERDIR'>LAYERDIR</ulink></filename>
|
|
variable, which expands to the directory of the current
|
|
layer.</para>
|
|
<para>Through the use of the <filename>BBPATH</filename>
|
|
variable, BitBake locates class files
|
|
(<filename>.bbclass</filename>),
|
|
configuration files, and files that are included
|
|
with <filename>include</filename> and
|
|
<filename>require</filename> statements.
|
|
For these cases, BitBake uses the first file that
|
|
matches the name found in <filename>BBPATH</filename>.
|
|
This is similar to the way the <filename>PATH</filename>
|
|
variable is used for binaries.
|
|
It is recommended, therefore, that you use unique
|
|
class and configuration
|
|
filenames in your custom layer.</para></listitem>
|
|
<listitem><para><emphasis>Add Content:</emphasis> Depending
|
|
on the type of layer, add the content.
|
|
If the layer adds support for a machine, add the machine
|
|
configuration in a <filename>conf/machine/</filename>
|
|
file within the layer.
|
|
If the layer adds distro policy, add the distro
|
|
configuration in a <filename>conf/distro/</filename>
|
|
file within the layer.
|
|
If the layer introduces new recipes, put the recipes
|
|
you need in <filename>recipes-*</filename>
|
|
subdirectories within the layer.
|
|
<note>In order to be compliant with the Yocto Project,
|
|
a layer must contain a
|
|
<ulink url='&YOCTO_DOCS_BSP_URL;#bsp-filelayout-readme'>README file.</ulink>
|
|
</note></para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='best-practices-to-follow-when-creating-layers'>
|
|
<title>Best Practices to Follow When Creating Layers</title>
|
|
|
|
<para>
|
|
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 sections.
|
|
</para>
|
|
|
|
<section id='avoid-overlaying-entire-recipes'>
|
|
<title>Avoid "Overlaying" Entire Recipes</title>
|
|
|
|
<para>
|
|
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 (<filename>.bbappend</filename>)
|
|
to override
|
|
only those parts of the original recipe you need to modify.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='avoid-duplicating-include-files'>
|
|
<title>Avoid Duplicating Include Files</title>
|
|
|
|
<para>
|
|
Avoid duplicating include files.
|
|
Use append files (<filename>.bbappend</filename>)
|
|
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
|
|
<filename>require recipes-core/somepackage/somefile.inc</filename>
|
|
instead of <filename>require somefile.inc</filename>.
|
|
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 need to address that deficiency
|
|
instead of overlaying the include file.
|
|
</para>
|
|
|
|
<para>
|
|
For example, consider how support plug-ins for the Qt 4
|
|
database are configured.
|
|
The Source Directory does not have MySQL or PostgreSQL.
|
|
However, OpenEmbedded's layer <filename>meta-oe</filename>
|
|
does.
|
|
Consequently, <filename>meta-oe</filename> uses
|
|
append files to modify the
|
|
<filename>QT_SQL_DRIVER_FLAGS</filename> variable to
|
|
enable the appropriate plug-ins.
|
|
This variable was added to the <filename>qt4.inc</filename>
|
|
include file in the Source Directory specifically to allow
|
|
the <filename>meta-oe</filename> layer to be able to control
|
|
which plug-ins are built.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='structure-your-layers'>
|
|
<title>Structure Your Layers</title>
|
|
|
|
<para>
|
|
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:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Modifying Variables to Support
|
|
a Different Machine:</emphasis>
|
|
Suppose you have a layer named
|
|
<filename>meta-one</filename> that adds support
|
|
for building machine "one".
|
|
To do so, you use an append file named
|
|
<filename>base-files.bbappend</filename> and
|
|
create a dependency on "foo" by altering the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>
|
|
variable:
|
|
<literallayout class='monospaced'>
|
|
DEPENDS = "foo"
|
|
</literallayout>
|
|
The dependency is created during any build that
|
|
includes the layer
|
|
<filename>meta-one</filename>.
|
|
However, you might not want this dependency
|
|
for all machines.
|
|
For example, suppose you are building for
|
|
machine "two" but your
|
|
<filename>bblayers.conf</filename> file has the
|
|
<filename>meta-one</filename> layer included.
|
|
During the build, the
|
|
<filename>base-files</filename> for machine
|
|
"two" will also have the dependency on
|
|
<filename>foo</filename>.</para>
|
|
<para>To make sure your changes apply only when
|
|
building machine "one", use a machine override
|
|
with the <filename>DEPENDS</filename> statement:
|
|
<literallayout class='monospaced'>
|
|
DEPENDS_one = "foo"
|
|
</literallayout>
|
|
You should follow the same strategy when using
|
|
<filename>_append</filename> and
|
|
<filename>_prepend</filename> operations:
|
|
<literallayout class='monospaced'>
|
|
DEPENDS_append_one = " foo"
|
|
DEPENDS_prepend_one = "foo "
|
|
</literallayout>
|
|
<note>
|
|
Avoiding "+=" and "=+" and using
|
|
machine-specific
|
|
<filename>_append</filename>
|
|
and <filename>_prepend</filename> operations
|
|
is recommended as well.
|
|
</note></para></listitem>
|
|
<listitem><para><emphasis>Place Machine-Specific Files
|
|
in Machine-Specific Locations:</emphasis>
|
|
When you have a base recipe, such as
|
|
<filename>base-files.bb</filename>, that
|
|
contains a
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
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
|
|
<filename>meta-one/recipes-core/base-files/base-files.bbappend</filename>
|
|
could extend
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILESPATH'><filename>FILESPATH</filename></ulink>
|
|
using
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILESEXTRAPATHS'><filename>FILESEXTRAPATHS</filename></ulink>
|
|
as follows:
|
|
<literallayout class='monospaced'>
|
|
FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:"
|
|
</literallayout>
|
|
The build for machine "one" will pick up your
|
|
machine-specific file as long as you have the
|
|
file in
|
|
<filename>meta-one/recipes-core/base-files/base-files/</filename>.
|
|
However, if you are building for a different
|
|
machine and the
|
|
<filename>bblayers.conf</filename> file includes
|
|
the <filename>meta-one</filename> layer and
|
|
the location of your machine-specific file is
|
|
the first location where that file is found
|
|
according to <filename>FILESPATH</filename>,
|
|
builds for all machines will also use that
|
|
machine-specific file.</para>
|
|
<para>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
|
|
<filename>meta-one/recipes-core/base-files/base-files/</filename>
|
|
as shown above, put it in
|
|
<filename>meta-one/recipes-core/base-files/base-files/one/</filename>.
|
|
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.</para>
|
|
<para>In summary, you need to place all files
|
|
referenced from <filename>SRC_URI</filename>
|
|
in a machine-specific subdirectory within the
|
|
layer in order to restrict those files to
|
|
machine-specific builds.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='other-recommendations'>
|
|
<title>Other Recommendations</title>
|
|
|
|
<para>
|
|
We also recommend the following:
|
|
<itemizedlist>
|
|
<listitem><para>Store custom layers in a Git repository
|
|
that uses the
|
|
<filename>meta-<layer_name></filename> format.
|
|
</para></listitem>
|
|
<listitem><para>Clone the repository alongside other
|
|
<filename>meta</filename> directories in the
|
|
<link linkend='source-directory'>Source Directory</link>.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
Following these recommendations keeps your Source Directory and
|
|
its configuration entirely inside the Yocto Project's core
|
|
base.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='enabling-your-layer'>
|
|
<title>Enabling Your Layer</title>
|
|
|
|
<para>
|
|
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
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BBLAYERS'>BBLAYERS</ulink></filename>
|
|
variable in your <filename>conf/bblayers.conf</filename> file,
|
|
which is found in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
The following example shows how to enable a layer named
|
|
<filename>meta-mylayer</filename>:
|
|
<literallayout class='monospaced'>
|
|
LCONF_VERSION = "6"
|
|
|
|
BBPATH = "${TOPDIR}"
|
|
BBFILES ?= ""
|
|
|
|
BBLAYERS ?= " \
|
|
$HOME/poky/meta \
|
|
$HOME/poky/meta-yocto \
|
|
$HOME/poky/meta-yocto-bsp \
|
|
$HOME/poky/meta-mylayer \
|
|
"
|
|
|
|
BBLAYERS_NON_REMOVABLE ?= " \
|
|
$HOME/poky/meta \
|
|
$HOME/poky/meta-yocto \
|
|
"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
BitBake parses each <filename>conf/layer.conf</filename> file
|
|
as specified in the <filename>BBLAYERS</filename> variable
|
|
within the <filename>conf/bblayers.conf</filename> file.
|
|
During the processing of each
|
|
<filename>conf/layer.conf</filename> file, BitBake adds the
|
|
recipes, classes and configurations contained within the
|
|
particular layer to the source directory.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='using-bbappend-files'>
|
|
<title>Using .bbappend Files</title>
|
|
|
|
<para>
|
|
Recipes used to append Metadata to other recipes are called
|
|
BitBake append files.
|
|
BitBake append files use the <filename>.bbappend</filename> file
|
|
type suffix, while the corresponding recipes to which Metadata
|
|
is being appended use the <filename>.bb</filename> file type
|
|
suffix.
|
|
</para>
|
|
|
|
<para>
|
|
A <filename>.bbappend</filename> file allows your layer to make
|
|
additions or changes to the content of another layer's recipe
|
|
without having to copy the other recipe into your layer.
|
|
Your <filename>.bbappend</filename> file resides in your layer,
|
|
while the main <filename>.bb</filename> recipe file to
|
|
which you are appending Metadata resides in a different layer.
|
|
</para>
|
|
|
|
<para>
|
|
Append files must have the same root names as their corresponding
|
|
recipes.
|
|
For example, the append file
|
|
<filename>someapp_&DISTRO;.bbappend</filename> must apply to
|
|
<filename>someapp_&DISTRO;.bb</filename>.
|
|
This means the original recipe and append file names are version
|
|
number-specific.
|
|
If the corresponding recipe is renamed to update to a newer
|
|
version, the corresponding <filename>.bbappend</filename> file must
|
|
be renamed (and possibly updated) as well.
|
|
During the build process, BitBake displays an error on starting
|
|
if it detects a <filename>.bbappend</filename> file that does
|
|
not have a corresponding recipe with a matching name.
|
|
See the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BB_DANGLINGAPPENDS_WARNONLY'><filename>BB_DANGLINGAPPENDS_WARNONLY</filename></ulink>
|
|
variable for information on how to handle this error.
|
|
</para>
|
|
|
|
<para>
|
|
Being able to append information to an existing recipe not only
|
|
avoids duplication, but also automatically applies recipe
|
|
changes in a different layer to your layer.
|
|
If you were copying recipes, you would have to manually merge
|
|
changes as they occur.
|
|
</para>
|
|
|
|
<para>
|
|
As an example, consider the main formfactor recipe and a
|
|
corresponding formfactor append file both from the
|
|
<link linkend='source-directory'>Source Directory</link>.
|
|
Here is the main formfactor recipe, which is named
|
|
<filename>formfactor_0.0.bb</filename> and located in the
|
|
"meta" layer at
|
|
<filename>meta/recipes-bsp/formfactor</filename>:
|
|
<literallayout class='monospaced'>
|
|
SUMMARY = "Device formfactor information"
|
|
SECTION = "base"
|
|
LICENSE = "MIT"
|
|
LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \
|
|
file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
|
|
PR = "r44"
|
|
|
|
SRC_URI = "file://config file://machconfig"
|
|
S = "${WORKDIR}"
|
|
|
|
PACKAGE_ARCH = "${MACHINE_ARCH}"
|
|
INHIBIT_DEFAULT_DEPS = "1"
|
|
|
|
do_install() {
|
|
# Only install file if it has a 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
|
|
}
|
|
</literallayout>
|
|
In the main recipe, note the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
variable, which tells the OpenEmbedded build system where to
|
|
find files during the build.
|
|
</para>
|
|
|
|
<para>
|
|
Following is the append file, which is named
|
|
<filename>formfactor_0.0.bbappend</filename> and is from the
|
|
Crown Bay BSP Layer named
|
|
<filename>meta-intel/meta-crownbay</filename>.
|
|
The file is in <filename>recipes-bsp/formfactor</filename>:
|
|
<literallayout class='monospaced'>
|
|
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
By default, the build system uses the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILESPATH'><filename>FILESPATH</filename></ulink>
|
|
variable to locate files.
|
|
This append file extends the locations by setting the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILESEXTRAPATHS'><filename>FILESEXTRAPATHS</filename></ulink>
|
|
variable.
|
|
Setting this variable in the <filename>.bbappend</filename>
|
|
file is the most reliable and recommended method for adding
|
|
directories to the search path used by the build system
|
|
to find files.
|
|
</para>
|
|
|
|
<para>
|
|
The statement in this example extends the directories to include
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-THISDIR'><filename>THISDIR</filename></ulink><filename>}/${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink><filename>}</filename>,
|
|
which resolves to a directory named
|
|
<filename>formfactor</filename> in the same directory
|
|
in which the append file resides (i.e.
|
|
<filename>meta-intel/meta-crownbay/recipes-bsp/formfactor/formfactor</filename>.
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
Using the immediate expansion assignment operator
|
|
<filename>:=</filename> is important because of the reference to
|
|
<filename>THISDIR</filename>.
|
|
The trailing colon character is important as it ensures that
|
|
items in the list remain colon-separated.
|
|
<note>
|
|
<para>
|
|
BitBake automatically defines the
|
|
<filename>THISDIR</filename> variable.
|
|
You should never set this variable yourself.
|
|
Using "_prepend" ensures your path will
|
|
be searched prior to other paths in the final list.
|
|
</para>
|
|
|
|
<para>
|
|
Also, not all append files add extra files.
|
|
Many append files simply exist to add build options
|
|
(e.g. <filename>systemd</filename>).
|
|
For these cases, it is not necessary to use the
|
|
"_prepend" part of the statement.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='prioritizing-your-layer'>
|
|
<title>Prioritizing Your Layer</title>
|
|
|
|
<para>
|
|
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
|
|
<filename>.bbappend</filename> 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.
|
|
</para>
|
|
|
|
<para>
|
|
To specify the layer's priority manually, use the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBFILE_PRIORITY'><filename>BBFILE_PRIORITY</filename></ulink>
|
|
variable.
|
|
For example:
|
|
<literallayout class='monospaced'>
|
|
BBFILE_PRIORITY_mylayer = "1"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<note>
|
|
<para>It is possible for a recipe with a lower version number
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>
|
|
in a layer that has a higher priority to take precedence.</para>
|
|
<para>Also, the layer priority does not currently affect the
|
|
precedence order of <filename>.conf</filename>
|
|
or <filename>.bbclass</filename> files.
|
|
Future versions of BitBake might address this.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id='managing-layers'>
|
|
<title>Managing Layers</title>
|
|
|
|
<para>
|
|
You can use the BitBake layer management tool 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
|
|
<filename>.bbappend</filename> files and their applicable
|
|
recipes can help to reveal potential problems.
|
|
</para>
|
|
|
|
<para>
|
|
Use the following form when running the layer management tool.
|
|
<literallayout class='monospaced'>
|
|
$ bitbake-layers <command> [arguments]
|
|
</literallayout>
|
|
The following list describes the available commands:
|
|
<itemizedlist>
|
|
<listitem><para><filename><emphasis>help:</emphasis></filename>
|
|
Displays general help or help on a specified command.
|
|
</para></listitem>
|
|
<listitem><para><filename><emphasis>show-layers:</emphasis></filename>
|
|
Shows the current configured layers.
|
|
</para></listitem>
|
|
<listitem><para><filename><emphasis>show-recipes:</emphasis></filename>
|
|
Lists available recipes and the layers that provide them.
|
|
</para></listitem>
|
|
<listitem><para><filename><emphasis>show-overlayed:</emphasis></filename>
|
|
Lists overlayed recipes.
|
|
A recipe is overlayed when a recipe with the same name
|
|
exists in another layer that has a higher layer
|
|
priority.
|
|
</para></listitem>
|
|
<listitem><para><filename><emphasis>show-appends:</emphasis></filename>
|
|
Lists <filename>.bbappend</filename> files and the
|
|
recipe files to which they apply.
|
|
</para></listitem>
|
|
<listitem><para><filename><emphasis>show-cross-depends:</emphasis></filename>
|
|
Lists dependency relationships between recipes that
|
|
cross layer boundaries.
|
|
</para></listitem>
|
|
<listitem><para><filename><emphasis>flatten:</emphasis></filename>
|
|
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
|
|
<filename>.bbappend</filename> files appended to the
|
|
corresponding recipes.
|
|
You might have to perform some manual cleanup of the
|
|
flattened layer as follows:
|
|
<itemizedlist>
|
|
<listitem><para>Non-recipe files (such as patches)
|
|
are overwritten.
|
|
The flatten command shows a warning for these
|
|
files.
|
|
</para></listitem>
|
|
<listitem><para>Anything beyond the normal layer
|
|
setup has been added to the
|
|
<filename>layer.conf</filename> file.
|
|
Only the lowest priority layer's
|
|
<filename>layer.conf</filename> is used.
|
|
</para></listitem>
|
|
<listitem><para>Overridden and appended items from
|
|
<filename>.bbappend</filename> files need to be
|
|
cleaned up.
|
|
The contents of each
|
|
<filename>.bbappend</filename> 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 <filename>bitbake-layers</filename>
|
|
command adds the line
|
|
<filename>#### bbappended ...</filename> so that
|
|
you know where the following lines originate:
|
|
<literallayout class='monospaced'>
|
|
...
|
|
DESCRIPTION = "A useful utility"
|
|
...
|
|
EXTRA_OECONF = "‐‐enable-something"
|
|
...
|
|
|
|
#### bbappended from meta-anotherlayer ####
|
|
|
|
DESCRIPTION = "Customized utility"
|
|
EXTRA_OECONF += "‐‐enable-somethingelse"
|
|
</literallayout>
|
|
Ideally, you would tidy up these utilities as
|
|
follows:
|
|
<literallayout class='monospaced'>
|
|
...
|
|
DESCRIPTION = "Customized utility"
|
|
...
|
|
EXTRA_OECONF = "‐‐enable-something ‐‐enable-somethingelse"
|
|
...
|
|
</literallayout></para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-a-general-layer-using-the-yocto-layer-script'>
|
|
<title>Creating a General Layer Using the yocto-layer Script</title>
|
|
|
|
<para>
|
|
The <filename>yocto-layer</filename> script simplifies
|
|
creating a new general layer.
|
|
<note>
|
|
For information on BSP layers, see the
|
|
"<ulink url='&YOCTO_DOCS_BSP_URL;#bsp-layers'>BSP Layers</ulink>"
|
|
section in the Yocto Project Board Specific (BSP)
|
|
Developer's Guide.
|
|
</note>
|
|
The default mode of the script's operation is to prompt you for
|
|
information needed to generate the layer:
|
|
<itemizedlist>
|
|
<listitem><para>The layer priority
|
|
</para></listitem>
|
|
<listitem><para>Whether or not to create a sample recipe.
|
|
</para></listitem>
|
|
<listitem><para>Whether or not to create a sample
|
|
append file.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Use the <filename>yocto-layer create</filename> sub-command
|
|
to create a new general layer.
|
|
In its simplest form, you can create a layer as follows:
|
|
<literallayout class='monospaced'>
|
|
$ yocto-layer create mylayer
|
|
</literallayout>
|
|
The previous example creates a layer named
|
|
<filename>meta-mylayer</filename> in the current directory.
|
|
</para>
|
|
|
|
<para>
|
|
As the <filename>yocto-layer create</filename> command runs,
|
|
default values for the prompts appear in brackets.
|
|
Pressing enter without supplying anything for the prompts
|
|
or pressing enter and providing an invalid response causes the
|
|
script to accept the default value.
|
|
Once the script completes, the new layer
|
|
is created in the current working directory.
|
|
The script names the layer by prepending
|
|
<filename>meta-</filename> to the name you provide.
|
|
</para>
|
|
|
|
<para>
|
|
Minimally, the script creates the following within the layer:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>The <filename>conf</filename>
|
|
directory:</emphasis>
|
|
This directory contains the layer's configuration file.
|
|
The root name for the file is the same as the root name
|
|
your provided for the layer (e.g.
|
|
<filename><layer>.conf</filename>).
|
|
</para></listitem>
|
|
<listitem><para><emphasis>The
|
|
<filename>COPYING.MIT</filename> file:</emphasis>
|
|
The copyright and use notice for the software.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>The <filename>README</filename>
|
|
file:</emphasis>
|
|
A file describing the contents of your new layer.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
If you choose to generate a sample recipe file, the script
|
|
prompts you for the name for the recipe and then creates it
|
|
in <filename><layer>/recipes-example/example/</filename>.
|
|
The script creates a <filename>.bb</filename> file and a
|
|
directory, which contains a sample
|
|
<filename>helloworld.c</filename> source file, along with
|
|
a sample patch file.
|
|
If you do not provide a recipe name, the script uses
|
|
"example".
|
|
</para>
|
|
|
|
<para>
|
|
If you choose to generate a sample append file, the script
|
|
prompts you for the name for the file and then creates it
|
|
in <filename><layer>/recipes-example-bbappend/example-bbappend/</filename>.
|
|
The script creates a <filename>.bbappend</filename> file and a
|
|
directory, which contains a sample patch file.
|
|
If you do not provide a recipe name, the script uses
|
|
"example".
|
|
The script also prompts you for the version of the append file.
|
|
The version should match the recipe to which the append file
|
|
is associated.
|
|
</para>
|
|
|
|
<para>
|
|
The easiest way to see how the <filename>yocto-layer</filename>
|
|
script works is to experiment with the script.
|
|
You can also read the usage information by entering the
|
|
following:
|
|
<literallayout class='monospaced'>
|
|
$ yocto-layer help
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Once you create your general layer, you must add it to your
|
|
<filename>bblayers.conf</filename> file.
|
|
Here is an example where a layer named
|
|
<filename>meta-mylayer</filename> is added:
|
|
<literallayout class='monospaced'>
|
|
BBLAYERS = ?" \
|
|
/usr/local/src/yocto/meta \
|
|
/usr/local/src/yocto/meta-yocto \
|
|
/usr/local/src/yocto/meta-yocto-bsp \
|
|
/usr/local/src/yocto/meta-mylayer \
|
|
"
|
|
|
|
BBLAYERS_NON_REMOVABLE ?= " \
|
|
/usr/local/src/yocto/meta \
|
|
/usr/local/src/yocto/meta-yocto \
|
|
"
|
|
</literallayout>
|
|
Adding the layer to this file enables the build system to
|
|
locate the layer during the build.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage'>
|
|
<title>Customizing Images</title>
|
|
|
|
<para>
|
|
You can customize images to satisfy particular requirements.
|
|
This section describes several methods and provides guidelines for each.
|
|
</para>
|
|
|
|
<section id='usingpoky-extend-customimage-localconf'>
|
|
<title>Customizing Images Using <filename>local.conf</filename></title>
|
|
|
|
<para>
|
|
Probably the easiest way to customize an image is to add a
|
|
package by way of the <filename>local.conf</filename>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
To add a package to your image using the local configuration
|
|
file, use the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_INSTALL'>IMAGE_INSTALL</ulink></filename>
|
|
variable with the <filename>_append</filename> operator:
|
|
<literallayout class='monospaced'>
|
|
IMAGE_INSTALL_append = " strace"
|
|
</literallayout>
|
|
Use of the syntax is important - specifically, the space between
|
|
the quote and the package name, which is
|
|
<filename>strace</filename> in this example.
|
|
This space is required since the <filename>_append</filename>
|
|
operator does not add the space.
|
|
</para>
|
|
|
|
<para>
|
|
Furthermore, you must use <filename>_append</filename> instead
|
|
of the <filename>+=</filename> 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
|
|
<filename>.bbclass</filename> files with operators like
|
|
<filename>?=</filename>.
|
|
Using <filename>_append</filename> ensures the operation takes
|
|
affect.
|
|
</para>
|
|
|
|
<para>
|
|
As shown in its simplest use,
|
|
<filename>IMAGE_INSTALL_append</filename> affects all images.
|
|
It is possible to extend the syntax so that the variable
|
|
applies to a specific image only.
|
|
Here is an example:
|
|
<literallayout class='monospaced'>
|
|
IMAGE_INSTALL_append_pn-core-image-minimal = " strace"
|
|
</literallayout>
|
|
This example adds <filename>strace</filename> to the
|
|
<filename>core-image-minimal</filename> image only.
|
|
</para>
|
|
|
|
<para>
|
|
You can add packages using a similar approach through the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-CORE_IMAGE_EXTRA_INSTALL'>CORE_IMAGE_EXTRA_INSTALL</ulink></filename>
|
|
variable.
|
|
If you use this variable, only
|
|
<filename>core-image-*</filename> images are affected.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage-imagefeatures'>
|
|
<title>Customizing Images Using Custom <filename>IMAGE_FEATURES</filename> and
|
|
<filename>EXTRA_IMAGE_FEATURES</filename></title>
|
|
|
|
<para>
|
|
Another method for customizing your image is to enable or
|
|
disable high-level image features by using the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>
|
|
and <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_IMAGE_FEATURES'><filename>EXTRA_IMAGE_FEATURES</filename></ulink>
|
|
variables.
|
|
Although the functions for both variables are nearly equivalent,
|
|
best practices dictate using <filename>IMAGE_FEATURES</filename>
|
|
from within a recipe and using
|
|
<filename>EXTRA_IMAGE_FEATURES</filename> from within
|
|
your <filename>local.conf</filename> file, which is found in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
</para>
|
|
|
|
<para>
|
|
To understand how these features work, the best reference is
|
|
<filename>meta/classes/core-image.bbclass</filename>.
|
|
In summary, the file looks at the contents of the
|
|
<filename>IMAGE_FEATURES</filename> variable and then maps
|
|
those contents into a set of package groups.
|
|
Based on this information, the build system automatically
|
|
adds the appropriate packages to the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_INSTALL'><filename>IMAGE_INSTALL</filename></ulink>
|
|
variable.
|
|
Effectively, you are enabling extra features by extending the
|
|
class or creating a custom class for use with specialized image
|
|
<filename>.bb</filename> files.
|
|
</para>
|
|
|
|
<para>
|
|
Use the <filename>EXTRA_IMAGE_FEATURES</filename> 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
|
|
<filename>IMAGE_FEATURES</filename>.
|
|
The value of <filename>EXTRA_IMAGE_FEATURES</filename> is added
|
|
to <filename>IMAGE_FEATURES</filename> within
|
|
<filename>meta/conf/bitbake.conf</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
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 <filename>core-image-sato</filename> image
|
|
is configured to use Dropbear.
|
|
The <filename>core-image-full-cmdline</filename> and
|
|
<filename>core-image-lsb</filename> images both
|
|
include OpenSSH.
|
|
The <filename>core-image-minimal</filename> image does not
|
|
contain an SSH server.
|
|
</para>
|
|
|
|
<para>
|
|
You can customize your image and change these defaults.
|
|
Edit the <filename>IMAGE_FEATURES</filename> variable
|
|
in your recipe or use the
|
|
<filename>EXTRA_IMAGE_FEATURES</filename> in your
|
|
<filename>local.conf</filename> file so that it configures the
|
|
image you are working with to include
|
|
<filename>ssh-server-dropbear</filename> or
|
|
<filename>ssh-server-openssh</filename>.
|
|
</para>
|
|
|
|
<note>
|
|
See the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-images'>Images</ulink>"
|
|
section in the Yocto Project Reference Manual for a complete
|
|
list of image features that ship with the Yocto Project.
|
|
</note>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage-custombb'>
|
|
<title>Customizing Images Using Custom .bb Files</title>
|
|
|
|
<para>
|
|
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:
|
|
<literallayout class='monospaced'>
|
|
IMAGE_INSTALL = "packagegroup-core-x11-base package1 package2"
|
|
|
|
inherit core-image
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_INSTALL'>IMAGE_INSTALL</ulink></filename>
|
|
variable.
|
|
You must use the OpenEmbedded notation and not the Debian notation for the names
|
|
(e.g. <filename>eglibc-dev</filename> instead of <filename>libc6-dev</filename>).
|
|
</para>
|
|
|
|
<para>
|
|
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 <filename>core-image-sato</filename>
|
|
but add the additional package <filename>strace</filename> to the image,
|
|
copy the <filename>meta/recipes-sato/images/core-image-sato.bb</filename> to a
|
|
new <filename>.bb</filename> and add the following line to the end of the copy:
|
|
<literallayout class='monospaced'>
|
|
IMAGE_INSTALL += "strace"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='usingpoky-extend-customimage-customtasks'>
|
|
<title>Customizing Images Using Custom Package Groups</title>
|
|
|
|
<para>
|
|
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
|
|
<filename>meta/recipes-core/packagegroups/packagegroup-core-boot.bb</filename>.
|
|
The
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'>PACKAGES</ulink></filename>
|
|
variable lists the package group packages you wish to produce.
|
|
<filename>inherit packagegroup</filename> sets appropriate
|
|
default values and automatically adds <filename>-dev</filename>,
|
|
<filename>-dbg</filename>, and <filename>-ptest</filename>
|
|
complementary packages for every package specified in
|
|
<filename>PACKAGES</filename>.
|
|
Note that the inherit line should be towards
|
|
the top of the recipe, certainly before you set
|
|
<filename>PACKAGES</filename>.
|
|
For each package you specify in <filename>PACKAGES</filename>,
|
|
you can use
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-RDEPENDS'>RDEPENDS</ulink></filename>
|
|
and
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-RRECOMMENDS'>RRECOMMENDS</ulink></filename>
|
|
entries to provide a list of packages the parent task package
|
|
should contain.
|
|
Following is an example:
|
|
<literallayout class='monospaced'>
|
|
DESCRIPTION = "My Custom Package Groups"
|
|
|
|
inherit packagegroup
|
|
|
|
PACKAGES = "\
|
|
packagegroup-custom-apps \
|
|
packagegroup-custom-tools \
|
|
"
|
|
|
|
RDEPENDS_packagegroup-custom-apps = "\
|
|
dropbear \
|
|
portmap \
|
|
psplash"
|
|
|
|
RDEPENDS_packagegroup-custom-tools = "\
|
|
oprofile \
|
|
oprofileui-server \
|
|
lttng-control \
|
|
lttng-viewer"
|
|
|
|
RRECOMMENDS_packagegroup-custom-tools = "\
|
|
kernel-module-oprofile"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
In the previous example, two package group packages are created with their dependencies and their
|
|
recommended package dependencies listed: <filename>packagegroup-custom-apps</filename>, and
|
|
<filename>packagegroup-custom-tools</filename>.
|
|
To build an image using these package group packages, you need to add
|
|
<filename>packagegroup-custom-apps</filename> and/or
|
|
<filename>packagegroup-custom-tools</filename> to
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_INSTALL'>IMAGE_INSTALL</ulink></filename>.
|
|
For other forms of image dependencies see the other areas of this section.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='new-recipe-writing-a-new-recipe'>
|
|
<title>Writing a New Recipe</title>
|
|
|
|
<para>
|
|
Recipes (<filename>.bb</filename> 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
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-varlocality-recipe-required'>Required</ulink>"
|
|
section of the Yocto Project Reference Manual.
|
|
</note>
|
|
</para>
|
|
|
|
<section id='new-recipe-overview'>
|
|
<title>Overview</title>
|
|
|
|
<para>
|
|
The following figure shows the basic process for creating a
|
|
new recipe.
|
|
The remainder of the section provides details for the steps.
|
|
<imagedata fileref="figures/recipe-workflow.png" width="6in" depth="7in" align="center" scalefit="1" />
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-locate-a-base-recipe'>
|
|
<title>Locate a Base Recipe</title>
|
|
|
|
<para>
|
|
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
|
|
<ulink url='http://layers.openembedded.org'>OpenEmbedded metadata index</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
Working from an existing recipe or a skeleton recipe is the
|
|
best way to get started.
|
|
Here are some points on both methods:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Locate and modify a recipe that
|
|
is close to what you want to do:</emphasis>
|
|
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.</para>
|
|
<para>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.</para></listitem>
|
|
<listitem><para><emphasis>Use and modify the following
|
|
skeleton recipe:</emphasis>
|
|
<literallayout class='monospaced'>
|
|
SUMMARY = ""
|
|
HOMEPAGE = ""
|
|
LICENSE = ""
|
|
|
|
LIC_FILES_CHKSUM = ""
|
|
|
|
SRC_URI = ""
|
|
SRC_URI[md5sum] = ""
|
|
SRC_URI[sha256sum] = ""
|
|
|
|
S = "${WORKDIR}/${PN}-${PV}"
|
|
|
|
inherit <stuff>
|
|
</literallayout>
|
|
Modifying this recipe is the recommended method for
|
|
creating a new recipe.
|
|
The recipe provides the fundamental areas that you need
|
|
to include, exclude, or alter to fit your needs.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-storing-and-naming-the-recipe'>
|
|
<title>Storing and Naming the Recipe</title>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Storing Your Recipe:</emphasis>
|
|
The OpenEmbedded build system locates your recipe
|
|
through the layer's <filename>conf/layer.conf</filename>
|
|
file and the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBFILES'><filename>BBFILES</filename></ulink>
|
|
variable.
|
|
This variable sets up a path from which the build system can
|
|
locate recipes.
|
|
Here is the typical use:
|
|
<literallayout class='monospaced'>
|
|
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
|
|
${LAYERDIR}/recipes-*/*/*.bbappend"
|
|
</literallayout>
|
|
Consequently, you need to be sure you locate your new recipe
|
|
inside your layer such that it can be found.</para>
|
|
<para>You can find more information on how layers are
|
|
structured in the
|
|
"<link linkend='understanding-and-creating-layers'>Understanding and Creating Layers</link>"
|
|
section.</para></listitem>
|
|
<listitem><para><emphasis>Naming Your Recipe:</emphasis>
|
|
When you name your recipe, you need to follow this naming
|
|
convention:
|
|
<literallayout class='monospaced'>
|
|
<basename>_<version>.bb
|
|
</literallayout>
|
|
Use lower-cased characters and do not include the reserved
|
|
suffixes <filename>-native</filename>,
|
|
<filename>-cross</filename>, <filename>-initial</filename>,
|
|
or <filename>-dev</filename> casually (i.e. do not use them
|
|
as part of your recipe name unless the string applies).
|
|
Here are some examples:
|
|
<literallayout class='monospaced'>
|
|
cups_1.7.0.bb
|
|
gawk_4.0.2.bb
|
|
irssi_0.8.16-rc1.bb
|
|
</literallayout></para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section id='understanding-recipe-syntax'>
|
|
<title>Understanding Recipe Syntax</title>
|
|
|
|
<para>
|
|
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
|
|
"<ulink url='&YOCTO_DOCS_BB_URL;#bitbake-user-manual-metadata'>Syntax and Operators</ulink>"
|
|
chapter of the BitBake User Manual.
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Variable Assignments and Manipulations:</emphasis>
|
|
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.</para>
|
|
<para>The following example shows some of the ways
|
|
you can use variables in recipes:
|
|
<literallayout class='monospaced'>
|
|
S = "${WORKDIR}/postfix-${PV}"
|
|
CFLAGS += "-DNO_ASM"
|
|
SRC_URI_append = " file://fixup.patch"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Functions:</emphasis>
|
|
Functions provide a series of actions to be performed.
|
|
You usually use functions to override the default
|
|
implementation of a task function or to compliment
|
|
a default function (i.e. append or prepend to an
|
|
existing function).
|
|
Standard functions use <filename>sh</filename> shell
|
|
syntax, although access to OpenEmbedded variables and
|
|
internal methods are also available.</para>
|
|
<para>The following is an example function from the
|
|
<filename>sed</filename> recipe:
|
|
<literallayout class='monospaced'>
|
|
do_install () {
|
|
autotools_do_install
|
|
install -d ${D}${base_bindir}
|
|
mv ${D}${bindir}/sed ${D}${base_bindir}/sed.${PN}
|
|
}
|
|
</literallayout>
|
|
It is also possible to implement new functions that
|
|
are called between existing tasks as long as the
|
|
new functions are not replacing or complimenting the
|
|
default functions.
|
|
You can implement functions in Python
|
|
instead of shell.
|
|
Both of these options are not seen in the majority of
|
|
recipes.</para></listitem>
|
|
<listitem><para><emphasis>Keywords:</emphasis>
|
|
BitBake recipes use only a few keywords.
|
|
You use keywords to include common
|
|
functions (<filename>inherit</filename>), load parts
|
|
of a recipe from other files
|
|
(<filename>include</filename> and
|
|
<filename>require</filename>) and export variables
|
|
to the environment (<filename>export</filename>).</para>
|
|
<para>The following example shows the use of some of
|
|
these keywords:
|
|
<literallayout class='monospaced'>
|
|
export POSTCONF = "${STAGING_BINDIR}/postconf"
|
|
inherit autoconf
|
|
require otherfile.inc
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Comments:</emphasis>
|
|
Any lines that begin with the hash character
|
|
(<filename>#</filename>) are treated as comment lines
|
|
and are ignored:
|
|
<literallayout class='monospaced'>
|
|
# This is a comment
|
|
</literallayout>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<ulink url='&YOCTO_DOCS_BB_URL;#bitbake-user-manual-metadata'>Syntax and Operators</ulink>
|
|
chapter in the BitBake User Manual.
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Line Continuation: <filename>\</filename></emphasis> -
|
|
Use the backward slash (<filename>\</filename>)
|
|
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:
|
|
<literallayout class='monospaced'>
|
|
VAR = "A really long \
|
|
line"
|
|
</literallayout>
|
|
<note>
|
|
You cannot have any characters including spaces
|
|
or tabs after the slash character.
|
|
</note>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Using Variables: <filename>${...}</filename></emphasis> -
|
|
Use the <filename>${<varname>}</filename> syntax to
|
|
access the contents of a variable:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Quote All Assignments: <filename>"<value>"</filename></emphasis> -
|
|
Use double quotes around the value in all variable
|
|
assignments.
|
|
<literallayout class='monospaced'>
|
|
VAR1 = "${OTHERVAR}"
|
|
VAR2 = "The version is ${PV}"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Conditional Assignment: <filename>?=</filename></emphasis> -
|
|
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
|
|
(<filename>?=</filename>) to make a "soft" assignment
|
|
used for conditional assignment.
|
|
Typically, "soft" assignments are used in the
|
|
<filename>local.conf</filename> file for variables
|
|
that are allowed to come through from the external
|
|
environment.
|
|
</para>
|
|
<para>Here is an example where
|
|
<filename>VAR1</filename> is set to "New value" if
|
|
it is currently empty.
|
|
However, if <filename>VAR1</filename> has already been
|
|
set, it remains unchanged:
|
|
<literallayout class='monospaced'>
|
|
VAR1 ?= "New value"
|
|
</literallayout>
|
|
In this next example, <filename>VAR1</filename>
|
|
is left with the value "Original value":
|
|
<literallayout class='monospaced'>
|
|
VAR1 = "Original value"
|
|
VAR1 ?= "New value"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Appending: <filename>+=</filename></emphasis> -
|
|
Use the plus character followed by the equals sign
|
|
(<filename>+=</filename>) to append values to existing
|
|
variables.
|
|
<note>
|
|
This operator adds a space between the existing
|
|
content of the variable and the new content.
|
|
</note></para>
|
|
<para>Here is an example:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI += "file://fix-makefile.patch"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Prepending: <filename>=+</filename></emphasis> -
|
|
Use the equals sign followed by the plus character
|
|
(<filename>=+</filename>) to prepend values to existing
|
|
variables.
|
|
<note>
|
|
This operator adds a space between the new content
|
|
and the existing content of the variable.
|
|
</note></para>
|
|
<para>Here is an example:
|
|
<literallayout class='monospaced'>
|
|
VAR =+ "Starts"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Appending: <filename>_append</filename></emphasis> -
|
|
Use the <filename>_append</filename> operator to
|
|
append values to existing variables.
|
|
This operator does not add any additional space.
|
|
Also, the operator is applied after all the
|
|
<filename>+=</filename>, and
|
|
<filename>=+</filename> operators have been applied and
|
|
after all <filename>=</filename> assignments have
|
|
occurred.
|
|
</para>
|
|
<para>The following example shows the space being
|
|
explicitly added to the start to ensure the appended
|
|
value is not merged with the existing value:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI_append = " file://fix-makefile.patch"
|
|
</literallayout>
|
|
You can also use the <filename>_append</filename>
|
|
operator with overrides, which results in the actions
|
|
only being performed for the specified target or
|
|
machine:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI_append_sh4 = " file://fix-makefile.patch"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Prepending: <filename>_prepend</filename></emphasis> -
|
|
Use the <filename>_prepend</filename> operator to
|
|
prepend values to existing variables.
|
|
This operator does not add any additional space.
|
|
This operator does not add any additional space.
|
|
Also, the operator is applied after all the
|
|
<filename>+=</filename>, and
|
|
<filename>=+</filename> operators have been applied and
|
|
after all <filename>=</filename> assignments have
|
|
occurred.
|
|
</para>
|
|
<para>The following example shows the space being
|
|
explicitly added to the end to ensure the prepended
|
|
value is not merged with the existing value:
|
|
<literallayout class='monospaced'>
|
|
CFLAGS_prepend = "-I${S}/myincludes "
|
|
</literallayout>
|
|
You can also use the <filename>_prepend</filename>
|
|
operator with overrides, which results in the actions
|
|
only being performed for the specified target or
|
|
machine:
|
|
<literallayout class='monospaced'>
|
|
CFLAGS_prepend_sh4 = " file://fix-makefile.patch"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Overrides:</emphasis> -
|
|
You can use overrides to set a value conditionally,
|
|
typically on how the recipe is being built.
|
|
For example, to set the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-KBRANCH'><filename>KBRANCH</filename></ulink>
|
|
variable's value to "standard/base" for any target
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>,
|
|
except for qemuarm where it should be set to
|
|
"standard/arm-versatile-926ejs", you would do the
|
|
following:
|
|
<literallayout class='monospaced'>
|
|
KBRANCH = "standard/base"
|
|
KBRANCH_qemuarm = "standard/arm-versatile-926ejs"
|
|
</literallayout>
|
|
Overrides are also used to separate alternate values
|
|
of a variable in other situations.
|
|
For example, when setting variables such as
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILES'><filename>FILES</filename></ulink>
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-RDEPENDS'><filename>RDEPENDS</filename></ulink>,
|
|
that are specific to individual packages produced by
|
|
a recipe, you should always use an override that
|
|
specifies the name of the package.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Indentation:</emphasis>
|
|
Use spaces for indentation rather than 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.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Using Python for Complex Operations: <filename>${@<python_code>}</filename></emphasis> -
|
|
For more advanced processing, it is possible to use
|
|
Python code during variable assignments (e.g.
|
|
search and replacement on a variable).</para>
|
|
<para>You indicate Python code using the
|
|
<filename>${@<python_code>}</filename>
|
|
syntax for the variable assignment:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI = "ftp://ftp.info-zip.org/pub/infozip/src/zip${@d.getVar('PV',1).replace('.', '')}.tgz
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Shell Function Syntax:</emphasis>
|
|
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
|
|
<filename>sh</filename> and that it does not require
|
|
any <filename>bash</filename> or other shell-specific
|
|
functionality.
|
|
The same considerations apply to various system
|
|
utilities (e.g. <filename>sed</filename>,
|
|
<filename>grep</filename>, <filename>awk</filename>,
|
|
and so forth) that you might wish to use.
|
|
If in doubt, you should check with multiple
|
|
implementations - including those from BusyBox.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-running-a-build-on-the-recipe'>
|
|
<title>Running a Build on the Recipe</title>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
Assuming you have sourced a build environment setup script (i.e.
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
|
or
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-memres-core-script'><filename>oe-init-build-env-memres</filename></ulink>)
|
|
and you are in the
|
|
<link linkend='build-directory'>Build Directory</link>,
|
|
use BitBake to process your recipe.
|
|
All you need to provide is the
|
|
<filename><basename></filename> of the recipe as described
|
|
in the previous section:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake <basename>
|
|
</literallayout>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
During the build, the OpenEmbedded build system creates a
|
|
temporary work directory for the recipe
|
|
(<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-WORKDIR'><filename>WORKDIR</filename></ulink><filename>}</filename>)
|
|
where it keeps extracted source files, log files, intermediate
|
|
compilation and packaging files, and so forth.
|
|
</para>
|
|
|
|
<para>
|
|
The temporary work directory is constructed as follows and
|
|
depends on several factors:
|
|
<literallayout class='monospaced'>
|
|
${TMPDIR}/work/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}
|
|
</literallayout>
|
|
As an example, assume a Source Directory top-level folder named
|
|
<filename>poky</filename>, a default Build Directory at
|
|
<filename>poky/build</filename>, and a
|
|
<filename>qemux86-poky-linux</filename> machine target system.
|
|
Furthermore, suppose your recipe is named
|
|
<filename>foo_1.3.0.bb</filename>.
|
|
In this case, the work directory the build system uses to
|
|
build the package would be as follows:
|
|
<literallayout class='monospaced'>
|
|
poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0
|
|
</literallayout>
|
|
Inside this directory you can find sub-directories such as
|
|
<filename>image</filename>, <filename>packages-split</filename>,
|
|
and <filename>temp</filename>.
|
|
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
|
|
<filename>temp</filename> directory (e.g.
|
|
<filename>poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0/temp</filename>).
|
|
Log files are named <filename>log.<taskname></filename>
|
|
(e.g. <filename>log.do_configure</filename>,
|
|
<filename>log.do_fetch</filename>, and
|
|
<filename>log.do_compile</filename>).
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
You can find more information about the build process in the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#closer-look'>A Closer Look at the Yocto Project Development Environment</ulink>"
|
|
chapter of the Yocto Project Reference Manual.
|
|
</para>
|
|
|
|
<para>
|
|
You can also reference the following variables in the
|
|
Yocto Project Reference Manual's glossary for more information:
|
|
<itemizedlist>
|
|
<listitem><ulink url='&YOCTO_DOCS_REF_URL;#var-TMPDIR'><filename>TMPDIR</filename></ulink>:
|
|
The top-level build output directory</listitem>
|
|
<listitem><ulink url='&YOCTO_DOCS_REF_URL;#var-MULTIMACH_TARGET_SYS'><filename>MULTIMACH_TARGET_SYS</filename></ulink>:
|
|
The target system identifier</listitem>
|
|
<listitem><ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink>:
|
|
The recipe name</listitem>
|
|
<listitem><ulink url='&YOCTO_DOCS_REF_URL;#var-EXTENDPE'><filename>EXTENDPE</filename></ulink>:
|
|
The epoch - (if
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PE'><filename>PE</filename></ulink>
|
|
is not specified, which is usually the case for most
|
|
recipes, then <filename>EXTENDPE</filename> is blank)</listitem>
|
|
<listitem><ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>:
|
|
The recipe version</listitem>
|
|
<listitem><ulink url='&YOCTO_DOCS_REF_URL;#var-PR'><filename>PR</filename></ulink>:
|
|
The recipe revision</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-fetching-code'>
|
|
<title>Fetching Code</title>
|
|
|
|
<para>
|
|
The first thing your recipe must do is specify how to fetch
|
|
the source files.
|
|
Fetching is controlled mainly through the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
variable.
|
|
Your recipe must have a <filename>SRC_URI</filename> variable
|
|
that points to where the source is located.
|
|
For a graphical representation of source locations, see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#sources-dev-environment'>Sources</ulink>"
|
|
section in the Yocto Project Reference Manual.
|
|
</para>
|
|
|
|
<para>
|
|
The
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-fetch'><filename>do_fetch</filename></ulink>
|
|
task uses the prefix of each entry in the
|
|
<filename>SRC_URI</filename> variable value to determine what
|
|
fetcher to use to get your source files.
|
|
It is the <filename>SRC_URI</filename> variable that triggers
|
|
the fetcher.
|
|
The
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-patch'><filename>do_patch</filename></ulink>
|
|
task uses the variable after source is fetched to apply
|
|
patches.
|
|
The OpenEmbedded build system uses
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILESOVERRIDES'><filename>FILESOVERRIDES</filename></ulink>
|
|
for scanning directory locations for local files in
|
|
<filename>SRC_URI</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
The <filename>SRC_URI</filename> variable in your recipe must
|
|
define each unique location for your source files.
|
|
It is good practice to not hard-code pathnames in an URL used
|
|
in <filename>SRC_URI</filename>.
|
|
Rather than hard-code these paths, use
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink><filename>}</filename>,
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
Here is a simple example from the
|
|
<filename>meta/recipes-devtools/cdrtools/cdrtools-native_3.01a17.bb</filename>
|
|
recipe where the source comes from a single tarball.
|
|
Notice the use of the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>
|
|
variable:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI = "ftp://ftp.berlios.de/pub/cdrecord/alpha/cdrtools-${PV}.tar.bz2"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Files mentioned in <filename>SRC_URI</filename> whose names end
|
|
in a typical archive extension (e.g. <filename>.tar</filename>,
|
|
<filename>.tar.gz</filename>, <filename>.tar.bz2</filename>,
|
|
<filename>.zip</filename>, and so forth), are automatically
|
|
extracted during the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-unpack'><filename>do_unpack</filename></ulink>
|
|
task.
|
|
For another example that specifies these types of files, see
|
|
the
|
|
"<link linkend='new-recipe-autotooled-package'>Autotooled Package</link>"
|
|
section.
|
|
</para>
|
|
|
|
<para>
|
|
Another way of specifying source is from an SCM.
|
|
For Git repositories, you must specify
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRCREV'><filename>SRCREV</filename></ulink>
|
|
and you should specify
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>
|
|
to include the revision with
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRCPV'><filename>SRCPV</filename></ulink>.
|
|
Here is an example from the recipe
|
|
<filename>meta/recipes-kernel/blktrace/blktrace_git.bb</filename>:
|
|
<literallayout class='monospaced'>
|
|
SRCREV = "d6918c8832793b4205ed3bfede78c2f915c23385"
|
|
|
|
PR = "r6"
|
|
PV = "1.0.5+git${SRCPV}"
|
|
|
|
SRC_URI = "git://git.kernel.dk/blktrace.git \
|
|
file://ldflags.patch"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
If your <filename>SRC_URI</filename> 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:
|
|
<filename>SRC_URI[md5sum]</filename> and
|
|
<filename>SRC_URI[sha256sum]</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
If your <filename>SRC_URI</filename> variable points to
|
|
more than a single URL (excluding SCM URLs), you need to
|
|
provide the <filename>md5</filename> and
|
|
<filename>sha256</filename> checksums for each URL.
|
|
For these cases, you provide a name for each URL as part of
|
|
the <filename>SRC_URI</filename> and then reference that name
|
|
in the subsequent checksum statements.
|
|
Here is an example:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI = "${DEBIAN_MIRROR}/main/a/apmd/apmd_3.2.2.orig.tar.gz;name=tarball \
|
|
${DEBIAN_MIRROR}/main/a/apmd/apmd_${PV}.diff.gz;name=patch
|
|
|
|
SRC_URI[tarball.md5sum] = "b1e6309e8331e0f4e6efd311c2d97fa8"
|
|
SRC_URI[tarball.sha256sum] = "7f7d9f60b7766b852881d40b8ff91d8e39fccb0d1d913102a5c75a2dbb52332d"
|
|
|
|
SRC_URI[patch.md5sum] = "57e1b689264ea80f78353519eece0c92"
|
|
SRC_URI[patch.sha256sum] = "7905ff96be93d725544d0040e425c42f9c05580db3c272f11cff75b9aa89d430"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Finding proper values for <filename>md5</filename> and
|
|
<filename>sha256</filename> checksums can involve some work.
|
|
Initially, you should locate any available signatures from
|
|
the upstream source (i.e. <filename>md5</filename>,
|
|
<filename>sha1</filename>, <filename>sha256</filename>,
|
|
<filename>GPG</filename>, and so forth).
|
|
Because the OpenEmbedded build system only deals with
|
|
<filename>sha256sum</filename> and <filename>md5sum</filename>,
|
|
you should verify all the signatures you find by hand.
|
|
</para>
|
|
|
|
<para>
|
|
After you have verified as many signatures as you can,
|
|
you can use a "build-fail" method that retrieves the exact
|
|
<filename>sha256sum</filename> and <filename>md5sum</filename>
|
|
checksums you need.
|
|
To use the "build-fail" method, comment the
|
|
<filename>SRC_URI</filename> statements out that provide the
|
|
checksums and then attempt to build the software.
|
|
The build will produce an error for each missing checksum
|
|
and as part of the error message provide the correct checksum
|
|
string.
|
|
Once you have the correct checksums, simply copy them into your
|
|
recipe for a subsequent build.
|
|
</para>
|
|
|
|
<para>
|
|
This final example is a bit more complicated and is from the
|
|
<filename>meta/recipes-sato/rxvt-unicode/rxvt-unicode_9.19.bb</filename>
|
|
recipe.
|
|
The example's <filename>SRC_URI</filename> statement identifies
|
|
multiple files as the source files for the recipe: a tarball, a
|
|
patch file, a desktop file, and an icon.
|
|
<literallayout class='monospaced'>
|
|
SRC_URI = "http://dist.schmorp.de/rxvt-unicode/Attic/rxvt-unicode-${PV}.tar.bz2 \
|
|
file://xwc.patch \
|
|
file://rxvt.desktop \
|
|
file://rxvt.png"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
When you specify local files using the
|
|
<filename>file://</filename> URI protocol, the build system
|
|
fetches files from the local machine.
|
|
The path is relative to the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILESPATH'><filename>FILESPATH</filename></ulink>
|
|
variable and searches specific directories in a certain order:
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BPN'><filename>BPN</filename></ulink><filename>}</filename>,
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BP'><filename>BP</filename></ulink><filename>}</filename>,
|
|
and <filename>files</filename>.
|
|
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
|
|
"<link linkend='new-recipe-single-c-file-package-hello-world'>Single .c File Package (Hello World!)</link>"
|
|
section.
|
|
</para>
|
|
|
|
<para>
|
|
The previous example also specifies a patch file.
|
|
Patch files are files whose names end in
|
|
<filename>.patch</filename> or <filename>.diff</filename>.
|
|
The build system automatically applies patches as described
|
|
in the
|
|
"<link linkend='new-recipe-patching-code'>Patching Code</link>" section.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-unpacking-code'>
|
|
<title>Unpacking Code</title>
|
|
|
|
<para>
|
|
During the build, the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-unpack'><filename>do_unpack</filename></ulink>
|
|
task unpacks the source with
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-S'><filename>S</filename></ulink><filename>}</filename>
|
|
pointing to where it is unpacked.
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BPN'><filename>BPN</filename></ulink><filename>}-${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink><filename>}</filename>,
|
|
then you do not need to set <filename>S</filename>.
|
|
However, if <filename>SRC_URI</filename> 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 <filename>S</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
If processing your recipe using BitBake successfully unpacks
|
|
the source files, you need to be sure that the directory
|
|
pointed to by <filename>${S}</filename> matches the structure
|
|
of the source.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-patching-code'>
|
|
<title>Patching Code</title>
|
|
|
|
<para>
|
|
Sometimes it is necessary to patch code after it has been
|
|
fetched.
|
|
Any files mentioned in <filename>SRC_URI</filename> whose
|
|
names end in <filename>.patch</filename> or
|
|
<filename>.diff</filename> are treated as patches.
|
|
The
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-patch'><filename>do_patch</filename></ulink>
|
|
task automatically applies these patches.
|
|
</para>
|
|
|
|
<para>
|
|
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 <filename>SRC_URI</filename> 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.
|
|
</para>
|
|
|
|
<para>
|
|
As with all local files referenced in
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
using <filename>file://</filename>, you should place
|
|
patch files in a directory next to the recipe either
|
|
named the same as the base name of the recipe
|
|
(<ulink url='&YOCTO_DOCS_REF_URL;#var-BPN'><filename>BPN</filename></ulink>),
|
|
or "files".
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-licensing'>
|
|
<title>Licensing</title>
|
|
|
|
<para>
|
|
Your recipe needs to have both the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-LICENSE'><filename>LICENSE</filename></ulink>
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-LIC_FILES_CHKSUM'><filename>LIC_FILES_CHKSUM</filename></ulink>
|
|
variables:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>LICENSE</filename>:</emphasis>
|
|
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
|
|
<filename>COPYING</filename>,
|
|
<filename>LICENSE</filename>, and
|
|
<filename>README</filename> 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 <filename>LICENSE</filename> as follows:
|
|
<literallayout class='monospaced'>
|
|
LICENSE = "GPLv2"
|
|
</literallayout></para>
|
|
<para>The licenses you specify within
|
|
<filename>LICENSE</filename> 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
|
|
<filename>meta/files/common-licenses/</filename>
|
|
or the <filename>SPDXLICENSEMAP</filename> flag names
|
|
defined in <filename>meta/conf/licenses.conf</filename>.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>LIC_FILES_CHKSUM</filename>:</emphasis>
|
|
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.
|
|
</para>
|
|
<para>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
|
|
<filename>LIC_FILES_CHKSUM</filename> variable, see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#usingpoky-configuring-LIC_FILES_CHKSUM'>Tracking License Changes</ulink>"
|
|
section in the Yocto Project Reference Manual.</para>
|
|
<para>To determine the correct checksum string, you
|
|
can list the appropriate files in the
|
|
<filename>LIC_FILES_CHKSUM</filename> variable with
|
|
incorrect md5 strings, attempt to build the software,
|
|
and then note the resulting error messages that will
|
|
report the correct md5 strings.
|
|
Here is an example that assumes the software has a
|
|
<filename>COPYING</filename> file:
|
|
<literallayout class='monospaced'>
|
|
LIC_FILES_CHKSUM = "file://COPYING;md5=xxx"
|
|
</literallayout>
|
|
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.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<!--
|
|
|
|
<para>
|
|
For trying this out I created a new recipe named
|
|
<filename>htop_1.0.2.bb</filename> and put it in
|
|
<filename>poky/meta/recipes-extended/htop</filename>.
|
|
There are two license type statements in my very simple
|
|
recipe:
|
|
<literallayout class='monospaced'>
|
|
LICENSE = ""
|
|
|
|
LIC_FILES_CHKSUM = ""
|
|
|
|
SRC_URI[md5sum] = ""
|
|
SRC_URI[sha256sum] = ""
|
|
</literallayout>
|
|
Evidently, you need to run a <filename>bitbake -c cleanall htop</filename>.
|
|
Next, you delete or comment out the two <filename>SRC_URI</filename>
|
|
lines at the end and then attempt to build the software with
|
|
<filename>bitbake htop</filename>.
|
|
Doing so causes BitBake to report some errors and and give
|
|
you the actual strings you need for the last two
|
|
<filename>SRC_URI</filename> lines.
|
|
Prior to this, you have to dig around in the home page of the
|
|
source for <filename>htop</filename> and determine that the
|
|
software is released under GPLv2.
|
|
You can provide that in the <filename>LICENSE</filename>
|
|
statement.
|
|
Now you edit your recipe to have those two strings for
|
|
the <filename>SRC_URI</filename> statements:
|
|
<literallayout class='monospaced'>
|
|
LICENSE = "GPLv2"
|
|
|
|
LIC_FILES_CHKSUM = ""
|
|
|
|
SRC_URI = "${SOURCEFORGE_MIRROR}/htop/htop-${PV}.tar.gz"
|
|
SRC_URI[md5sum] = "0d01cca8df3349c74569cefebbd9919e"
|
|
SRC_URI[sha256sum] = "ee60657b044ece0df096c053060df7abf3cce3a568ab34d260049e6a37ccd8a1"
|
|
</literallayout>
|
|
At this point, you can build the software again using the
|
|
<filename>bitbake htop</filename> command.
|
|
There is just a set of errors now associated with the
|
|
empty <filename>LIC_FILES_CHKSUM</filename> variable now.
|
|
</para>
|
|
-->
|
|
|
|
</section>
|
|
|
|
<section id='new-recipe-configuring-the-recipe'>
|
|
<title>Configuring the Recipe</title>
|
|
|
|
<para>
|
|
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 some options, or by modifying a build
|
|
configuration file.
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
The following list provides configuration items of note based
|
|
on how your software is built:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Autotools:</emphasis>
|
|
If your source files have a
|
|
<filename>configure.ac</filename> file, then your
|
|
software is built using Autotools.
|
|
If this is the case, you just need to worry about
|
|
tweaking the configuration.</para>
|
|
<para>When using Autotools, your recipe needs to inherit
|
|
the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-autotools'><filename>autotools</filename></ulink>
|
|
class and your recipe does not have to contain a
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-configure'><filename>do_configure</filename></ulink>
|
|
task.
|
|
However, you might still want to make some adjustments.
|
|
For example, you can set
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OECONF'><filename>EXTRA_OECONF</filename></ulink>
|
|
to pass any needed configure options that are specific
|
|
to the recipe.</para></listitem>
|
|
<listitem><para><emphasis>CMake:</emphasis>
|
|
If your source files have a
|
|
<filename>CMakeLists.txt</filename> file, then your
|
|
software is built using CMake.
|
|
If this is the case, you just need to worry about
|
|
tweaking the configuration.</para>
|
|
<para>When you use CMake, your recipe needs to inherit
|
|
the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-cmake'><filename>cmake</filename></ulink>
|
|
class and your recipe does not have to contain a
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-configure'><filename>do_configure</filename></ulink>
|
|
task.
|
|
You can make some adjustments by setting
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OECMAKE'><filename>EXTRA_OECMAKE</filename></ulink>
|
|
to pass any needed configure options that are specific
|
|
to the recipe.</para></listitem>
|
|
<listitem><para><emphasis>Other:</emphasis>
|
|
If your source files do not have a
|
|
<filename>configure.ac</filename> or
|
|
<filename>CMakeLists.txt</filename> 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
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-configure'><filename>do_configure</filename></ulink>
|
|
task in your recipe
|
|
unless, of course, there is nothing to configure.
|
|
</para>
|
|
<para>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.</para>
|
|
<para>For the case involving a custom configure
|
|
script, you would run
|
|
<filename>./configure ‐‐help</filename> and look for
|
|
the options you need to set.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Once configuration succeeds, it is always good practice to
|
|
look at the <filename>log.do_configure</filename> file to
|
|
ensure that the appropriate options have been enabled and no
|
|
additional build-time dependencies need to be added to
|
|
<filename>DEPENDS</filename>.
|
|
For example, if the configure script reports that it found
|
|
something not mentioned in <filename>DEPENDS</filename>, or
|
|
that it did not find something that it needed for some
|
|
desired optional functionality, then you would need to add
|
|
those to <filename>DEPENDS</filename>.
|
|
Looking at the log might also reveal items being checked for
|
|
and/or enabled that you do not want, or items not being found
|
|
that are in <filename>DEPENDS</filename>, 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
|
|
<filename>./configure ‐‐help</filename> command within
|
|
<filename>${S}</filename> or consult the software's upstream
|
|
documentation.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-compilation'>
|
|
<title>Compilation</title>
|
|
|
|
<para>
|
|
During a build, the <filename>do_compile</filename> task
|
|
happens after source is fetched, unpacked, and configured.
|
|
If the recipe passes through <filename>do_compile</filename>
|
|
successfully, nothing needs to be done.
|
|
</para>
|
|
|
|
<para>
|
|
However, if the compile step fails, you need to diagnose the
|
|
failure.
|
|
Here are some common issues that cause failures:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Parallel build failures:</emphasis>
|
|
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.</para>
|
|
<para>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
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKE'><filename>PARALLEL_MAKE</filename></ulink>
|
|
to an empty string:
|
|
<literallayout class='monospaced'>
|
|
PARALLEL_MAKE = ""
|
|
</literallayout></para></listitem>
|
|
<listitem><para><emphasis>Improper host path usage:</emphasis>
|
|
This failure applies to recipes building for the target
|
|
or <filename>nativesdk</filename> 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.
|
|
</para>
|
|
<para>To fix the problem, examine the
|
|
<filename>log.do_compile</filename> file to identify
|
|
the host paths being used (e.g.
|
|
<filename>/usr/include</filename>,
|
|
<filename>/usr/lib</filename>, and so forth) and then
|
|
either add configure options, apply a patch, or do both.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Failure to find required
|
|
libraries/headers:</emphasis>
|
|
If a build-time dependency is missing because it has
|
|
not been declared in
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>,
|
|
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
|
|
<filename>DEPENDS</filename>.</para>
|
|
<para>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.
|
|
<filename>STAGING_BINDIR</filename>,
|
|
<filename>STAGING_INCDIR</filename>,
|
|
<filename>STAGING_DATADIR</filename>, and so forth).
|
|
<!--
|
|
(e.g.
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-STAGING_BINDIR'><filename>STAGING_BINDIR</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-STAGING_INCDIR'><filename>STAGING_INCDIR</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-STAGING_DATADIR'><filename>STAGING_DATADIR</filename></ulink>,
|
|
and so forth).
|
|
-->
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-installing'>
|
|
<title>Installing</title>
|
|
|
|
<para>
|
|
During <filename>do_install</filename>, 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
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-S'><filename>S</filename></ulink><filename>}</filename>,
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-B'><filename>B</filename></ulink><filename>}</filename>,
|
|
and
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-WORKDIR'><filename>WORKDIR</filename></ulink><filename>}</filename>
|
|
directories to the
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-D'><filename>D</filename></ulink><filename>}</filename>
|
|
directory to create the structure as it should appear on the
|
|
target system.
|
|
</para>
|
|
|
|
<para>
|
|
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:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Autotools and CMake:</emphasis>
|
|
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
|
|
<filename>do_install</filename> 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
|
|
<filename>make install</filename>, you should do this
|
|
using a <filename>do_install_append</filename> function
|
|
using the install command as described in
|
|
<emphasis>Manual</emphasis> later in this list.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Other (using
|
|
<filename>make install</filename>):</emphasis>
|
|
You need to define a
|
|
<filename>do_install</filename> function in your
|
|
recipe.
|
|
The function should call
|
|
<filename>oe_runmake install</filename> and will likely
|
|
need to pass in the destination directory as well.
|
|
How you pass that path is dependent on how the
|
|
<filename>Makefile</filename> being run is written
|
|
(e.g. <filename>DESTDIR=${D}</filename>,
|
|
<filename>PREFIX=${D}</filename>,
|
|
<filename>INSTALLROOT=${D}</filename>, and so forth).
|
|
</para>
|
|
<para>For an example recipe using
|
|
<filename>make install</filename>, see the
|
|
"<link linkend='new-recipe-makefile-based-package'>Makefile-Based Package</link>"
|
|
section.</para></listitem>
|
|
<listitem><para><emphasis>Manual:</emphasis>
|
|
You need to define a
|
|
<filename>do_install</filename> function in your
|
|
recipe.
|
|
The function must first use
|
|
<filename>install -d</filename> to create the
|
|
directories under
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-D'><filename>D</filename></ulink><filename>}</filename>.
|
|
Once the directories exist, your function can use
|
|
<filename>install</filename> to manually install the
|
|
built software into the directories.</para>
|
|
<para>You can find more information on
|
|
<filename>install</filename> at
|
|
<ulink url='http://www.gnu.org/software/coreutils/manual/html_node/install-invocation.html'></ulink>.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<filename>${D}</filename>, which is
|
|
<filename>${WORKDIR}/image</filename>, to be sure your
|
|
files have been installed correctly.
|
|
</para>
|
|
|
|
<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 <filename>/usr/bin/</filename> with
|
|
<filename>${bindir}</filename>.
|
|
If you do perform such modifications during
|
|
<filename>do_install</filename>, be sure to modify the
|
|
destination file after copying rather than before copying.
|
|
Modifying after copying ensures that the build system can
|
|
re-execute <filename>do_install</filename> if needed.
|
|
</note>
|
|
|
|
<note>
|
|
<filename>oe_runmake install</filename>, which can be run
|
|
directly or can be run indirectly by the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-autotools'><filename>autotools</filename></ulink>
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-cmake'><filename>cmake</filename></ulink>
|
|
classes, runs <filename>make install</filename> in parallel.
|
|
Sometimes, a Makefile can have missing dependencies between
|
|
targets that can result in race conditions.
|
|
If you experience intermittent failures during
|
|
<filename>do_install</filename>, you might be able to work
|
|
around them by disabling parallel Makefile installs
|
|
by adding the following to the recipe:
|
|
<literallayout class='monospaced'>
|
|
PARALLEL_MAKEINST = ""
|
|
</literallayout>
|
|
See
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKEINST'><filename>PARALLEL_MAKEINST</filename></ulink>
|
|
for additional information.
|
|
</note>
|
|
</section>
|
|
|
|
<section id='new-recipe-enabling-system-services'>
|
|
<title>Enabling System Services</title>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<filename>do_install_append</filename> function.
|
|
If your recipe already has a <filename>do_install</filename>
|
|
function, update the function near its end rather than
|
|
adding an additional <filename>do_install_append</filename>
|
|
function.
|
|
</para>
|
|
|
|
<para>
|
|
When you create the installation for your services, you need
|
|
to accomplish what is normally done by
|
|
<filename>make install</filename>.
|
|
In other words, make sure your installation arranges the output
|
|
similar to how it is arranged on the target system.
|
|
</para>
|
|
|
|
<para>
|
|
The OpenEmbedded build system provides support for starting
|
|
services two different ways:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>SysVinit:</emphasis>
|
|
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.</para>
|
|
<para>To enable a service using SysVinit, your recipe
|
|
needs to inherit the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-update-rc.d'><filename>update-rc.d</filename></ulink>
|
|
class.
|
|
The class helps facilitate safely installing the
|
|
package on the target.</para>
|
|
<para>You will need to set the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-INITSCRIPT_PACKAGES'><filename>INITSCRIPT_PACKAGES</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-INITSCRIPT_NAME'><filename>INITSCRIPT_NAME</filename></ulink>,
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-INITSCRIPT_PARAMS'><filename>INITSCRIPT_PARAMS</filename></ulink>
|
|
variables within your recipe.</para></listitem>
|
|
<listitem><para><emphasis>systemd:</emphasis>
|
|
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
|
|
<ulink url='http://freedesktop.org/wiki/Software/systemd/'></ulink>.
|
|
</para>
|
|
<para>To enable a service using systemd, your recipe
|
|
needs to inherit the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-systemd'><filename>systemd</filename></ulink>
|
|
class.
|
|
See the <filename>systemd.class</filename> file
|
|
located in your
|
|
<link linkend='source-directory'>Source Directory</link>.
|
|
section for more information.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-packaging'>
|
|
<title>Packaging</title>
|
|
|
|
<para>
|
|
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:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Splitting Files</emphasis>:
|
|
The <filename>do_package</filename> 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 <filename>do_package</filename> task ensures
|
|
that files are split up and packaged correctly.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Running QA Checks</emphasis>:
|
|
The <filename>insane</filename> 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
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-insane'><filename>insane</filename></ulink>
|
|
class and the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-qa-checks'>QA Error and Warning Messages</ulink>"
|
|
chapter in the Yocto Project Reference Manual.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Hand-Checking Your Packages</emphasis>:
|
|
After you build your software, you need to be sure
|
|
your packages are correct.
|
|
Examine the
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-WORKDIR'><filename>WORKDIR</filename></ulink><filename>}/packages-split</filename>
|
|
directory and make sure files are where you expect
|
|
them to be.
|
|
If you discover problems, you can set
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'><filename>PACKAGES</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILES'><filename>FILES</filename></ulink>,
|
|
<filename>do_install(_append)</filename>, and so forth as
|
|
needed.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Splitting an Application into Multiple Packages</emphasis>:
|
|
If you need to split an application into several
|
|
packages, see the
|
|
"<link linkend='splitting-an-application-into-multiple-packages'>Splitting an Application into Multiple Packages</link>"
|
|
section for an example.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Installing a Post-Installation Script</emphasis>:
|
|
For an example showing how to install a
|
|
post-installation script, see the
|
|
"<link linkend='new-recipe-post-installation-scripts'>Post-Installation Scripts</link>"
|
|
section.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Marking Package Architecture</emphasis>:
|
|
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 produced for the target are
|
|
marked as being specific to the architecture of the
|
|
target machine because that is usually the desired
|
|
result.
|
|
However, if the recipe configures the software to be
|
|
built specific to the target machine (e.g. the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
value is passed into the configure script or a patch
|
|
is applied only for a particular machine), then you
|
|
should mark the packages produced as being
|
|
machine-specific by adding the following to the
|
|
recipe:
|
|
<literallayout class='monospaced'>
|
|
PACKAGE_ARCH = "${MACHINE_ARCH}"
|
|
</literallayout>
|
|
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
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#allarch'><filename>allarch</filename></ulink>
|
|
class to do this for you by adding this to your
|
|
recipe:
|
|
<literallayout class='monospaced'>
|
|
inherit allarch
|
|
</literallayout>
|
|
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
|
|
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.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='properly-versioning-pre-release-recipes'>
|
|
<title>Properly Versioning Pre-Release Recipes</title>
|
|
|
|
<para>
|
|
Sometimes the name of a recipe can lead to versioning
|
|
problems when the recipe is upgraded to a final release.
|
|
For example, consider the
|
|
<filename>irssi_0.8.16-rc1.bb</filename> recipe file in
|
|
the list of example recipes in the
|
|
"<link linkend='new-recipe-storing-and-naming-the-recipe'>Storing and Naming the Recipe</link>"
|
|
section.
|
|
This recipe is at a release candidate stage (i.e.
|
|
"rc1").
|
|
When the recipe is released, the recipe filename becomes
|
|
<filename>irssi_0.8.16.bb</filename>.
|
|
The version change from <filename>0.8.16-rc1</filename>
|
|
to <filename>0.8.16</filename> is seen as a decrease by the
|
|
build system and package managers, so the resulting packages
|
|
will not correctly trigger an upgrade.
|
|
</para>
|
|
|
|
<para>
|
|
In order to ensure the versions compare properly, the
|
|
recommended convention is to set
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>
|
|
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:
|
|
<literallayout class='monospaced'>
|
|
REALPV = "0.8.16-rc1"
|
|
PV = "0.8.15+${REALPV}"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-post-installation-scripts'>
|
|
<title>Post-Installation Scripts</title>
|
|
|
|
<para>
|
|
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
|
|
<filename>pkg_postinst_PACKAGENAME()</filename> function to
|
|
the recipe file (<filename>.bb</filename>) and replace
|
|
<filename>PACKAGENAME</filename> with the name of the package
|
|
you want to attach to the <filename>postinst</filename>
|
|
script.
|
|
To apply the post-installation script to the main package
|
|
for the recipe, which is usually what is required, specify
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink><filename>}</filename>
|
|
in place of <filename>PACKAGENAME</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
A post-installation function has the following structure:
|
|
<literallayout class='monospaced'>
|
|
pkg_postinst_PACKAGENAME () {
|
|
#!/bin/sh -e
|
|
# Commands to carry out
|
|
}
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
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.
|
|
If the script fails, the package is marked as unpacked and
|
|
the script is executed when the image boots again.
|
|
</para>
|
|
|
|
<para>
|
|
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, use the following
|
|
structure in the post-installation script:
|
|
<literallayout class='monospaced'>
|
|
pkg_postinst_PACKAGENAME () {
|
|
#!/bin/sh -e
|
|
if [ x"$D" = "x" ]; then
|
|
# Actions to carry out on the device go here
|
|
else
|
|
exit 1
|
|
fi
|
|
}
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
The previous example delays execution until the image boots
|
|
again because the environment variable <filename>D</filename>
|
|
points to the directory containing the image when
|
|
the root filesystem is created at build time but is unset
|
|
when executed on the first boot.
|
|
</para>
|
|
|
|
<note>
|
|
Equivalent support for pre-install, pre-uninstall, and
|
|
post-uninstall scripts exist by way of
|
|
<filename>pkg_preinst</filename>,
|
|
<filename>pkg_prerm</filename>, and
|
|
<filename>pkg_postrm</filename>, respectively.
|
|
These scrips work in exactly the same way as does
|
|
<filename>pkg_postinst</filename> 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
|
|
<filename>pkg_postinst</filename>.
|
|
</note>
|
|
</section>
|
|
|
|
<section id='new-recipe-testing'>
|
|
<title>Testing</title>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
For information on how to customize your image by adding
|
|
specific packages, see the
|
|
"<link linkend='usingpoky-extend-customimage'>Customizing Images</link>"
|
|
section.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-testing-examples'>
|
|
<title>Examples</title>
|
|
|
|
<para>
|
|
To help summarize how to write a recipe, this section provides
|
|
some examples given various scenarios:
|
|
<itemizedlist>
|
|
<listitem><para>Recipes that use local files</para></listitem>
|
|
<listitem><para>Using an Autotooled package</para></listitem>
|
|
<listitem><para>Using a Makefile-based package</para></listitem>
|
|
<listitem><para>Splitting an application into multiple packages</para></listitem>
|
|
<listitem><para>Adding binaries to an image</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<section id='new-recipe-single-c-file-package-hello-world'>
|
|
<title>Single .c File Package (Hello World!)</title>
|
|
|
|
<para>
|
|
Building an application from a single file that is stored
|
|
locally (e.g. under <filename>files/</filename>) requires
|
|
a recipe that has the file listed in the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'>SRC_URI</ulink></filename>
|
|
variable.
|
|
Additionally, you need to manually write the
|
|
<filename>do_compile</filename> and
|
|
<filename>do_install</filename> tasks.
|
|
The <filename><ulink url='&YOCTO_DOCS_REF_URL;#var-S'>S</ulink></filename>
|
|
variable defines the directory containing the source code,
|
|
which is set to
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-WORKDIR'><filename>WORKDIR</filename></ulink>
|
|
in this case - the directory BitBake uses for the build.
|
|
<literallayout class='monospaced'>
|
|
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} helloworld.c -o helloworld
|
|
}
|
|
|
|
do_install() {
|
|
install -d ${D}${bindir}
|
|
install -m 0755 helloworld ${D}${bindir}
|
|
}
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
By default, the <filename>helloworld</filename>,
|
|
<filename>helloworld-dbg</filename>, and
|
|
<filename>helloworld-dev</filename> packages are built.
|
|
For information on how to customize the packaging process,
|
|
see the
|
|
"<link linkend='splitting-an-application-into-multiple-packages'>Splitting an Application into Multiple Packages</link>"
|
|
section.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-autotooled-package'>
|
|
<title>Autotooled Package</title>
|
|
<para>
|
|
Applications that use Autotools such as <filename>autoconf</filename> and
|
|
<filename>automake</filename> require a recipe that has a source archive listed in
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'>SRC_URI</ulink></filename> and
|
|
also inherit the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-autotools'><filename>autotools</filename></ulink>
|
|
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: (<filename>hello_2.3.bb</filename>)
|
|
<literallayout class='monospaced'>
|
|
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
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
The variable
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-LIC_FILES_CHKSUM'>LIC_FILES_CHKSUM</ulink></filename>
|
|
is used to track source license changes as described in the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#usingpoky-configuring-LIC_FILES_CHKSUM'>Tracking License Changes</ulink>" section.
|
|
You can quickly create Autotool-based recipes in a manner similar to the previous example.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='new-recipe-makefile-based-package'>
|
|
<title>Makefile-Based Package</title>
|
|
|
|
<para>
|
|
Applications that use GNU <filename>make</filename> also require a recipe that has
|
|
the source archive listed in
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'>SRC_URI</ulink></filename>.
|
|
You do not need to add a <filename>do_compile</filename> step since by default BitBake
|
|
starts the <filename>make</filename> command to compile the application.
|
|
If you need additional <filename>make</filename> options, you should store them in the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OEMAKE'>EXTRA_OEMAKE</ulink></filename>
|
|
variable.
|
|
BitBake passes these options into the <filename>make</filename> GNU invocation.
|
|
Note that a <filename>do_install</filename> task is still required.
|
|
Otherwise, BitBake runs an empty <filename>do_install</filename> task by default.
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-CFLAGS'>CFLAGS</ulink></filename> variable.
|
|
The following example shows this:
|
|
<literallayout class='monospaced'>
|
|
CFLAGS_prepend = "-I ${S}/include "
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
In the following example, <filename>mtd-utils</filename> is a makefile-based package:
|
|
<literallayout class='monospaced'>
|
|
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"
|
|
|
|
SRC_URI = "git://git.infradead.org/mtd-utils.git;protocol=git;tag=995cfe51b0a3cf32f381c140bf72b21bf91cef1b \
|
|
file://add-exclusion-to-mkfs-jffs2-git-2.patch"
|
|
|
|
S = "${WORKDIR}/git/"
|
|
|
|
PR = "r1"
|
|
|
|
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}
|
|
install -d ${D}${includedir}/mtd/
|
|
for f in ${S}/include/mtd/*.h; do
|
|
install -m 0644 $f ${D}${includedir}/mtd/
|
|
done
|
|
}
|
|
|
|
PARALLEL_MAKE = ""
|
|
|
|
BBCLASSEXTEND = "native"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='splitting-an-application-into-multiple-packages'>
|
|
<title>Splitting an Application into Multiple Packages</title>
|
|
|
|
<para>
|
|
You can use the variables
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'>PACKAGES</ulink></filename> and
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-FILES'>FILES</ulink></filename>
|
|
to split an application into multiple packages.
|
|
</para>
|
|
|
|
<para>
|
|
Following is an example that uses the <filename>libxpm</filename> 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:
|
|
<literallayout class='monospaced'>
|
|
require xorg-lib-common.inc
|
|
|
|
SUMMARY = "X11 Pixmap library"
|
|
LICENSE = "X-BSD"
|
|
LIC_FILES_CHKSUM = "file://COPYING;md5=3e07763d16963c3af12db271a31abaa5"
|
|
DEPENDS += "libxext libsm libxt"
|
|
PR = "r3"
|
|
PE = "1"
|
|
|
|
XORG_PN = "libXpm"
|
|
|
|
PACKAGES =+ "sxpm cxpm"
|
|
FILES_cxpm = "${bindir}/cxpm"
|
|
FILES_sxpm = "${bindir}/sxpm"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
In the previous example, we want to ship the <filename>sxpm</filename>
|
|
and <filename>cxpm</filename> binaries in separate packages.
|
|
Since <filename>bindir</filename> would be packaged into the main
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PN'>PN</ulink></filename>
|
|
package by default, we prepend the <filename>PACKAGES</filename>
|
|
variable so additional package names are added to the start of list.
|
|
This results in the extra <filename>FILES_*</filename>
|
|
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 <filename>PN</filename> package
|
|
does not include the above listed files.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='packaging-externally-produced-binaries'>
|
|
<title>Packaging Externally Produced Binaries</title>
|
|
|
|
<para>
|
|
Sometimes, you need to add pre-compiled binaries to an
|
|
image.
|
|
For example, suppose that binaries for proprietary code
|
|
exist, which are 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
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
and then compile it.
|
|
</para>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
The easiest solution is to create a recipe that uses
|
|
the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-bin-package'><filename>bin_package</filename></ulink>
|
|
class and to be sure that you are using default locations
|
|
for build artifacts.
|
|
In most cases, the <filename>bin_package</filename> 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 <filename>noexec</filename>
|
|
on both the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-configure'><filename>do_configure</filename></ulink>
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-compile'><filename>do_compile</filename></ulink>
|
|
tasks, sets
|
|
<filename>FILES_${PN}</filename> to "/" so that it picks
|
|
up all files, and sets up a
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-install'><filename>do_install</filename></ulink>
|
|
task, which effectively copies all files from
|
|
<filename>${S}</filename> to <filename>${D}</filename>.
|
|
For more information on these variables, see the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FILES'><filename>FILES</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-S'><filename>S</filename></ulink>,
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-D'><filename>D</filename></ulink>
|
|
variables in the Yocto Project Reference Manual's variable
|
|
glossary.
|
|
</para>
|
|
|
|
<para>
|
|
If you can't use the <filename>bin_package</filename>
|
|
class, you need to be sure you are doing the following:
|
|
<itemizedlist>
|
|
<listitem><para>Create a recipe where the
|
|
<filename>do_configure</filename> and
|
|
<filename>do_compile</filename> tasks do nothing:
|
|
<literallayout class='monospaced'>
|
|
do_configure[noexec] = "1"
|
|
do_compile[noexec] = "1"
|
|
</literallayout>
|
|
Alternatively, you can make these tasks an empty
|
|
function.
|
|
</para></listitem>
|
|
<listitem><para>make sure your
|
|
<filename>do_install</filename> task installs the
|
|
binaries appropriately.
|
|
</para></listitem>
|
|
<listitem><para>Ensure that you set up
|
|
<filename>FILES</filename> (usually
|
|
<filename>FILES_${PN}</filename>) 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.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="platdev-newmachine">
|
|
<title>Adding a New Machine</title>
|
|
|
|
<para>
|
|
Adding a new machine to the Yocto Project is a straight forward
|
|
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 <filename>gcc/eglibc</filename> and to the site
|
|
information, which is beyond the scope of this manual.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
For a complete example that shows how to add a new machine,
|
|
see the
|
|
"<ulink url='&YOCTO_DOCS_BSP_URL;#creating-a-new-bsp-layer-using-the-yocto-bsp-script'>Creating a New BSP Layer Using the yocto-bsp Script</ulink>"
|
|
section in the Yocto Project Board Support Package (BSP) Developer's Guide.
|
|
</para>
|
|
|
|
<section id="platdev-newmachine-conffile">
|
|
<title>Adding the Machine Configuration File</title>
|
|
|
|
<para>
|
|
To add a new machine, you need to add a new machine
|
|
configuration file to the layer's
|
|
<filename>conf/machine</filename> directory.
|
|
This configuration file provides details about the device
|
|
you are adding.
|
|
</para>
|
|
|
|
<para>
|
|
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
|
|
<filename>crownbay.conf</filename>, the build system
|
|
recognizes the machine as "crownbay".
|
|
</para>
|
|
|
|
<para>
|
|
The most important variables you must set in your machine
|
|
configuration file are as follows:
|
|
<itemizedlist>
|
|
<listitem><para><filename><ulink url='&YOCTO_DOCS_REF_URL;#var-TARGET_ARCH'>TARGET_ARCH</ulink></filename>
|
|
(e.g. "arm")</para></listitem>
|
|
<listitem><para><filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PREFERRED_PROVIDER'>PREFERRED_PROVIDER</ulink>_virtual/kernel</filename>
|
|
(see below)</para></listitem>
|
|
<listitem><para><filename><ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE_FEATURES'>MACHINE_FEATURES</ulink></filename>
|
|
(e.g. "apm screen wifi")</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
You might also need these variables:
|
|
<itemizedlist>
|
|
<listitem><para><filename><ulink url='&YOCTO_DOCS_REF_URL;#var-SERIAL_CONSOLES'>SERIAL_CONSOLES</ulink></filename>
|
|
(e.g. "115200;ttyS0 115200;ttyS1")</para></listitem>
|
|
<listitem><para><filename><ulink url='&YOCTO_DOCS_REF_URL;#var-KERNEL_IMAGETYPE'>KERNEL_IMAGETYPE</ulink></filename>
|
|
(e.g. "zImage")</para></listitem>
|
|
<listitem><para><filename><ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FSTYPES'>IMAGE_FSTYPES</ulink></filename>
|
|
(e.g. "tar.gz jffs2")</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
You can find full details on these variables in the reference
|
|
section.
|
|
You can leverage existing machine <filename>.conf</filename>
|
|
files from <filename>meta-yocto-bsp/conf/machine/</filename>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-newmachine-kernel">
|
|
<title>Adding a Kernel for the Machine</title>
|
|
|
|
<para>
|
|
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
|
|
<filename>meta/recipes-kernel/linux</filename>
|
|
that you can use as references.
|
|
</para>
|
|
|
|
<para>
|
|
If you are creating a new kernel recipe, normal recipe-writing
|
|
rules apply for setting up a
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'>SRC_URI</ulink></filename>.
|
|
Thus, you need to specify any necessary patches and set
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-S'>S</ulink></filename>
|
|
to point at the source code.
|
|
You need to create a <filename>do_configure</filename> task that
|
|
configures the unpacked kernel with a
|
|
<filename>defconfig</filename> file.
|
|
You can do this by using a <filename>make defconfig</filename>
|
|
command or, more commonly, by copying in a suitable
|
|
<filename>defconfig</filename> file and then running
|
|
<filename>make oldconfig</filename>.
|
|
By making use of <filename>inherit kernel</filename> and
|
|
potentially some of the <filename>linux-*.inc</filename> files,
|
|
most other functionality is centralized and the defaults of the
|
|
class normally work well.
|
|
</para>
|
|
|
|
<para>
|
|
If you are extending an existing kernel recipe, it is usually
|
|
a matter of adding a suitable <filename>defconfig</filename>
|
|
file.
|
|
The file needs to be added into a location similar to
|
|
<filename>defconfig</filename> files used for other machines
|
|
in a given kernel recipe.
|
|
A possible way to do this is by listing the file in the
|
|
<filename>SRC_URI</filename> and adding the machine to the
|
|
expression in
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-COMPATIBLE_MACHINE'>COMPATIBLE_MACHINE</ulink></filename>:
|
|
<literallayout class='monospaced'>
|
|
COMPATIBLE_MACHINE = '(qemux86|qemumips)'
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-newmachine-formfactor">
|
|
<title>Adding a Formfactor Configuration File</title>
|
|
|
|
<para>
|
|
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.
|
|
</para>
|
|
|
|
<para>
|
|
The build system uses reasonable defaults in most cases.
|
|
However, if customization is
|
|
necessary, you need to create a <filename>machconfig</filename> file
|
|
in the <filename>meta/recipes-bsp/formfactor/files</filename>
|
|
directory.
|
|
This directory contains directories for specific machines such as
|
|
<filename>qemuarm</filename> and <filename>qemux86</filename>.
|
|
For information about the settings available and the defaults, see the
|
|
<filename>meta/recipes-bsp/formfactor/files/config</filename> file found in the
|
|
same area.
|
|
</para>
|
|
|
|
<para>
|
|
Following is an example for "qemuarm" machine:
|
|
<literallayout class='monospaced'>
|
|
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
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="platdev-working-with-libraries">
|
|
<title>Working With Libraries</title>
|
|
|
|
<para>
|
|
Libraries are an integral part of your system.
|
|
This section describes some common practices you might find
|
|
helpful when working with libraries to build your system:
|
|
<itemizedlist>
|
|
<listitem><para><link linkend='including-static-library-files'>How to include static library files</link>
|
|
</para></listitem>
|
|
<listitem><para><link linkend='combining-multiple-versions-library-files-into-one-image'>How to use the Multilib feature to combine multiple versions of library files into a single image</link>
|
|
</para></listitem>
|
|
<listitem><para><link linkend='installing-multiple-versions-of-the-same-library'>How to install multiple versions of the same library in parallel on the same system</link>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<section id='including-static-library-files'>
|
|
<title>Including Static Library Files</title>
|
|
|
|
<para>
|
|
If you are building a library and the library offers static linking, you can control
|
|
which static library files (<filename>*.a</filename> files) get included in the
|
|
built library.
|
|
</para>
|
|
|
|
<para>
|
|
The <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'><filename>PACKAGES</filename></ulink>
|
|
and <ulink url='&YOCTO_DOCS_REF_URL;#var-FILES'><filename>FILES_*</filename></ulink>
|
|
variables in the
|
|
<filename>meta/conf/bitbake.conf</filename> configuration file define how files installed
|
|
by the <filename>do_install</filename> task are packaged.
|
|
By default, the <filename>PACKAGES</filename> variable contains
|
|
<filename>${PN}-staticdev</filename>, which includes all static library files.
|
|
<note>
|
|
Some previously released versions of the Yocto Project
|
|
defined the static library files through
|
|
<filename>${PN}-dev</filename>.
|
|
</note>
|
|
Following, is part of the BitBake configuration file.
|
|
You can see where the static library files are defined:
|
|
<literallayout class='monospaced'>
|
|
PACKAGES = "${PN}-dbg ${PN} ${PN}-doc ${PN}-dev ${PN}-staticdev ${PN}-locale"
|
|
PACKAGES_DYNAMIC = "${PN}-locale-*"
|
|
FILES = ""
|
|
|
|
FILES_${PN} = "${bindir}/* ${sbindir}/* ${libexecdir}/* ${libdir}/lib*${SOLIBS} \
|
|
${sysconfdir} ${sharedstatedir} ${localstatedir} \
|
|
${base_bindir}/* ${base_sbindir}/* \
|
|
${base_libdir}/*${SOLIBS} \
|
|
${datadir}/${BPN} ${libdir}/${BPN}/* \
|
|
${datadir}/pixmaps ${datadir}/applications \
|
|
${datadir}/idl ${datadir}/omf ${datadir}/sounds \
|
|
${libdir}/bonobo/servers"
|
|
|
|
FILES_${PN}-doc = "${docdir} ${mandir} ${infodir} ${datadir}/gtk-doc \
|
|
${datadir}/gnome/help"
|
|
SECTION_${PN}-doc = "doc"
|
|
|
|
FILES_${PN}-dev = "${includedir} ${libdir}/lib*${SOLIBSDEV} ${libdir}/*.la \
|
|
${libdir}/*.o ${libdir}/pkgconfig ${datadir}/pkgconfig \
|
|
${datadir}/aclocal ${base_libdir}/*.o"
|
|
SECTION_${PN}-dev = "devel"
|
|
ALLOW_EMPTY_${PN}-dev = "1"
|
|
RDEPENDS_${PN}-dev = "${PN} (= ${EXTENDPKGV})"
|
|
|
|
FILES_${PN}-staticdev = "${libdir}/*.a ${base_libdir}/*.a"
|
|
SECTION_${PN}-staticdev = "devel"
|
|
RDEPENDS_${PN}-staticdev = "${PN}-dev (= ${EXTENDPKGV})"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="combining-multiple-versions-library-files-into-one-image">
|
|
<title>Combining Multiple Versions of Library Files into One Image</title>
|
|
|
|
<para>
|
|
The build system offers the ability to build libraries with different
|
|
target optimizations or architecture formats and combine these together
|
|
into one system image.
|
|
You can link different binaries in the image
|
|
against the different libraries as needed for specific use cases.
|
|
This feature is called "Multilib."
|
|
</para>
|
|
|
|
<para>
|
|
An example would be where you have most of a system compiled in 32-bit
|
|
mode using 32-bit libraries, but you have something large, like a database
|
|
engine, that needs to be a 64-bit application and uses 64-bit libraries.
|
|
Multilib allows you to get the best of both 32-bit and 64-bit libraries.
|
|
</para>
|
|
|
|
<para>
|
|
While the Multilib feature is most commonly used for 32 and 64-bit differences,
|
|
the approach the build system uses facilitates different target optimizations.
|
|
You could compile some binaries to use one set of libraries and other binaries
|
|
to use other different sets of libraries.
|
|
The libraries could differ in architecture, compiler options, or other
|
|
optimizations.
|
|
</para>
|
|
|
|
<para>
|
|
This section overviews the Multilib process only.
|
|
For more details on how to implement Multilib, see the
|
|
<ulink url='&YOCTO_WIKI_URL;/wiki/Multilib'>Multilib</ulink> wiki
|
|
page.
|
|
</para>
|
|
|
|
<para>
|
|
Aside from this wiki page, several examples exist in the
|
|
<filename>meta-skeleton</filename> layer found in the
|
|
<link linkend='source-directory'>Source Directory</link>:
|
|
<itemizedlist>
|
|
<listitem><para><filename>conf/multilib-example.conf</filename>
|
|
configuration file</para></listitem>
|
|
<listitem><para><filename>conf/multilib-example2.conf</filename>
|
|
configuration file</para></listitem>
|
|
<listitem><para><filename>recipes-multilib/images/core-image-multilib-example.bb</filename>
|
|
recipe</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<section id='preparing-to-use-multilib'>
|
|
<title>Preparing to Use Multilib</title>
|
|
|
|
<para>
|
|
User-specific requirements drive the Multilib feature.
|
|
Consequently, there is no one "out-of-the-box" configuration that likely
|
|
exists to meet your needs.
|
|
</para>
|
|
|
|
<para>
|
|
In order to enable Multilib, you first need to ensure your recipe is
|
|
extended to support multiple libraries.
|
|
Many standard recipes are already extended and support multiple libraries.
|
|
You can check in the <filename>meta/conf/multilib.conf</filename>
|
|
configuration file in the
|
|
<link linkend='source-directory'>Source Directory</link> to see how this is
|
|
done using the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBCLASSEXTEND'><filename>BBCLASSEXTEND</filename></ulink>
|
|
variable.
|
|
Eventually, all recipes will be covered and this list will
|
|
not be needed.
|
|
</para>
|
|
|
|
<para>
|
|
For the most part, the Multilib class extension works automatically to
|
|
extend the package name from <filename>${PN}</filename> to
|
|
<filename>${MLPREFIX}${PN}</filename>, where <filename>MLPREFIX</filename>
|
|
is the particular multilib (e.g. "lib32-" or "lib64-").
|
|
Standard variables such as
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-RDEPENDS'><filename>RDEPENDS</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-RPROVIDES'><filename>RPROVIDES</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-RRECOMMENDS'><filename>RRECOMMENDS</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'><filename>PACKAGES</filename></ulink>,
|
|
and <filename>PACKAGES_DYNAMIC</filename> are automatically extended by the system.
|
|
If you are extending any manual code in the recipe, you can use the
|
|
<filename>${MLPREFIX}</filename> variable to ensure those names are extended
|
|
correctly.
|
|
This automatic extension code resides in <filename>multilib.bbclass</filename>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='using-multilib'>
|
|
<title>Using Multilib</title>
|
|
|
|
<para>
|
|
After you have set up the recipes, you need to define the actual
|
|
combination of multiple libraries you want to build.
|
|
You accomplish this through your <filename>local.conf</filename>
|
|
configuration file in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
An example configuration would be as follows:
|
|
<literallayout class='monospaced'>
|
|
MACHINE = "qemux86-64"
|
|
require conf/multilib.conf
|
|
MULTILIBS = "multilib:lib32"
|
|
DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
|
|
IMAGE_INSTALL = "lib32-connman"
|
|
</literallayout>
|
|
This example enables an
|
|
additional library named <filename>lib32</filename> alongside the
|
|
normal target packages.
|
|
When combining these "lib32" alternatives, the example uses "x86" for tuning.
|
|
For information on this particular tuning, see
|
|
<filename>meta/conf/machine/include/ia32/arch-ia32.inc</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
The example then includes <filename>lib32-connman</filename>
|
|
in all the images, which illustrates one method of including a
|
|
multiple library dependency.
|
|
You can use a normal image build to include this dependency,
|
|
for example:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake core-image-sato
|
|
</literallayout>
|
|
You can also build Multilib packages specifically with a command like this:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake lib32-connman
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='additional-implementation-details'>
|
|
<title>Additional Implementation Details</title>
|
|
|
|
<para>
|
|
Different packaging systems have different levels of native Multilib
|
|
support.
|
|
For the RPM Package Management System, the following implementation details
|
|
exist:
|
|
<itemizedlist>
|
|
<listitem><para>A unique architecture is defined for the Multilib packages,
|
|
along with creating a unique deploy folder under
|
|
<filename>tmp/deploy/rpm</filename> in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
For example, consider <filename>lib32</filename> in a
|
|
<filename>qemux86-64</filename> image.
|
|
The possible architectures in the system are "all", "qemux86_64",
|
|
"lib32_qemux86_64", and "lib32_x86".</para></listitem>
|
|
<listitem><para>The <filename>${MLPREFIX}</filename> variable is stripped from
|
|
<filename>${PN}</filename> during RPM packaging.
|
|
The naming for a normal RPM package and a Multilib RPM package in a
|
|
<filename>qemux86-64</filename> system resolves to something similar to
|
|
<filename>bash-4.1-r2.x86_64.rpm</filename> and
|
|
<filename>bash-4.1.r2.lib32_x86.rpm</filename>, respectively.
|
|
</para></listitem>
|
|
<listitem><para>When installing a Multilib image, the RPM backend first
|
|
installs the base image and then installs the Multilib libraries.
|
|
</para></listitem>
|
|
<listitem><para>The build system relies on RPM to resolve the identical files in the
|
|
two (or more) Multilib packages.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
For the IPK Package Management System, the following implementation details exist:
|
|
<itemizedlist>
|
|
<listitem><para>The <filename>${MLPREFIX}</filename> is not stripped from
|
|
<filename>${PN}</filename> during IPK packaging.
|
|
The naming for a normal RPM package and a Multilib IPK package in a
|
|
<filename>qemux86-64</filename> system resolves to something like
|
|
<filename>bash_4.1-r2.x86_64.ipk</filename> and
|
|
<filename>lib32-bash_4.1-rw_x86.ipk</filename>, respectively.
|
|
</para></listitem>
|
|
<listitem><para>The IPK deploy folder is not modified with
|
|
<filename>${MLPREFIX}</filename> because packages with and without
|
|
the Multilib feature can exist in the same folder due to the
|
|
<filename>${PN}</filename> differences.</para></listitem>
|
|
<listitem><para>IPK defines a sanity check for Multilib installation
|
|
using certain rules for file comparison, overridden, etc.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='installing-multiple-versions-of-the-same-library'>
|
|
<title>Installing Multiple Versions of the Same Library</title>
|
|
|
|
<para>
|
|
Situations can exist where you need to install and use
|
|
multiple versions of the same library on the same system
|
|
at the same time.
|
|
These situations almost always exist when a library API
|
|
changes and you have multiple pieces of software that
|
|
depend on the separate versions of the library.
|
|
To accommodate these situations, you can install multiple
|
|
versions of the same library in parallel on the same system.
|
|
</para>
|
|
|
|
<para>
|
|
The process is straight forward as long as the libraries use
|
|
proper versioning.
|
|
With properly versioned libraries, all you need to do to
|
|
individually specify the libraries is create separate,
|
|
appropriately named recipes where the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink> part of the
|
|
name includes a portion that differentiates each library version
|
|
(e.g.the major part of the version number).
|
|
Thus, instead of having a single recipe that loads one version
|
|
of a library (e.g. <filename>clutter</filename>), you provide
|
|
multiple recipes that result in different versions
|
|
of the libraries you want.
|
|
As an example, the following two recipes would allow the
|
|
two separate versions of the <filename>clutter</filename>
|
|
library to co-exist on the same system:
|
|
<literallayout class='monospaced'>
|
|
clutter-1.6_1.6.20.bb
|
|
clutter-1.8_1.8.4.bb
|
|
</literallayout>
|
|
Additionally, if you have other recipes that depend on a given
|
|
library, you need to use the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>
|
|
variable to create the dependency.
|
|
Continuing with the same example, if you want to have a recipe
|
|
depend on the 1.8 version of the <filename>clutter</filename>
|
|
library, use the following in your recipe:
|
|
<literallayout class='monospaced'>
|
|
DEPENDS = "clutter-1.8"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='creating-partitioned-images'>
|
|
<title>Creating Partitioned Images</title>
|
|
|
|
<para>
|
|
Creating an image for a particular hardware target using the
|
|
OpenEmbedded build system does not necessarily mean you can boot
|
|
that image as is on your device.
|
|
Physical devices accept and boot images in various ways depending
|
|
on the specifics of the device.
|
|
Usually, information about the hardware can tell you what image
|
|
format the device requires.
|
|
Should your device require multiple partitions on an SD card, flash,
|
|
or an HDD, you can use the OpenEmbedded Image Creator,
|
|
<filename>wic</filename>, to create the properly partitioned image.
|
|
</para>
|
|
|
|
<para>
|
|
The <filename>wic</filename> command generates partitioned images
|
|
from existing OpenEmbedded build artifacts.
|
|
Image generation is driven by partitioning commands contained
|
|
in an Openembedded kickstart file (<filename>.wks</filename>)
|
|
specified either directly on the command-line or as one of a
|
|
selection of canned <filename>.wks</filename> files as shown
|
|
with the <filename>wic list images</filename> command in the
|
|
"<link linkend='using-a-provided-kickstart_file'>Using an Existing Kickstart File</link>"
|
|
section.
|
|
When applied to a given set of build artifacts, the result is an
|
|
image or set of images that can be directly written onto media and
|
|
used on a particular system.
|
|
</para>
|
|
|
|
<para>
|
|
The <filename>wic</filename> command and the infrastructure
|
|
it is based on is by definition incomplete.
|
|
Its purpose is to allow the generation of customized images,
|
|
and as such was designed to be completely extensible via a
|
|
plugin interface.
|
|
See the
|
|
"<link linkend='openembedded-kickstart-plugins'>Plugins</link>"
|
|
section for information on these plugins.
|
|
</para>
|
|
|
|
<para>
|
|
This section provides some background information on
|
|
<filename>wic</filename>, describes what you need to have in
|
|
place to run the tool, provides instruction on how to use
|
|
<filename>wic</filename>, and provides several examples.
|
|
</para>
|
|
|
|
<section id='wic-background'>
|
|
<title>Background</title>
|
|
|
|
<para>
|
|
This section provides some background on the
|
|
<filename>wic</filename> utility.
|
|
While none of this information is required to use
|
|
<filename>wic</filename>, you might find it interesting.
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
The name "wic" is derived from OpenEmbedded
|
|
Image Creator (oeic).
|
|
The "oe" diphthong in "oeic" was promoted to the
|
|
letter "w", because "oeic" is both difficult to remember and
|
|
pronounce.</para></listitem>
|
|
<listitem><para>
|
|
<filename>wic</filename> is loosely based on the
|
|
Meego Image Creator (<filename>mic</filename>)
|
|
framework.
|
|
The <filename>wic</filename> implementation has been
|
|
heavily modified to make direct use of OpenEmbedded
|
|
build artifacts instead of package installation and
|
|
configuration, which are already incorporated within
|
|
the OpenEmbedded artifacts.</para></listitem>
|
|
<listitem><para>
|
|
<filename>wic</filename> is a completely independent
|
|
standalone utility that initially provides
|
|
easier-to-use and more flexible replacements for a
|
|
couple bits of existing functionality in OE Core's
|
|
<filename>directdisk.bbclass</filename> and
|
|
<filename>mkefidisk.sh</filename> scripts.
|
|
The difference between
|
|
<filename>wic</filename> and those examples is
|
|
that with <filename>wic</filename> the
|
|
functionality of those scripts is implemented
|
|
by a general-purpose partitioning language, which is
|
|
based on Redhat kickstart syntax.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='wic-requirements'>
|
|
<title>Requirements</title>
|
|
|
|
<para>
|
|
In order to use the <filename>wic</filename> utility
|
|
with the OpenEmbedded Build system, your system needs
|
|
to meet the following requirements:
|
|
<itemizedlist>
|
|
<listitem><para>The Linux distribution on your
|
|
development host must support the Yocto Project.
|
|
See the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#detailed-supported-distros'>Supported Linux Distributions</ulink>"
|
|
section in the Yocto Project Reference Manual for this
|
|
list of distributions.</para></listitem>
|
|
<listitem><para>
|
|
The standard system utilities, such as
|
|
<filename>cp</filename>, must be installed on your
|
|
development host system.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
The
|
|
<ulink url='http://www.gnu.org/software/parted/'>GNU Parted</ulink>
|
|
package must be installed on your development host
|
|
system.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
You need to have the build artifacts already
|
|
available, which typically means that you must
|
|
have already created an image using the
|
|
Openembedded build system (e.g.
|
|
<filename>core-image-minimal</filename>).
|
|
While it might seem redundant to generate an image in
|
|
order to create an image using
|
|
<filename>wic</filename>, the current version of
|
|
<filename>wic</filename> requires the artifacts
|
|
in the form generated by the build system.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
You must have sourced one of the build environment
|
|
setup scripts (i.e.
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
|
or
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-memres-core-script'><filename>oe-init-build-env-memres</filename></ulink>)
|
|
found in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='wic-getting-help'>
|
|
<title>Getting Help</title>
|
|
|
|
<para>
|
|
You can get general help for the <filename>wic</filename>
|
|
by entering the <filename>wic</filename> command by itself
|
|
or by entering the command with a help argument as follows:
|
|
<literallayout class='monospaced'>
|
|
$ wic -h
|
|
$ wic ‐‐help
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Currently, <filename>wic</filename> supports two commands:
|
|
<filename>create</filename> and <filename>list</filename>.
|
|
You can get help for these commands as follows:
|
|
<literallayout class='monospaced'>
|
|
$ wic help <command>
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
You can also get detailed help on a number of topics
|
|
from the help system.
|
|
The output of <filename>wic ‐‐help</filename>
|
|
displays a list of available help
|
|
topics under a "Help topics" heading.
|
|
You can have the help system display the help text for
|
|
a given topic by prefacing the topic with
|
|
<filename>wic help</filename>:
|
|
<literallayout class='monospaced'>
|
|
$ wic help <help topic>
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
You can find out more about the images
|
|
<filename>wic</filename> creates using the existing
|
|
kickstart files with the following form of the command:
|
|
<literallayout class='monospaced'>
|
|
$ wic list <image> help
|
|
</literallayout>
|
|
Where <filename><image></filename> is either
|
|
<filename>directdisk</filename> or
|
|
<filename>mkefidisk</filename>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='operational-modes'>
|
|
<title>Operational Modes</title>
|
|
|
|
<para>
|
|
You can use <filename>wic</filename> in two different
|
|
modes, depending on how much control you need for
|
|
specifying the Openembedded build artifacts that are
|
|
used for creating the image: Raw and Cooked:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Raw Mode:</emphasis>
|
|
You explicitly specify build artifacts through
|
|
command-line arguments.</para></listitem>
|
|
<listitem><para><emphasis>Cooked Mode:</emphasis>
|
|
The current
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
setting and image name are used to automatically locate
|
|
and provide the build artifacts.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Regardless of the mode you use, you need to have the build
|
|
artifacts ready and available.
|
|
Additionally, the environment must be set up using the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
|
or
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-memres-core-script'><filename>oe-init-build-env-memres</filename></ulink>
|
|
script found in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
</para>
|
|
|
|
<section id='raw-mode'>
|
|
<title>Raw Mode</title>
|
|
|
|
<para>
|
|
The general form of the 'wic' command in raw mode is:
|
|
<literallayout class='monospaced'>
|
|
$ wic create <replaceable>image_name</replaceable>.wks [<replaceable>options</replaceable>] [...]
|
|
|
|
Where:
|
|
|
|
<replaceable>image_name</replaceable>.wks
|
|
An an OpenEmbedded kickstart file. You can provide
|
|
your own custom file or use a file from a set of
|
|
existing files as described by further options.
|
|
|
|
-o <replaceable>OUTDIR</replaceable>, ‐‐outdir=<replaceable>OUTDIR</replaceable>
|
|
The name of a directory in which to create image.
|
|
|
|
-i <replaceable>PROPERTIES_FILE</replaceable>, ‐‐infile=<replaceable>PROPERTIES_FILE</replaceable>
|
|
The name of a file containing the values for image
|
|
properties as a JSON file.
|
|
|
|
-e <replaceable>IMAGE_NAME</replaceable>, ‐‐image-name=<replaceable>IMAGE_NAME</replaceable>
|
|
The name of the image from which to use the artifacts
|
|
(e.g. <filename>core-image-sato</filename>).
|
|
|
|
-r <replaceable>ROOTFS_DIR</replaceable>, ‐‐rootfs-dir=<replaceable>ROOTFS_DIR</replaceable>
|
|
The path to the <filename>/rootfs</filename> directory to use as the
|
|
<filename>.wks</filename> rootfs source.
|
|
|
|
-b <replaceable>BOOTIMG_DIR</replaceable>, ‐‐bootimg-dir=<replaceable>BOOTIMG_DIR</replaceable>
|
|
The path to the directory containing the boot artifacts
|
|
(e.g. <filename>/EFI</filename> or <filename>/syslinux</filename>) to use as the <filename>.wks</filename> bootimg
|
|
source.
|
|
|
|
-k <replaceable>KERNEL_DIR</replaceable>, ‐‐kernel-dir=<replaceable>KERNEL_DIR</replaceable>
|
|
The path to the directory containing the kernel to use
|
|
in the <filename>.wks</filename> boot image.
|
|
|
|
-n <replaceable>NATIVE_SYSROOT</replaceable>, ‐‐native-sysroot=<replaceable>NATIVE_SYSROOT</replaceable>
|
|
The path to the native sysroot containing the tools to use
|
|
to build the image.
|
|
|
|
-p, ‐‐skip-build-check
|
|
Skips the build check.
|
|
|
|
-D, ‐‐debug
|
|
Output debug information.
|
|
</literallayout>
|
|
<note>
|
|
You do not need root privileges to run
|
|
<filename>wic</filename>.
|
|
In fact, you should not run as root when using the
|
|
utility.
|
|
</note>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='cooked-mode'>
|
|
<title>Cooked Mode</title>
|
|
|
|
<para>
|
|
The general form of the <filename>wic</filename> command
|
|
using Cooked Mode is:
|
|
<literallayout class='monospaced'>
|
|
$ wic create <replaceable>kickstart_file</replaceable> -e <replaceable>image_name</replaceable>
|
|
|
|
Where:
|
|
|
|
<replaceable>kickstart_file</replaceable>
|
|
An OpenEmbedded kickstart file. You can provide your own
|
|
custom file or supplied file.
|
|
|
|
<replaceable>image_name</replaceable>
|
|
Specifies the image built using the OpenEmbedded build
|
|
system.
|
|
</literallayout>
|
|
This form is the simplest and most user-friendly, as it
|
|
does not require specifying all individual parameters.
|
|
All you need to provide is your own
|
|
<filename>.wks</filename> file or one provided with the
|
|
release.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='using-a-provided-kickstart_file'>
|
|
<title>Using an Existing Kickstart File</title>
|
|
|
|
<para>
|
|
If you do not want to create your own
|
|
<filename>.wks</filename> file, you can use an existing
|
|
file provided by the <filename>wic</filename> installation.
|
|
Use the following command to list the available files:
|
|
<literallayout class='monospaced'>
|
|
$ wic list images
|
|
directdisk Create a 'pcbios' direct disk image
|
|
mkefidisk Create an EFI disk image
|
|
</literallayout>
|
|
When you use an existing file, you do not have to use the
|
|
<filename>.wks</filename> extension.
|
|
Here is an example in Raw Mode that uses the
|
|
<filename>directdisk</filename> file:
|
|
<literallayout class='monospaced'>
|
|
$ wic create directdisk -r <replaceable>rootfs_dir</replaceable> -b <replaceable>bootimg_dir</replaceable> \
|
|
-k <replaceable>kernel_dir</replaceable> -n <replaceable>native_sysroot</replaceable>
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Here are the actual partition language commands
|
|
used in the <filename>mkefidisk.wks</filename> file to generate
|
|
an image:
|
|
<literallayout class='monospaced'>
|
|
# short-description: Create an EFI disk image
|
|
# long-description: Creates a partitioned EFI disk image that the user
|
|
# can directly dd to boot media.
|
|
|
|
part /boot ‐‐source bootimg-efi ‐‐ondisk sda ‐‐active
|
|
|
|
part / ‐‐source rootfs ‐‐ondisk sda ‐‐fstype=ext3 ‐‐label platform
|
|
|
|
part swap ‐‐ondisk sda ‐‐size 44 ‐‐label swap1 ‐‐fstype=swap
|
|
|
|
bootloader ‐‐timeout=10 ‐‐append="rootwait console=ttyPCH0,115200"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='wic-usage-examples'>
|
|
<title>Examples</title>
|
|
|
|
<para>
|
|
This section provides several examples that show how to use
|
|
the <filename>wic</filename> utility.
|
|
All the examples assume the list of requirements in the
|
|
"<link linkend='wic-requirements'>Requirements</link>" section
|
|
have been met.
|
|
The examples assume the previously generated image is
|
|
<filename>core-image-minimal</filename>.
|
|
</para>
|
|
|
|
<section id='generate-an-image-using-a-provided-kickstart-file'>
|
|
<title>Generate an Image using an Existing Kickstart File</title>
|
|
|
|
<para>
|
|
This example runs in Cooked Mode and uses the
|
|
<filename>mkefidisk</filename> kickstart file:
|
|
<literallayout class='monospaced'>
|
|
$ wic create mkefidisk -e core-image-minimal
|
|
Checking basic build environment...
|
|
Done.
|
|
|
|
Creating image(s)...
|
|
|
|
Info: The new image(s) can be found here:
|
|
/var/tmp/wic/build/mkefidisk-201310230946-sda.direct
|
|
|
|
The following build artifacts were used to create the image(s):
|
|
ROOTFS_DIR: /home/trz/yocto/yocto-image/build/tmp/work/minnow-poky-linux/core-image-minimal/1.0-r0/rootfs
|
|
BOOTIMG_DIR: /home/trz/yocto/yocto-image/build/tmp/work/minnow-poky-linux/core-image-minimal/1.0-r0/core-image-minimal-1.0/hddimg
|
|
KERNEL_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/minnow/usr/src/kernel
|
|
NATIVE_SYSROOT: /home/trz/yocto/yocto-image/build/tmp/sysroots/x86_64-linux
|
|
|
|
|
|
The image(s) were created using OE kickstart file:
|
|
/home/trz/yocto/yocto-image/scripts/lib/image/canned-wks/mkefidisk.wks
|
|
</literallayout>
|
|
This example shows the easiest way to create an image
|
|
by running in Cooked Mode and using the
|
|
<filename>-e</filename> option with an existing kickstart
|
|
file.
|
|
All that is necessary is to specify the image used to
|
|
generate the artifacts.
|
|
Your <filename>local.conf</filename> needs to have the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
variable set to the machine you are using, which is
|
|
"minnow" in this example.
|
|
</para>
|
|
|
|
<para>
|
|
The output specifies exactly which image was
|
|
created as well as where it was created.
|
|
The output also names the artifacts used and the exact
|
|
<filename>.wks</filename> script that was used to generate
|
|
the image.
|
|
<note>
|
|
You should always verify the details provided in the
|
|
output to make sure that the image was indeed created
|
|
exactly as expected.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
Continuing with the example, you can now directly
|
|
<filename>dd</filename> the image to a USB stick, or
|
|
whatever media for which you built your image,
|
|
and boot the resulting media:
|
|
<literallayout class='monospaced'>
|
|
$ sudo dd if=/var/tmp/wic/build/mkefidisk-201310230946-sda.direct of=/dev/sdb
|
|
[sudo] password for trz:
|
|
182274+0 records in
|
|
182274+0 records out
|
|
93324288 bytes (93 MB) copied, 14.4777 s, 6.4 MB/s
|
|
[trz@empanada ~]$ sudo eject /dev/sdb
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='using-a-modified-kickstart-file'>
|
|
<title>Using a Modified Kickstart File</title>
|
|
|
|
<para>
|
|
Because <filename>wic</filename> image creation is driven
|
|
by the kickstart file, it is easy to affect image creation
|
|
by changing the parameters in the file.
|
|
This next example demonstrates that through modification
|
|
of the <filename>directdisk</filename> kickstart file.
|
|
</para>
|
|
|
|
<para>
|
|
As mentioned earlier, you can use the command
|
|
<filename>wic list images</filename> to show the list
|
|
of existing kickstart files.
|
|
The directory in which these files reside is
|
|
<filename>scripts/lib/image/canned-wks/</filename>
|
|
located in the
|
|
<link linkend='source-directory'>Source Directory</link>.
|
|
Because the available files reside in this directory, you
|
|
can create and add your own custom files to the directory.
|
|
Subsequent use of the <filename>wic list images</filename>
|
|
command would then include your kickstart files.
|
|
</para>
|
|
|
|
<para>
|
|
In this example, the existing
|
|
<filename>directdisk</filename> file already does most
|
|
of what is needed.
|
|
However, for the hardware in this example, the image will
|
|
need to boot from <filename>sdb</filename> instead of
|
|
<filename>sda</filename>, which is what the
|
|
<filename>directdisk</filename> kickstart file uses.
|
|
</para>
|
|
|
|
<para>
|
|
The example begins by making a copy of the
|
|
<filename>directdisk.wks</filename> file in the
|
|
<filename>scripts/lib/image/canned-wks</filename>
|
|
directory and then changing the lines that specify the
|
|
target disk from which to boot.
|
|
<literallayout class='monospaced'>
|
|
$ cp /home/trz/yocto/yocto-image/scripts/lib/image/canned-wks/directdisk.wks \
|
|
/home/trz/yocto/yocto-image/scripts/lib/image/canned-wks/directdisksdb.wks
|
|
</literallayout>
|
|
Next, the example modifies the
|
|
<filename>directdisksdb.wks</filename> file and changes all
|
|
instances of "<filename>‐‐ondisk sda</filename>"
|
|
to "<filename>‐‐ondisk sdb</filename>".
|
|
The example changes the following two lines and leaves the
|
|
remaining lines untouched:
|
|
<literallayout class='monospaced'>
|
|
part /boot ‐‐source bootimg-pcbios ‐‐ondisk sdb ‐‐label boot ‐‐active ‐‐align 1024
|
|
part / ‐‐source rootfs ‐‐ondisk sdb ‐‐fstype=ext3 ‐‐label platform ‐‐align 1024
|
|
</literallayout>
|
|
Once the lines are changed, the example generates the
|
|
<filename>directdisksdb</filename> image.
|
|
The command points the process at the
|
|
<filename>core-image-minimal</filename> artifacts for the
|
|
Next Unit of Computing (nuc)
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
the <filename>local.conf</filename>.
|
|
<literallayout class='monospaced'>
|
|
$ wic create directdisksdb -e core-image-minimal
|
|
Checking basic build environment...
|
|
Done.
|
|
|
|
Creating image(s)...
|
|
|
|
Info: The new image(s) can be found here:
|
|
/var/tmp/wic/build/directdisksdb-201310231131-sdb.direct
|
|
|
|
The following build artifacts were used to create the image(s):
|
|
ROOTFS_DIR: /home/trz/yocto/yocto-image/build/tmp/work/nuc-poky-linux/core-image-minimal/1.0-r0/rootfs
|
|
BOOTIMG_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/nuc/usr/share
|
|
KERNEL_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/nuc/usr/src/kernel
|
|
NATIVE_SYSROOT: /home/trz/yocto/yocto-image/build/tmp/sysroots/x86_64-linux
|
|
|
|
|
|
The image(s) were created using OE kickstart file:
|
|
/home/trz/yocto/yocto-image/scripts/lib/image/canned-wks/directdisksdb.wks
|
|
</literallayout>
|
|
Continuing with the example, you can now directly
|
|
<filename>dd</filename> the image to a USB stick, or
|
|
whatever media for which you built your image,
|
|
and boot the resulting media:
|
|
<literallayout class='monospaced'>
|
|
$ sudo dd if=/var/tmp/wic/build/directdisksdb-201310231131-sdb.direct of=/dev/sdb
|
|
86018+0 records in
|
|
86018+0 records out
|
|
44041216 bytes (44 MB) copied, 13.0734 s, 3.4 MB/s
|
|
[trz@empanada tmp]$ sudo eject /dev/sdb
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-an-image-based-on-core-image-minimal-and-crownbay-noemgd'>
|
|
<title>Creating an Image Based on <filename>core-image-minimal</filename> and <filename>crownbay-noemgd</filename></title>
|
|
|
|
<para>
|
|
This example creates an image based on
|
|
<filename>core-image-minimal</filename> and a
|
|
<filename>crownbay-noemgd</filename>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
that works right out of the box.
|
|
<literallayout class='monospaced'>
|
|
$ wic create directdisk -e core-image-minimal
|
|
|
|
Checking basic build environment...
|
|
Done.
|
|
|
|
Creating image(s)...
|
|
|
|
Info: The new image(s) can be found here:
|
|
/var/tmp/wic/build/directdisk-201309252350-sda.direct
|
|
|
|
The following build artifacts were used to create the image(s):
|
|
|
|
ROOTFS_DIR: /home/trz/yocto/yocto-image/build/tmp/work/crownbay_noemgd-poky-linux/core-image-minimal/1.0-r0/rootfs
|
|
BOOTIMG_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/share
|
|
KERNEL_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/src/kernel
|
|
NATIVE_SYSROOT: /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/src/kernel
|
|
|
|
The image(s) were created using OE kickstart file:
|
|
/home/trz/yocto/yocto-image/scripts/lib/image/canned-wks/directdisk.wks
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='using-a-modified-kickstart-file-and-running-in-raw-mode'>
|
|
<title>Using a Modified Kickstart File and Running in Raw Mode</title>
|
|
|
|
<para>
|
|
This next example manually specifies each build artifact
|
|
(runs in Raw Mode) and uses a modified kickstart file.
|
|
The example also uses the <filename>-o</filename> option
|
|
to cause <filename>wic</filename> to create the output
|
|
somewhere other than the default
|
|
<filename>/var/tmp/wic</filename> directory:
|
|
<literallayout class='monospaced'>
|
|
$ wic create ~/test.wks -o /home/trz/testwic ‐‐rootfs-dir \
|
|
/home/trz/yocto/yocto-image/build/tmp/work/crownbay_noemgd-poky-linux/core-image-minimal/1.0-r0/rootfs \
|
|
‐‐bootimg-dir /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/share \
|
|
‐‐kernel-dir /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/src/kernel \
|
|
‐‐native-sysroot /home/trz/yocto/yocto-image/build/tmp/sysroots/x86_64-linux
|
|
|
|
Creating image(s)...
|
|
|
|
Info: The new image(s) can be found here:
|
|
/home/trz/testwic/build/test-201309260032-sda.direct
|
|
|
|
The following build artifacts were used to create the image(s):
|
|
|
|
ROOTFS_DIR: /home/trz/yocto/yocto-image/build/tmp/work/crownbay_noemgd-poky-linux/core-image-minimal/1.0-r0/rootfs
|
|
BOOTIMG_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/share
|
|
KERNEL_DIR: /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/src/kernel
|
|
NATIVE_SYSROOT: /home/trz/yocto/yocto-image/build/tmp/sysroots/crownbay-noemgd/usr/src/kernel
|
|
|
|
The image(s) were created using OE kickstart file:
|
|
/home/trz/test.wks
|
|
</literallayout>
|
|
For this example,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
did not have to be specified in the
|
|
<filename>local.conf</filename> file since the artifact is
|
|
manually specified.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='openembedded-kickstart-plugins'>
|
|
<title>Plugins</title>
|
|
|
|
<para>
|
|
Plugins allow <filename>wic</filename> functionality to
|
|
be extended and specialized by users.
|
|
This section documents the plugin interface, which is
|
|
currently restricted to source plugins.
|
|
</para>
|
|
|
|
<para>
|
|
Source plugins provide a mechanism to customize
|
|
various aspects of the image generation process in
|
|
<filename>wic</filename>, mainly the contents of
|
|
partitions.
|
|
The plugins provide a mechanism for mapping values
|
|
specified in <filename>.wks</filename> files using the
|
|
<filename>‐‐source</filename> keyword to a
|
|
particular plugin implementation that populates a
|
|
corresponding partition.
|
|
</para>
|
|
|
|
<para>
|
|
A source plugin is created as a subclass of
|
|
<filename>SourcePlugin</filename>.
|
|
The plugin file containing it is added to
|
|
<filename>scripts/lib/mic/plugins/source/</filename> to
|
|
make the plugin implementation available to the
|
|
<filename>wic</filename> implementation.
|
|
For more information, see
|
|
<filename>scripts/lib/mic/pluginbase.py</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Source plugins can also be implemented and added by
|
|
external layers.
|
|
As such, any plugins found in a
|
|
<filename>scripts/lib/mic/plugins/source/</filename>
|
|
directory in an external layer are also made
|
|
available.
|
|
</para>
|
|
|
|
<para>
|
|
When the <filename>wic</filename> implementation needs
|
|
to invoke a partition-specific implementation, it looks
|
|
for the plugin that has the same name as the
|
|
<filename>‐‐source</filename> parameter given to
|
|
that partition.
|
|
For example, if the partition is set up as follows:
|
|
<literallayout class='monospaced'>
|
|
part /boot ‐‐source bootimg-pcbios ...
|
|
</literallayout>
|
|
The methods defined as class members of the plugin
|
|
having the matching <filename>bootimg-pcbios.name</filename>
|
|
class member are used.
|
|
</para>
|
|
|
|
<para>
|
|
To be more concrete, here is the plugin definition that
|
|
matches a
|
|
<filename>'‐‐source bootimg-pcbios'</filename> usage,
|
|
along with an example
|
|
method called by the <filename>wic</filename> implementation
|
|
when it needs to invoke an implementation-specific
|
|
partition-preparation function:
|
|
<literallayout class='monospaced'>
|
|
class BootimgPcbiosPlugin(SourcePlugin):
|
|
name = 'bootimg-pcbios'
|
|
|
|
@classmethod
|
|
def do_prepare_partition(self, part, ...)
|
|
</literallayout>
|
|
If the subclass itself does not implement a function, a
|
|
default version in a superclass is located and
|
|
used, which is why all plugins must be derived from
|
|
<filename>SourcePlugin</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
The <filename>SourcePlugin</filename> class defines the
|
|
following methods, which is the current set of methods
|
|
that can be implemented or overridden by
|
|
<filename>‐‐source</filename> plugins.
|
|
Any methods not implemented by a
|
|
<filename>SourcePlugin</filename> subclass inherit the
|
|
implementations present in the
|
|
<filename>SourcePlugin</filename> class.
|
|
For more information, see the
|
|
<filename>SourcePlugin</filename> source for details:
|
|
</para>
|
|
|
|
<para>
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>do_prepare_partition()</filename>:</emphasis>
|
|
Called to do the actual content population for a
|
|
partition.
|
|
In other words, the method prepares the final
|
|
partition image that is incorporated into the
|
|
disk image.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>do_configure_partition()</filename>:</emphasis>
|
|
Called before
|
|
<filename>do_prepare_partition()</filename>.
|
|
This method is typically used to create custom
|
|
configuration files for a partition (e.g. syslinux or
|
|
grub configuration files).
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>do_install_disk()</filename>:</emphasis>
|
|
Called after all partitions have been prepared and
|
|
assembled into a disk image.
|
|
This method provides a hook to allow finalization of a
|
|
disk image, (e.g. writing an MBR).
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>do_stage_partition()</filename>:</emphasis>
|
|
Special content-staging hook called before
|
|
<filename>do_prepare_partition()</filename>.
|
|
This method is normally empty.</para>
|
|
<para>Typically, a partition just uses the passed-in
|
|
parameters (e.g. the unmodified value of
|
|
<filename>bootimg_dir</filename>).
|
|
However, in some cases things might need to be
|
|
more tailored.
|
|
As an example, certain files might additionally
|
|
need to be taken from
|
|
<filename>bootimg_dir + /boot</filename>.
|
|
This hook allows those files to be staged in a
|
|
customized fashion.
|
|
<note>
|
|
<filename>get_bitbake_var()</filename>
|
|
allows you to access non-standard variables
|
|
that you might want to use for this.
|
|
</note>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
This scheme is extensible.
|
|
Adding more hooks is a simple matter of adding more
|
|
plugin methods to <filename>SourcePlugin</filename> and
|
|
derived classes.
|
|
The code that then needs to call the plugin methods uses
|
|
<filename>plugin.get_source_plugin_methods()</filename>
|
|
to find the method or methods needed by the call.
|
|
Retrieval of those methods is accomplished is accomplished
|
|
by filling up a dict with keys
|
|
containing the method names of interest.
|
|
On success, these will be filled in with the actual
|
|
methods.
|
|
Please see the <filename>wic</filename>
|
|
implementation for examples and details.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='openembedded-kickstart-wks-reference'>
|
|
<title>OpenEmbedded Kickstart (.wks) Reference</title>
|
|
|
|
<para>
|
|
The current <filename>wic</filename> implementation supports
|
|
only the basic kickstart partitioning commands:
|
|
<filename>partition</filename> (or <filename>part</filename>
|
|
for short) and <filename>bootloader</filename>.
|
|
<note>
|
|
Future updates will implement more commands and options.
|
|
If you use anything that is not specifically
|
|
supported, results can be unpredictable.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
The following is a list of the commands, their syntax,
|
|
and meanings.
|
|
The commands are based on the Fedora
|
|
kickstart versions but with modifications to
|
|
reflect <filename>wic</filename> capabilities.
|
|
You can see the original documentation for those commands
|
|
at the following links:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
<ulink url='http://fedoraproject.org/wiki/Anaconda/Kickstart#part_or_partition'>http://fedoraproject.org/wiki/Anaconda/Kickstart#part_or_partition</ulink>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink url='http://fedoraproject.org/wiki/Anaconda/Kickstart#bootloader'>http://fedoraproject.org/wiki/Anaconda/Kickstart#bootloader</ulink>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<section id='command-part-or-partition'>
|
|
<title>Command: part or partition</title>
|
|
|
|
<para>
|
|
This command creates a partition on the system and uses the
|
|
following syntax:
|
|
<literallayout class='monospaced'>
|
|
part <mntpoint>
|
|
</literallayout>
|
|
The <filename><mntpoint></filename> is where the
|
|
partition will be mounted and must be of one of the
|
|
following forms:
|
|
<itemizedlist>
|
|
<listitem><para><filename>/<path></filename>:
|
|
For example, <filename>/</filename>,
|
|
<filename>/usr</filename>, and
|
|
<filename>/home</filename></para></listitem>
|
|
<listitem><para><filename>swap</filename>:
|
|
The partition will be used as swap space.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Following are the supported options:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>‐‐size</filename>:</emphasis>
|
|
The minimum partition size in MBytes.
|
|
Specify an integer value such as 500.
|
|
Do not append the number with "MB".
|
|
You do not need this option if you use
|
|
<filename>‐‐source</filename>.</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐source</filename>:</emphasis>
|
|
This option is a
|
|
<filename>wic</filename>-specific option that
|
|
names the source of the data that populates
|
|
the partition.
|
|
The most common value for this option is
|
|
"rootfs", but you can use any value that maps to
|
|
a valid source plugin.
|
|
For information on the source plugins, see the
|
|
"<link linkend='openembedded-kickstart-plugins'>Plugins</link>"
|
|
section.</para>
|
|
<para>If you use
|
|
<filename>‐‐source rootfs</filename>,
|
|
<filename>wic</filename> creates a partition as
|
|
large as needed and to fill it with the contents of
|
|
the root filesystem pointed to by the
|
|
<filename>-r</filename> command-line option
|
|
or the equivalent rootfs derived from the
|
|
<filename>-e</filename> command-line
|
|
option.
|
|
The filesystem type used to create the
|
|
partition is driven by the value of the
|
|
<filename>‐‐fstype</filename> option
|
|
specified for the partition.
|
|
See the entry on
|
|
<filename>‐‐fstype</filename> that
|
|
follows for more information.
|
|
</para>
|
|
<para>If you use
|
|
<filename>‐‐source <plugin-name></filename>,
|
|
<filename>wic</filename> creates a partition as
|
|
large as needed and fills it with the contents of
|
|
the partition that is generated by the
|
|
specified plugin name using the data pointed
|
|
to by the <filename>-r</filename> command-line
|
|
option or the equivalent rootfs derived from the
|
|
<filename>-e</filename> command-line
|
|
option.
|
|
Exactly what those contents and
|
|
filesystem type end up being are dependent
|
|
on the given plugin implementation.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐ondisk</filename> or <filename>‐‐ondrive</filename>:</emphasis>
|
|
Forces the partition to be created on a particular
|
|
disk.</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐fstype</filename>:</emphasis>
|
|
Sets the file system type for the partition.
|
|
Valid values are:
|
|
<itemizedlist>
|
|
<listitem><para><filename>ext4</filename>
|
|
</para></listitem>
|
|
<listitem><para><filename>ext3</filename>
|
|
</para></listitem>
|
|
<listitem><para><filename>ext2</filename>
|
|
</para></listitem>
|
|
<listitem><para><filename>btrfs</filename>
|
|
</para></listitem>
|
|
<listitem><para><filename>squashfs</filename>
|
|
</para></listitem>
|
|
<listitem><para><filename>swap</filename>
|
|
</para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐fsoptions</filename>:</emphasis>
|
|
Specifies a free-form string of options to be
|
|
used when mounting the filesystem.
|
|
This string will be copied into the
|
|
<filename>/etc/fstab</filename> file of the
|
|
installed system and should be enclosed in
|
|
quotes.
|
|
If not specified, the default string
|
|
is "defaults".
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐label label</filename>:</emphasis>
|
|
Specifies the label to give to the filesystem to
|
|
be made on the partition.
|
|
If the given label is already in use by another
|
|
filesystem, a new label is created for the
|
|
partition.</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐active</filename>:</emphasis>
|
|
Marks the partition as active.</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐align (in KBytes)</filename>:</emphasis>
|
|
This option is a <filename>wic</filename>-specific
|
|
option that says to start a partition on an
|
|
x KBytes boundary.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='command-bootloader'>
|
|
<title>Command: bootloader</title>
|
|
|
|
<para>
|
|
This command specifies how the boot loader should be
|
|
configured and supports the following options:
|
|
<note>
|
|
Bootloader functionality and boot partitions are
|
|
implemented by the various
|
|
<filename>‐‐source</filename>
|
|
plugins that implement bootloader functionality.
|
|
The bootloader command essentially provides a means of
|
|
modifying bootloader configuration.
|
|
</note>
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>‐‐timeout</filename>:</emphasis>
|
|
Specifies the number of seconds before the
|
|
bootloader times out and boots the default option.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>‐‐append</filename>:</emphasis>
|
|
Specifies kernel parameters.
|
|
These parameters will be added to the syslinux
|
|
<filename>APPEND</filename> or
|
|
<filename>grub</filename> kernel command line.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='configuring-the-kernel'>
|
|
<title>Configuring the Kernel</title>
|
|
|
|
<para>
|
|
Configuring the Yocto Project kernel consists of making sure the <filename>.config</filename>
|
|
file has all the right information in it for the image you are building.
|
|
You can use the <filename>menuconfig</filename> tool and configuration fragments to
|
|
make sure your <filename>.config</filename> file is just how you need it.
|
|
This section describes how to use <filename>menuconfig</filename>, create and use
|
|
configuration fragments, and how to interactively tweak your <filename>.config</filename>
|
|
file to create the leanest kernel configuration file possible.
|
|
</para>
|
|
|
|
<para>
|
|
For more information on kernel configuration, see the
|
|
"<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;#changing-the-configuration'>Changing the Configuration</ulink>"
|
|
section in the Yocto Project Linux Kernel Development Manual.
|
|
</para>
|
|
|
|
<section id='using-menuconfig'>
|
|
<title>Using <filename>menuconfig</filename></title>
|
|
|
|
<para>
|
|
The easiest way to define kernel configurations is to set them through the
|
|
<filename>menuconfig</filename> tool.
|
|
This tool provides an interactive method with which
|
|
to set kernel configurations.
|
|
For general information on <filename>menuconfig</filename>, see
|
|
<ulink url='http://en.wikipedia.org/wiki/Menuconfig'></ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
To use the <filename>menuconfig</filename> tool in the Yocto Project development
|
|
environment, you must launch it using BitBake.
|
|
Thus, the environment must be set up using the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
|
or
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-memres-core-script'><filename>oe-init-build-env-memres</filename></ulink>
|
|
script found in the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
The following commands run <filename>menuconfig</filename> assuming the
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
top-level folder is <filename>~/poky</filename>:
|
|
<literallayout class='monospaced'>
|
|
$ cd poky
|
|
$ source oe-init-build-env
|
|
$ bitbake linux-yocto -c menuconfig
|
|
</literallayout>
|
|
Once <filename>menuconfig</filename> comes up, its standard interface allows you to
|
|
interactively examine and configure all the kernel configuration parameters.
|
|
After making your changes, simply exit the tool and save your changes to
|
|
create an updated version of the <filename>.config</filename> configuration file.
|
|
</para>
|
|
|
|
<para>
|
|
Consider an example that configures the <filename>linux-yocto-3.14</filename>
|
|
kernel.
|
|
The OpenEmbedded build system recognizes this kernel as
|
|
<filename>linux-yocto</filename>.
|
|
Thus, the following commands from the shell in which you previously sourced the
|
|
environment initialization script cleans the shared state cache and the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-WORKDIR'><filename>WORKDIR</filename></ulink>
|
|
directory and then runs <filename>menuconfig</filename>:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake linux-yocto -c menuconfig
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Once <filename>menuconfig</filename> launches, use the interface
|
|
to navigate through the selections to find the configuration settings in
|
|
which you are interested.
|
|
For example, consider the <filename>CONFIG_SMP</filename> configuration setting.
|
|
You can find it at <filename>Processor Type and Features</filename> under
|
|
the configuration selection <filename>Symmetric Multi-processing Support</filename>.
|
|
After highlighting the selection, use the arrow keys to select or deselect
|
|
the setting.
|
|
When you are finished with all your selections, exit out and save them.
|
|
</para>
|
|
|
|
<para>
|
|
Saving the selections updates the <filename>.config</filename> configuration file.
|
|
This is the file that the OpenEmbedded build system uses to configure the
|
|
kernel during the build.
|
|
You can find and examine this file in the Build Directory in
|
|
<filename>tmp/work/</filename>.
|
|
The actual <filename>.config</filename> is located in the area where the
|
|
specific kernel is built.
|
|
For example, if you were building a Linux Yocto kernel based on the
|
|
Linux 3.14 kernel and you were building a QEMU image targeted for
|
|
<filename>x86</filename> architecture, the
|
|
<filename>.config</filename> file would be located here:
|
|
<literallayout class='monospaced'>
|
|
poky/build/tmp/work/qemux86-poky-linux/linux-yocto-3.14.11+git1+84f...
|
|
...656ed30-r1/linux-qemux86-standard-build
|
|
</literallayout>
|
|
<note>
|
|
The previous example directory is artificially split and many of the characters
|
|
in the actual filename are omitted in order to make it more readable.
|
|
Also, depending on the kernel you are using, the exact pathname
|
|
for <filename>linux-yocto-3.14...</filename> might differ.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
Within the <filename>.config</filename> file, you can see the kernel settings.
|
|
For example, the following entry shows that symmetric multi-processor support
|
|
is not set:
|
|
<literallayout class='monospaced'>
|
|
# CONFIG_SMP is not set
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
A good method to isolate changed configurations is to use a combination of the
|
|
<filename>menuconfig</filename> tool and simple shell commands.
|
|
Before changing configurations with <filename>menuconfig</filename>, copy the
|
|
existing <filename>.config</filename> and rename it to something else,
|
|
use <filename>menuconfig</filename> to make
|
|
as many changes as you want and save them, then compare the renamed configuration
|
|
file against the newly created file.
|
|
You can use the resulting differences as your base to create configuration fragments
|
|
to permanently save in your kernel layer.
|
|
<note>
|
|
Be sure to make a copy of the <filename>.config</filename> and don't just
|
|
rename it.
|
|
The build system needs an existing <filename>.config</filename>
|
|
from which to work.
|
|
</note>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-config-fragments'>
|
|
<title>Creating Configuration Fragments</title>
|
|
|
|
<para>
|
|
Configuration fragments are simply kernel options that appear in a file
|
|
placed where the OpenEmbedded build system can find and apply them.
|
|
Syntactically, the configuration statement is identical to what would appear
|
|
in the <filename>.config</filename> file, which is in the
|
|
<link linkend='build-directory'>Build Directory</link> in
|
|
<filename>tmp/work/<arch>-poky-linux/linux-yocto-<release-specific-string>/linux-<arch>-<build-type></filename>.
|
|
</para>
|
|
|
|
<para>
|
|
It is simple to create a configuration fragment.
|
|
For example, issuing the following from the shell creates a configuration fragment
|
|
file named <filename>my_smp.cfg</filename> that enables multi-processor support
|
|
within the kernel:
|
|
<literallayout class='monospaced'>
|
|
$ echo "CONFIG_SMP=y" >> my_smp.cfg
|
|
</literallayout>
|
|
<note>
|
|
All configuration files must use the <filename>.cfg</filename> extension in order
|
|
for the OpenEmbedded build system to recognize them as a configuration fragment.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
Where do you put your configuration files?
|
|
You can place these configuration files in the same area pointed to by
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>.
|
|
The OpenEmbedded build system will pick up the configuration and add it to the
|
|
kernel's configuration.
|
|
For example, suppose you had a set of configuration options in a file called
|
|
<filename>myconfig.cfg</filename>.
|
|
If you put that file inside a directory named <filename>linux-yocto</filename>
|
|
that resides in the same directory as the kernel's append file and then add
|
|
a <filename>SRC_URI</filename> statement such as the following to the kernel's append file,
|
|
those configuration options will be picked up and applied when the kernel is built.
|
|
<literallayout class='monospaced'>
|
|
SRC_URI += "file://myconfig.cfg"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
As mentioned earlier, you can group related configurations into multiple files and
|
|
name them all in the <filename>SRC_URI</filename> statement as well.
|
|
For example, you could group separate configurations specifically for Ethernet and graphics
|
|
into their own files and add those by using a <filename>SRC_URI</filename> statement like the
|
|
following in your append file:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI += "file://myconfig.cfg \
|
|
file://eth.cfg \
|
|
file://gfx.cfg"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='fine-tuning-the-kernel-configuration-file'>
|
|
<title>Fine-Tuning the Kernel Configuration File</title>
|
|
|
|
<para>
|
|
You can make sure the <filename>.config</filename> file is as lean or efficient as
|
|
possible by reading the output of the kernel configuration fragment audit,
|
|
noting any issues, making changes to correct the issues, and then repeating.
|
|
</para>
|
|
|
|
<para>
|
|
As part of the kernel build process, the
|
|
<filename>do_kernel_configcheck</filename> task runs.
|
|
This task validates the kernel configuration by checking the final
|
|
<filename>.config</filename> file against the input files.
|
|
During the check, the task produces warning messages for the following
|
|
issues:
|
|
<itemizedlist>
|
|
<listitem><para>Requested options that did not make the final
|
|
<filename>.config</filename> file.</para></listitem>
|
|
<listitem><para>Configuration items that appear twice in the same
|
|
configuration fragment.</para></listitem>
|
|
<listitem><para>Configuration items tagged as "required" that were overridden.
|
|
</para></listitem>
|
|
<listitem><para>A board overrides a non-board specific option.</para></listitem>
|
|
<listitem><para>Listed options not valid for the kernel being processed.
|
|
In other words, the option does not appear anywhere.</para></listitem>
|
|
</itemizedlist>
|
|
<note>
|
|
The <filename>do_kernel_configcheck</filename> task can
|
|
also optionally report if an option is overridden during
|
|
processing.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
For each output warning, a message points to the file
|
|
that contains a list of the options and a pointer to the config
|
|
fragment that defines them.
|
|
Collectively, the files are the key to streamlining the configuration.
|
|
</para>
|
|
|
|
<para>
|
|
To streamline the configuration, do the following:
|
|
<orderedlist>
|
|
<listitem><para>Start with a full configuration that you
|
|
know works - it builds and boots successfully.
|
|
This configuration file will be your baseline.
|
|
</para></listitem>
|
|
<listitem><para>Separately run the
|
|
<filename>do_configme</filename> and
|
|
<filename>do_kernel_configcheck</filename> tasks.
|
|
</para></listitem>
|
|
<listitem><para>Take the resulting list of files from the
|
|
<filename>do_kernel_configcheck</filename> task
|
|
warnings and do the following:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
Drop values that are redefined in the fragment
|
|
but do not change the final
|
|
<filename>.config</filename> file.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Analyze and potentially drop values from the
|
|
<filename>.config</filename> file that override
|
|
required configurations.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Analyze and potentially remove non-board
|
|
specific options.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Remove repeated and invalid options.
|
|
</para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
<listitem><para>
|
|
After you have worked through the output of the kernel
|
|
configuration audit, you can re-run the
|
|
<filename>do_configme</filename> and
|
|
<filename>do_kernel_configcheck</filename> tasks to
|
|
see the results of your changes.
|
|
If you have more issues, you can deal with them as
|
|
described in the previous step.
|
|
</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Iteratively working through steps two through four eventually yields
|
|
a minimal, streamlined configuration file.
|
|
Once you have the best <filename>.config</filename>, you can build the Linux
|
|
Yocto kernel.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="patching-the-kernel">
|
|
<title>Patching the Kernel</title>
|
|
|
|
<para>
|
|
Patching the kernel involves changing or adding configurations to an existing kernel,
|
|
changing or adding recipes to the kernel that are needed to support specific hardware features,
|
|
or even altering the source code itself.
|
|
<note>
|
|
You can use the <filename>yocto-kernel</filename> script
|
|
found in the <link linkend='source-directory'>Source Directory</link>
|
|
under <filename>scripts</filename> to manage kernel patches and configuration.
|
|
See the "<ulink url='&YOCTO_DOCS_BSP_URL;#managing-kernel-patches-and-config-items-with-yocto-kernel'>Managing kernel Patches and Config Items with yocto-kernel</ulink>"
|
|
section in the Yocto Project Board Support Packages (BSP) Developer's Guide for
|
|
more information.</note>
|
|
</para>
|
|
|
|
<para>
|
|
This example creates a simple patch by adding some QEMU emulator console
|
|
output at boot time through <filename>printk</filename> statements in the kernel's
|
|
<filename>calibrate.c</filename> source code file.
|
|
Applying the patch and booting the modified image causes the added
|
|
messages to appear on the emulator's console.
|
|
</para>
|
|
|
|
<para>
|
|
The example assumes a clean build exists for the <filename>qemux86</filename>
|
|
machine in a
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
named <filename>poky</filename>.
|
|
Furthermore, the <link linkend='build-directory'>Build Directory</link> is
|
|
<filename>build</filename> and is located in <filename>poky</filename> and
|
|
the kernel is based on the Linux 3.4 kernel.
|
|
For general information on how to configure the most efficient build, see the
|
|
"<ulink url='&YOCTO_DOCS_QS_URL;#building-image'>Building an Image</ulink>" section
|
|
in the Yocto Project Quick Start.
|
|
</para>
|
|
|
|
<para>
|
|
Also, for more information on patching the kernel, see the
|
|
"<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;#applying-patches'>Applying Patches</ulink>"
|
|
section in the Yocto Project Linux Kernel Development Manual.
|
|
</para>
|
|
|
|
<section id='create-a-layer-for-your-changes'>
|
|
<title>Create a Layer for your Changes</title>
|
|
|
|
<para>
|
|
The first step is to create a layer so you can isolate your
|
|
changes.
|
|
Rather than use the <filename>yocto-layer</filename> script
|
|
to create the layer, this example steps through the process
|
|
by hand.
|
|
If you want information on the script that creates a general
|
|
layer, see the
|
|
"<link linkend='creating-a-general-layer-using-the-yocto-layer-script'>Creating a General Layer Using the yocto-layer Script</link>"
|
|
section.
|
|
</para>
|
|
|
|
<para>
|
|
These two commands create a directory you can use for your
|
|
layer:
|
|
<literallayout class='monospaced'>
|
|
$ cd ~/poky
|
|
$ mkdir meta-mylayer
|
|
</literallayout>
|
|
Creating a directory that follows the Yocto Project layer naming
|
|
conventions sets up the layer for your changes.
|
|
The layer is where you place your configuration files, append
|
|
files, and patch files.
|
|
To learn more about creating a layer and filling it with the
|
|
files you need, see the "<link linkend='understanding-and-creating-layers'>Understanding
|
|
and Creating Layers</link>" section.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='finding-the-kernel-source-code'>
|
|
<title>Finding the Kernel Source Code</title>
|
|
|
|
<para>
|
|
Each time you build a kernel image, the kernel source code is fetched
|
|
and unpacked into the following directory:
|
|
<literallayout class='monospaced'>
|
|
${S}/linux
|
|
</literallayout>
|
|
See the "<link linkend='finding-the-temporary-source-code'>Finding the Temporary Source Code</link>"
|
|
section and the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-S'><filename>S</filename></ulink> variable
|
|
for more information about where source is kept during a build.
|
|
</para>
|
|
|
|
<para>
|
|
For this example, we are going to patch the
|
|
<filename>init/calibrate.c</filename> file
|
|
by adding some simple console <filename>printk</filename> statements that we can
|
|
see when we boot the image using QEMU.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-the-patch'>
|
|
<title>Creating the Patch</title>
|
|
|
|
<para>
|
|
Two methods exist by which you can create the patch:
|
|
<link linkend='using-a-git-workflow'>Git workflow</link> and
|
|
<link linkend='using-a-quilt-workflow'>Quilt workflow</link>.
|
|
For kernel patches, the Git workflow is more appropriate.
|
|
This section assumes the Git workflow and shows the steps specific to
|
|
this example.
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Change the working directory</emphasis>:
|
|
Change to where the kernel source code is before making
|
|
your edits to the <filename>calibrate.c</filename> file:
|
|
<literallayout class='monospaced'>
|
|
$ cd ~/poky/build/tmp/work/qemux86-poky-linux/linux-yocto-${PV}-${PR}/linux
|
|
</literallayout>
|
|
Because you are working in an established Git repository,
|
|
you must be in this directory in order to commit your changes
|
|
and create the patch file.
|
|
<note>The <ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink> and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PR'><filename>PR</filename></ulink> variables
|
|
represent the version and revision for the
|
|
<filename>linux-yocto</filename> recipe.
|
|
The <filename>PV</filename> variable includes the Git meta and machine
|
|
hashes, which make the directory name longer than you might
|
|
expect.
|
|
</note></para></listitem>
|
|
<listitem><para><emphasis>Edit the source file</emphasis>:
|
|
Edit the <filename>init/calibrate.c</filename> file to have the
|
|
following changes:
|
|
<literallayout class='monospaced'>
|
|
void calibrate_delay(void)
|
|
{
|
|
unsigned long lpj;
|
|
static bool printed;
|
|
int this_cpu = smp_processor_id();
|
|
|
|
printk("*************************************\n");
|
|
printk("* *\n");
|
|
printk("* HELLO YOCTO KERNEL *\n");
|
|
printk("* *\n");
|
|
printk("*************************************\n");
|
|
|
|
if (per_cpu(cpu_loops_per_jiffy, this_cpu)) {
|
|
.
|
|
.
|
|
.
|
|
</literallayout></para></listitem>
|
|
<listitem><para><emphasis>Stage and commit your changes</emphasis>:
|
|
These Git commands display the modified file, stage it, and then
|
|
commit the file:
|
|
<literallayout class='monospaced'>
|
|
$ git status
|
|
$ git add init/calibrate.c
|
|
$ git commit -m "calibrate: Add printk example"
|
|
</literallayout></para></listitem>
|
|
<listitem><para><emphasis>Generate the patch file</emphasis>:
|
|
This Git command creates the a patch file named
|
|
<filename>0001-calibrate-Add-printk-example.patch</filename>
|
|
in the current directory.
|
|
<literallayout class='monospaced'>
|
|
$ git format-patch -1
|
|
</literallayout>
|
|
</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='set-up-your-layer-for-the-build'>
|
|
<title>Set Up Your Layer for the Build</title>
|
|
|
|
<para>These steps get your layer set up for the build:
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Create additional structure</emphasis>:
|
|
Create the additional layer structure:
|
|
<literallayout class='monospaced'>
|
|
$ cd ~/poky/meta-mylayer
|
|
$ mkdir conf
|
|
$ mkdir recipes-kernel
|
|
$ mkdir recipes-kernel/linux
|
|
$ mkdir recipes-kernel/linux/linux-yocto
|
|
</literallayout>
|
|
The <filename>conf</filename> directory holds your configuration files, while the
|
|
<filename>recipes-kernel</filename> directory holds your append file and
|
|
your patch file.</para></listitem>
|
|
<listitem><para><emphasis>Create the layer configuration file</emphasis>:
|
|
Move to the <filename>meta-mylayer/conf</filename> directory and create
|
|
the <filename>layer.conf</filename> file as follows:
|
|
<literallayout class='monospaced'>
|
|
# 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 += "mylayer"
|
|
BBFILE_PATTERN_mylayer = "^${LAYERDIR}/"
|
|
BBFILE_PRIORITY_mylayer = "5"
|
|
</literallayout>
|
|
Notice <filename>mylayer</filename> as part of the last three
|
|
statements.</para></listitem>
|
|
<listitem><para><emphasis>Create the kernel recipe append file</emphasis>:
|
|
Move to the <filename>meta-mylayer/recipes-kernel/linux</filename> directory and create
|
|
the <filename>linux-yocto_3.4.bbappend</filename> file as follows:
|
|
<literallayout class='monospaced'>
|
|
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
|
|
|
|
SRC_URI += "file://0001-calibrate-Add-printk-example.patch"
|
|
</literallayout>
|
|
The <ulink url='&YOCTO_DOCS_REF_URL;#var-FILESEXTRAPATHS'><filename>FILESEXTRAPATHS</filename></ulink>
|
|
and <ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
statements enable the OpenEmbedded build system to find the patch file.
|
|
For more information on using append files, see the
|
|
"<link linkend='using-bbappend-files'>Using .bbappend Files</link>"
|
|
section.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Put the patch file in your layer</emphasis>:
|
|
Move the <filename>0001-calibrate-Add-printk-example.patch</filename> file to
|
|
the <filename>meta-mylayer/recipes-kernel/linux/linux-yocto</filename>
|
|
directory.</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='set-up-for-the-build'>
|
|
<title>Set Up for the Build</title>
|
|
|
|
<para>
|
|
Do the following to make sure the build parameters are set up for the example.
|
|
Once you set up these build parameters, they do not have to change unless you
|
|
change the target architecture of the machine you are building:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Build for the correct target architecture:</emphasis> Your
|
|
selected <ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>
|
|
definition within the <filename>local.conf</filename> file in the
|
|
<link linkend='build-directory'>Build Directory</link>
|
|
specifies the target architecture used when building the Linux kernel.
|
|
By default, <filename>MACHINE</filename> is set to
|
|
<filename>qemux86</filename>, which specifies a 32-bit
|
|
<trademark class='registered'>Intel</trademark> Architecture
|
|
target machine suitable for the QEMU emulator.</para></listitem>
|
|
<listitem><para><emphasis>Identify your <filename>meta-mylayer</filename>
|
|
layer:</emphasis> The
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBLAYERS'><filename>BBLAYERS</filename></ulink>
|
|
variable in the
|
|
<filename>bblayers.conf</filename> file found in the
|
|
<filename>poky/build/conf</filename> directory needs to have the path to your local
|
|
<filename>meta-mylayer</filename> layer.
|
|
By default, the <filename>BBLAYERS</filename> variable contains paths to
|
|
<filename>meta</filename>, <filename>meta-yocto</filename>, and
|
|
<filename>meta-yocto-bsp</filename> in the
|
|
<filename>poky</filename> Git repository.
|
|
Add the path to your <filename>meta-mylayer</filename> location:
|
|
<literallayout class='monospaced'>
|
|
BBLAYERS ?= " \
|
|
$HOME/poky/meta \
|
|
$HOME/poky/meta-yocto \
|
|
$HOME/poky/meta-yocto-bsp \
|
|
$HOME/poky/meta-mylayer \
|
|
"
|
|
|
|
BBLAYERS_NON_REMOVABLE ?= " \
|
|
$HOME/poky/meta \
|
|
$HOME/poky/meta-yocto \
|
|
"
|
|
</literallayout></para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='build-the-modified-qemu-kernel-image'>
|
|
<title>Build the Modified QEMU Kernel Image</title>
|
|
|
|
<para>
|
|
The following steps build your modified kernel image:
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Be sure your build environment is initialized</emphasis>:
|
|
Your environment should be set up since you previously sourced
|
|
the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
|
script.
|
|
If it is not, source the script again from <filename>poky</filename>.
|
|
<literallayout class='monospaced'>
|
|
$ cd ~/poky
|
|
$ source &OE_INIT_FILE;
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Clean up</emphasis>:
|
|
Be sure to clean the shared state out by using BitBake
|
|
to run from within the Build Directory the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-cleansstate'><filename>do_cleansstate</filename></ulink>
|
|
task as follows:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake -c cleansstate linux-yocto
|
|
</literallayout></para>
|
|
<para>
|
|
<note>
|
|
Never remove any files by hand from the
|
|
<filename>tmp/deploy</filename>
|
|
directory inside the
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
Always use the various BitBake clean tasks to
|
|
clear out previous build artifacts.
|
|
For information on the clean tasks, see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-clean'><filename>do_clean</filename></ulink>",
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-cleanall'><filename>do_cleanall</filename></ulink>",
|
|
and
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-cleansstate'><filename>do_cleansstate</filename></ulink>"
|
|
sections all in the Yocto Project Reference
|
|
Manual.
|
|
</note>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Build the image</emphasis>:
|
|
Next, build the kernel image using this command:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake -k linux-yocto
|
|
</literallayout></para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='boot-the-image-and-verify-your-changes'>
|
|
<title>Boot the Image and Verify Your Changes</title>
|
|
|
|
<para>
|
|
These steps boot the image and allow you to see the changes
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Boot the image</emphasis>:
|
|
Boot the modified image in the QEMU emulator
|
|
using this command:
|
|
<literallayout class='monospaced'>
|
|
$ runqemu qemux86
|
|
</literallayout></para></listitem>
|
|
<listitem><para><emphasis>Verify the changes</emphasis>:
|
|
Log into the machine using <filename>root</filename> with no password and then
|
|
use the following shell command to scroll through the console's boot output.
|
|
<literallayout class='monospaced'>
|
|
# dmesg | less
|
|
</literallayout>
|
|
You should see the results of your <filename>printk</filename> statements
|
|
as part of the output.</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='making-images-more-secure'>
|
|
<title>Making Images More Secure</title>
|
|
|
|
<para>
|
|
Security is of increasing concern for embedded devices.
|
|
Consider the issues and problems discussed in just this
|
|
sampling of work found across the Internet:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>
|
|
"<ulink url='https://www.schneier.com/blog/archives/2014/01/security_risks_9.html'>Security Risks of Embedded Systems</ulink>"</emphasis>
|
|
by Bruce Schneier
|
|
</para></listitem>
|
|
<listitem><para><emphasis>
|
|
"<ulink url='http://internetcensus2012.bitbucket.org/paper.html'>Internet Census 2012</ulink>"</emphasis>
|
|
by Carna Botnet</para></listitem>
|
|
<listitem><para><emphasis>
|
|
"<ulink url='http://elinux.org/images/6/6f/Security-issues.pdf'>Security Issues for Embedded Devices</ulink>"</emphasis>
|
|
by Jake Edge
|
|
</para></listitem>
|
|
<listitem><para><emphasis>
|
|
"<ulink url='https://www.nccgroup.com/media/18475/exploiting_security_gateways_via_their_web_interfaces.pdf'>They ought to know better: Exploiting Security
|
|
Gateways via their Web Interfaces</ulink>"</emphasis>
|
|
by Ben Williams
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
When securing your image is of concern, there are steps, tools,
|
|
and variables that you can consider to help you reach the
|
|
security goals you need for your particular device.
|
|
Not all situations are identical when it comes to making an
|
|
image secure.
|
|
Consequently, this section provides some guidance and suggestions
|
|
for consideration when you want to make your image more secure.
|
|
<note>
|
|
Because the security requirements and risks are
|
|
different for every type of device, this section cannot
|
|
provide a complete reference on securing your custom OS.
|
|
It is strongly recommended that you also consult other sources
|
|
of information on embedded Linux system hardening and on
|
|
security.
|
|
</note>
|
|
</para>
|
|
|
|
<section id='general-considerations'>
|
|
<title>General Considerations</title>
|
|
|
|
<para>
|
|
General considerations exist that help you create more
|
|
secure images.
|
|
You should consider the following suggestions to help
|
|
make your device more secure:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
Scan additional code you are adding to the system
|
|
(e.g. application code) by using static analysis
|
|
tools.
|
|
Look for buffer overflows and other potential
|
|
security problems.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Pay particular attention to to the security for
|
|
any web-based administration interface.
|
|
</para>
|
|
<para>Web interfaces typically need to perform
|
|
administrative functions and tend to need to run with
|
|
elevated privileges.
|
|
Thus, the consequences resulting from the interface's
|
|
security becoming compromised can be serious.
|
|
Look for common web vulnerabilities such as
|
|
cross-site-scripting (XSS), unvalidated inputs,
|
|
and so forth.</para>
|
|
<para>As with system passwords, the default credentials
|
|
for accessing a web-based interface should not be the
|
|
same across all devices.
|
|
This is particularly true if the interface is enabled
|
|
by default as it can be assumed that many end-users
|
|
will not change the credentials.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Ensure you can update the software on the device to
|
|
mitigate vulnerabilities discovered in the future.
|
|
This consideration especially applies when your
|
|
device is network-enabled.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Ensure you remove or disable debugging functionality
|
|
before producing the final image.
|
|
For information on how to do this, see the
|
|
"<link linkend='considerations-specific-to-the-openembedded-build-system'>Considerations Specific to the OpenEmbedded Build System</link>"
|
|
section.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Ensure you have no network services listening that
|
|
are not needed.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Remove any software from the image that is not needed.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Enable hardware support for secure boot functionality
|
|
when your device supports this functionality.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='security-flags'>
|
|
<title>Security Flags</title>
|
|
|
|
<para>
|
|
The Yocto Project has security flags that you can enable that
|
|
help make your build output more secure.
|
|
The security flags are in the
|
|
<filename>meta/conf/distro/include/security_flags.inc</filename>
|
|
file in your
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
(e.g. <filename>poky</filename>).
|
|
<note>
|
|
Depending on the recipe, certain security flags are enabled
|
|
and disabled by default.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
<!--
|
|
The GCC/LD flags in <filename>security_flags.inc</filename>
|
|
enable more secure code generation.
|
|
By including the <filename>security_flags.inc</filename>
|
|
file, you enable flags to the compiler and linker that cause
|
|
them to generate more secure code.
|
|
<note>
|
|
The GCC/LD flags are enabled by default in the
|
|
<filename>poky-lsb</filename> distribution.
|
|
</note>
|
|
-->
|
|
Use the following line in your
|
|
<filename>local.conf</filename> file or in your custom
|
|
distribution configuration file to enable the security
|
|
compiler and linker flags to your build:
|
|
<literallayout class='monospaced'>
|
|
require conf/distro/include/security_flags.inc
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='considerations-specific-to-the-openembedded-build-system'>
|
|
<title>Considerations Specific to the OpenEmbedded Build System</title>
|
|
|
|
<para>
|
|
You can take some steps that are specific to the
|
|
OpenEmbedded build system to make your images more secure:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
Ensure "debug-tweaks" is not listed with
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>.
|
|
The default is to enable "debug-tweaks" by adding it
|
|
to
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_IMAGE_FEATURES'><filename>EXTRA_IMAGE_FEATURES</filename></ulink>
|
|
in <filename>local.conf</filename>.
|
|
However, you should comment out the variable or be
|
|
sure that it does not have "debug-tweaks" before
|
|
producing your final image.
|
|
Among other things, leaving this in place sets the
|
|
root password as blank, which makes logging in for
|
|
debugging or inspection easy during
|
|
development but also means anyone can easily log in
|
|
during production.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
It is possible to set a root password for the image
|
|
and also to set passwords for any extra users you might
|
|
add (e.g. administrative or service type users).
|
|
When you set up passwords for multiple images or
|
|
users, you should not duplicate passwords.
|
|
</para>
|
|
<para>
|
|
To set up passwords, use the
|
|
<filename>extrausers</filename> class, which is the
|
|
preferred method.
|
|
For an example on how to set up both root and user
|
|
passwords, see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-extrausers'><filename>extrausers.bbclass</filename></ulink>"
|
|
section.
|
|
<note>
|
|
When adding extra user accounts or setting a
|
|
root password, be cautious about setting the
|
|
same password on every device.
|
|
If you do this, and the password you have set
|
|
is exposed, then every device is now potentially
|
|
compromised.
|
|
If you need this access but want to ensure
|
|
security, consider setting a different,
|
|
random password for each device.
|
|
Typically, you do this as a separate step after
|
|
you deploy the image onto the device.
|
|
</note>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Consider enabling a Mandatory Access Control (MAC)
|
|
framework (such as SMACK or SELinux) and tuning it
|
|
appropriately for your device's usage.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='tools-for-hardening-your-image'>
|
|
<title>Tools for Hardening Your Image</title>
|
|
|
|
<para>
|
|
The Yocto Project provides tools for making your image
|
|
more secure.
|
|
You can find these tools in the
|
|
<filename>meta-security</filename> layer of the
|
|
<ulink url='&YOCTO_GIT_URL;/cgit/cgit.cgi'>Yocto Project Source Repositories</ulink>.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='creating-your-own-distribution'>
|
|
<title>Creating Your Own Distribution</title>
|
|
|
|
<para>
|
|
When you build an image using the Yocto Project and
|
|
do not alter any distribution
|
|
<link linkend='metadata'>Metadata</link>, you are creating a
|
|
Poky distribution.
|
|
If you wish to gain more control over package alternative
|
|
selections, compile-time options, and other low-level
|
|
configurations, you can create your own distribution.
|
|
</para>
|
|
|
|
<para>
|
|
To create your own distribution, the basic steps consist of
|
|
creating your own distribution layer, creating your own
|
|
distribution configuration file, and then adding any needed
|
|
code and Metadata to the layer.
|
|
The following steps provide some more detail:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Create a layer for your new distro:</emphasis>
|
|
Create your distribution layer so that you can keep your
|
|
Metadata and code for the distribution separate.
|
|
It is strongly recommended that you create and use your own
|
|
layer for configuration and code.
|
|
Using your own layer as compared to just placing
|
|
configurations in a <filename>local.conf</filename>
|
|
configuration file makes it easier to reproduce the same
|
|
build configuration when using multiple build machines.
|
|
See the
|
|
"<link linkend='creating-a-general-layer-using-the-yocto-layer-script'>Creating a General Layer Using the yocto-layer Script</link>"
|
|
section for information on how to quickly set up a layer.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Create the distribution configuration file:</emphasis>
|
|
The distribution configuration file needs to be created in
|
|
the <filename>conf/distro</filename> directory of your
|
|
layer.
|
|
You need to name it using your distribution name
|
|
(e.g. <filename>mydistro.conf</filename>).
|
|
<note>
|
|
The
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO'><filename>DISTRO</filename></ulink>
|
|
variable in your
|
|
<filename>local.conf</filename> file determines the
|
|
name of your distribution.
|
|
</note></para>
|
|
<para>You can split out parts of your configuration file
|
|
into include files and then "require" them from within
|
|
your distribution configuration file.
|
|
Be sure to place the include files in the
|
|
<filename>conf/distro/include</filename> directory of
|
|
your layer.
|
|
A common example usage of include files would be to
|
|
separate out the selection of desired version and revisions
|
|
for individual recipes.
|
|
</para>
|
|
<para>Your configuration file needs to set the following
|
|
required variables:
|
|
<literallayout class='monospaced'>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_NAME'><filename>DISTRO_NAME</filename></ulink>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_VERSION'><filename>DISTRO_VERSION</filename></ulink>
|
|
</literallayout>
|
|
These following variables are optional and you typically
|
|
set them from the distribution configuration file:
|
|
<literallayout class='monospaced'>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_FEATURES'><filename>DISTRO_FEATURES</filename></ulink>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_EXTRA_RDEPENDS'><filename>DISTRO_EXTRA_RDEPENDS</filename></ulink>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_EXTRA_RRECOMMENDS'><filename>DISTRO_EXTRA_RRECOMMENDS</filename></ulink>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-TCLIBC'><filename>TCLIBC</filename></ulink>
|
|
</literallayout>
|
|
<tip>
|
|
If you want to base your distribution configuration file
|
|
on the very basic configuration from OE-Core, you
|
|
can use
|
|
<filename>conf/distro/defaultsetup.conf</filename> as
|
|
a reference and just include variables that differ
|
|
as compared to <filename>defaultsetup.conf</filename>.
|
|
Alternatively, you can create a distribution
|
|
configuration file from scratch using the
|
|
<filename>defaultsetup.conf</filename> file
|
|
or configuration files from other distributions
|
|
such as Poky or Angstrom as references.
|
|
</tip></para></listitem>
|
|
<listitem><para><emphasis>Provide miscellaneous variables:</emphasis>
|
|
Be sure to define any other variables for which you want to
|
|
create a default or enforce as part of the distribution
|
|
configuration.
|
|
You can include nearly any variable from the
|
|
<filename>local.conf</filename> file.
|
|
The variables you use are not limited to the list in the
|
|
previous bulleted item.</para></listitem>
|
|
<listitem><para><emphasis>Point to Your distribution configuration file:</emphasis>
|
|
In your <filename>local.conf</filename> file in the
|
|
<link linkend='build-directory'>Build Directory</link>,
|
|
set your
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO'><filename>DISTRO</filename></ulink>
|
|
variable to point to your distribution's configuration file.
|
|
For example, if your distribution's configuration file is
|
|
named <filename>mydistro.conf</filename>, then you point
|
|
to it as follows:
|
|
<literallayout class='monospaced'>
|
|
DISTRO = "mydistro"
|
|
</literallayout></para></listitem>
|
|
<listitem><para><emphasis>Add more to the layer if necessary:</emphasis>
|
|
Use your layer to hold other information needed for the
|
|
distribution:
|
|
<itemizedlist>
|
|
<listitem><para>Add recipes for installing
|
|
distro-specific configuration files that are not
|
|
already installed by another recipe.
|
|
If you have distro-specific configuration files
|
|
that are included by an existing recipe, you should
|
|
add an append file (<filename>.bbappend</filename>)
|
|
for those.
|
|
For general information and recommendations
|
|
on how to add recipes to your layer, see the
|
|
"<link linkend='creating-your-own-layer'>Creating Your Own Layer</link>"
|
|
and
|
|
"<link linkend='best-practices-to-follow-when-creating-layers'>Best Practices to Follow When Creating Layers</link>"
|
|
sections.</para></listitem>
|
|
<listitem><para>Add any image recipes that are specific
|
|
to your distribution.</para></listitem>
|
|
<listitem><para>Add a <filename>psplash</filename>
|
|
append file for a branded splash screen.
|
|
For information on append files, see the
|
|
"<link linkend='using-bbappend-files'>Using .bbappend Files</link>"
|
|
section.</para></listitem>
|
|
<listitem><para>Add any other append files to make
|
|
custom changes that are specific to individual
|
|
recipes.</para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-a-custom-template-configuration-directory'>
|
|
<title>Creating a Custom Template Configuration Directory</title>
|
|
|
|
<para>
|
|
If you are producing your own customized version
|
|
of the build system for use by other users, you might
|
|
want to customize the message shown by the setup script or
|
|
you might want to change the template configuration files (i.e.
|
|
<filename>local.conf</filename> and
|
|
<filename>bblayers.conf</filename>) that are created in
|
|
a new build directory.
|
|
</para>
|
|
|
|
<para>
|
|
The OpenEmbedded build system uses the environment variable
|
|
<filename>TEMPLATECONF</filename> to locate the directory
|
|
from which it gathers configuration information that ultimately
|
|
ends up in the
|
|
<link linkend='build-directory'>Build Directory's</link>
|
|
<filename>conf</filename> directory.
|
|
By default, <filename>TEMPLATECONF</filename> is set as
|
|
follows in the <filename>poky</filename> repository:
|
|
<literallayout class='monospaced'>
|
|
TEMPLATECONF=${TEMPLATECONF:-meta-yocto/conf}
|
|
</literallayout>
|
|
This is the directory used by the build system to find templates
|
|
from which to build some key configuration files.
|
|
If you look at this directory, you will see the
|
|
<filename>bblayers.conf.sample</filename>,
|
|
<filename>local.conf.sample</filename>, and
|
|
<filename>conf-notes.txt</filename> files.
|
|
The build system uses these files to form the respective
|
|
<filename>bblayers.conf</filename> file,
|
|
<filename>local.conf</filename> file, and display the list of
|
|
BitBake targets when running the setup script.
|
|
</para>
|
|
|
|
<para>
|
|
To override these default configuration files with
|
|
configurations you want used within every new
|
|
Build Directory, simply set the
|
|
<filename>TEMPLATECONF</filename> variable to your directory.
|
|
The <filename>TEMPLATECONF</filename> variable is set in the
|
|
<filename>.templateconf</filename> file, which is in the
|
|
top-level
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
folder (e.g. <filename>poky</filename>).
|
|
Edit the <filename>.templateconf</filename> so that it can locate
|
|
your directory.
|
|
</para>
|
|
|
|
<para>
|
|
Best practices dictate that you should keep your
|
|
template configuration directory in your custom distribution layer.
|
|
For example, suppose you have a layer named
|
|
<filename>meta-mylayer</filename> located in your home directory
|
|
and you want your template configuration directory named
|
|
<filename>myconf</filename>.
|
|
Changing the <filename>.templateconf</filename> as follows
|
|
causes the OpenEmbedded build system to look in your directory
|
|
and base its configuration files on the
|
|
<filename>*.sample</filename> configuration files it finds.
|
|
The final configuration files (i.e.
|
|
<filename>local.conf</filename> and
|
|
<filename>bblayers.conf</filename> ultimately still end up in
|
|
your Build Directory, but they are based on your
|
|
<filename>*.sample</filename> files.
|
|
<literallayout class='monospaced'>
|
|
TEMPLATECONF=${TEMPLATECONF:-meta-mylayer/myconf}
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Aside from the <filename>*.sample</filename> configuration files,
|
|
the <filename>conf-notes.txt</filename> also resides in the
|
|
default <filename>meta-yocto/conf</filename> directory.
|
|
The scripts that set up the build environment
|
|
(i.e.
|
|
<ulink url="&YOCTO_DOCS_REF_URL;#structure-core-script"><filename>&OE_INIT_FILE;</filename></ulink>
|
|
and
|
|
<ulink url="&YOCTO_DOCS_REF_URL;#structure-memres-core-script"><filename>oe-init-build-env-memres</filename></ulink>)
|
|
use this file to display BitBake targets as part of the script
|
|
output.
|
|
Customizing this <filename>conf-notes.txt</filename> file is a
|
|
good way to make sure your list of custom targets appears
|
|
as part of the script's output.
|
|
</para>
|
|
|
|
<para>
|
|
Here is the default list of targets displayed as a result of
|
|
running either of the setup scripts:
|
|
<literallayout class='monospaced'>
|
|
You can now run 'bitbake <target>'
|
|
|
|
Common targets are:
|
|
core-image-minimal
|
|
core-image-sato
|
|
meta-toolchain
|
|
adt-installer
|
|
meta-ide-support
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Changing the listed common targets is as easy as editing your
|
|
version of <filename>conf-notes.txt</filename> in your
|
|
custom template configuration directory and making sure you
|
|
have <filename>TEMPLATECONF</filename> set to your directory.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='building-a-tiny-system'>
|
|
<title>Building a Tiny System</title>
|
|
|
|
<para>
|
|
Very small distributions have some significant advantages such
|
|
as requiring less on-die or in-package memory (cheaper), better
|
|
performance through efficient cache usage, lower power requirements
|
|
due to less memory, faster boot times, and reduced development
|
|
overhead.
|
|
Some real-world examples where a very small distribution gives
|
|
you distinct advantages are digital cameras, medical devices,
|
|
and small headless systems.
|
|
</para>
|
|
|
|
<para>
|
|
This section presents information that shows you how you can
|
|
trim your distribution to even smaller sizes than the
|
|
<filename>poky-tiny</filename> distribution, which is around
|
|
5 Mbytes, that can be built out-of-the-box using the Yocto Project.
|
|
</para>
|
|
|
|
<section id='tiny-system-overview'>
|
|
<title>Overview</title>
|
|
|
|
<para>
|
|
The following list presents the overall steps you need to
|
|
consider and perform to create distributions with smaller
|
|
root filesystems, achieve faster boot times, maintain your critical
|
|
functionality, and avoid initial RAM disks:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
<link linkend='goals-and-guiding-principles'>Determine your goals and guiding principles.</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='understand-what-gives-your-image-size'>Understand what contributes to your image size.</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='trim-the-root-filesystem'>Reduce the size of the root filesystem.</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='trim-the-kernel'>Reduce the size of the kernel.</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='remove-package-management-requirements'>Eliminate packaging requirements.</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='look-for-other-ways-to-minimize-size'>Look for other ways to minimize size.</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='iterate-on-the-process'>Iterate on the process.</link>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='goals-and-guiding-principles'>
|
|
<title>Goals and Guiding Principles</title>
|
|
|
|
<para>
|
|
Before you can reach your destination, you need to know
|
|
where you are going.
|
|
Here is an example list that you can use as a guide when
|
|
creating very small distributions:
|
|
<itemizedlist>
|
|
<listitem><para>Determine how much space you need
|
|
(e.g. a kernel that is 1 Mbyte or less and
|
|
a root filesystem that is 3 Mbytes or less).
|
|
</para></listitem>
|
|
<listitem><para>Find the areas that are currently
|
|
taking 90% of the space and concentrate on reducing
|
|
those areas.
|
|
</para></listitem>
|
|
<listitem><para>Do not create any difficult "hacks"
|
|
to achieve your goals.</para></listitem>
|
|
<listitem><para>Leverage the device-specific
|
|
options.</para></listitem>
|
|
<listitem><para>Work in a separate layer so that you
|
|
keep changes isolated.
|
|
For information on how to create layers, see
|
|
the "<link linkend='understanding-and-creating-layers'>Understanding and Creating Layers</link>" section.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='understand-what-gives-your-image-size'>
|
|
<title>Understand What Contributes to Your Image Size</title>
|
|
|
|
<para>
|
|
It is easiest to have something to start with when creating
|
|
your own distribution.
|
|
You can use the Yocto Project out-of-the-box to create the
|
|
<filename>poky-tiny</filename> distribution.
|
|
Ultimately, you will want to make changes in your own
|
|
distribution that are likely modeled after
|
|
<filename>poky-tiny</filename>.
|
|
<note>
|
|
To use <filename>poky-tiny</filename> in your build,
|
|
set the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO'><filename>DISTRO</filename></ulink>
|
|
variable in your
|
|
<filename>local.conf</filename> file to "poky-tiny"
|
|
as described in the
|
|
"<link linkend='creating-your-own-distribution'>Creating Your Own Distribution</link>"
|
|
section.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
Understanding some memory concepts will help you reduce the
|
|
system size.
|
|
Memory consists of static, dynamic, and temporary memory.
|
|
Static memory is the TEXT (code), DATA (initialized data
|
|
in the code), and BSS (uninitialized data) sections.
|
|
Dynamic memory represents memory that is allocated at runtime:
|
|
stacks, hash tables, and so forth.
|
|
Temporary memory is recovered after the boot process.
|
|
This memory consists of memory used for decompressing
|
|
the kernel and for the <filename>__init__</filename>
|
|
functions.
|
|
</para>
|
|
|
|
<para>
|
|
To help you see where you currently are with kernel and root
|
|
filesystem sizes, you can use two tools found in the
|
|
<link linkend='source-directory'>Source Directory</link> in
|
|
the <filename>scripts/tiny/</filename> directory:
|
|
<itemizedlist>
|
|
<listitem><para><filename>ksize.py</filename>: Reports
|
|
component sizes for the kernel build objects.
|
|
</para></listitem>
|
|
<listitem><para><filename>dirsize.py</filename>: Reports
|
|
component sizes for the root filesystem.</para></listitem>
|
|
</itemizedlist>
|
|
This next tool and command help you organize configuration
|
|
fragments and view file dependencies in a human-readable form:
|
|
<itemizedlist>
|
|
<listitem><para><filename>merge_config.sh</filename>:
|
|
Helps you manage configuration files and fragments
|
|
within the kernel.
|
|
With this tool, you can merge individual configuration
|
|
fragments together.
|
|
The tool allows you to make overrides and warns you
|
|
of any missing configuration options.
|
|
The tool is ideal for allowing you to iterate on
|
|
configurations, create minimal configurations, and
|
|
create configuration files for different machines
|
|
without having to duplicate your process.</para>
|
|
<para>The <filename>merge_config.sh</filename> script is
|
|
part of the Linux Yocto kernel Git repositories
|
|
(i.e. <filename>linux-yocto-3.14</filename>,
|
|
<filename>linux-yocto-3.10</filename>,
|
|
<filename>linux-yocto-3.8</filename>, and so forth)
|
|
in the
|
|
<filename>scripts/kconfig</filename> directory.</para>
|
|
<para>For more information on configuration fragments,
|
|
see the
|
|
"<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;#generating-configuration-files'>Generating Configuration Files</ulink>"
|
|
section of the Yocto Project Linux Kernel Development
|
|
Manual and the "<link linkend='creating-config-fragments'>Creating Configuration Fragments</link>"
|
|
section, which is in this manual.</para></listitem>
|
|
<listitem><para><filename>bitbake -u depexp -g <bitbake_target></filename>:
|
|
Using the BitBake command with these options brings up
|
|
a Dependency Explorer from which you can view file
|
|
dependencies.
|
|
Understanding these dependencies allows you to make
|
|
informed decisions when cutting out various pieces of the
|
|
kernel and root filesystem.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='trim-the-root-filesystem'>
|
|
<title>Trim the Root Filesystem</title>
|
|
|
|
<para>
|
|
The root filesystem is made up of packages for booting,
|
|
libraries, and applications.
|
|
To change things, you can configure how the packaging happens,
|
|
which changes the way you build them.
|
|
You can also tweak the filesystem itself or select a different
|
|
filesystem.
|
|
</para>
|
|
|
|
<para>
|
|
First, find out what is hogging your root filesystem by running the
|
|
<filename>dirsize.py</filename> script from your root directory:
|
|
<literallayout class='monospaced'>
|
|
$ cd <root-directory-of-image>
|
|
$ dirsize.py 100000 > dirsize-100k.log
|
|
$ cat dirsize-100k.log
|
|
</literallayout>
|
|
You can apply a filter to the script to ignore files under
|
|
a certain size.
|
|
The previous example filters out any files below 100 Kbytes.
|
|
The sizes reported by the tool are uncompressed, and thus
|
|
will be smaller by a relatively constant factor in a
|
|
compressed root filesystem.
|
|
When you examine your log file, you can focus on areas of the
|
|
root filesystem that take up large amounts of memory.
|
|
</para>
|
|
|
|
<para>
|
|
You need to be sure that what you eliminate does not cripple
|
|
the functionality you need.
|
|
One way to see how packages relate to each other is by using
|
|
the Dependency Explorer UI with the BitBake command:
|
|
<literallayout class='monospaced'>
|
|
$ cd <image-directory>
|
|
$ bitbake -u depexp -g <image>
|
|
</literallayout>
|
|
Use the interface to select potential packages you wish to
|
|
eliminate and see their dependency relationships.
|
|
</para>
|
|
|
|
<para>
|
|
When deciding how to reduce the size, get rid of packages that
|
|
result in minimal impact on the feature set.
|
|
For example, you might not need a VGA display.
|
|
Or, you might be able to get by with <filename>devtmpfs</filename>
|
|
and <filename>mdev</filename> instead of
|
|
<filename>udev</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Use your <filename>local.conf</filename> file to make changes.
|
|
For example, to eliminate <filename>udev</filename> and
|
|
<filename>glib</filename>, set the following in the
|
|
local configuration file:
|
|
<literallayout class='monospaced'>
|
|
VIRTUAL-RUNTIME_dev_manager = ""
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Finally, you should consider exactly the type of root
|
|
filesystem you need to meet your needs while also reducing
|
|
its size.
|
|
For example, consider <filename>cramfs</filename>,
|
|
<filename>squashfs</filename>, <filename>ubifs</filename>,
|
|
<filename>ext2</filename>, or an <filename>initramfs</filename>
|
|
using <filename>initramfs</filename>.
|
|
Be aware that <filename>ext3</filename> requires a 1 Mbyte
|
|
journal.
|
|
If you are okay with running read-only, you do not need this
|
|
journal.
|
|
</para>
|
|
|
|
<note>
|
|
After each round of elimination, you need to rebuild your
|
|
system and then use the tools to see the effects of your
|
|
reductions.
|
|
</note>
|
|
|
|
|
|
</section>
|
|
|
|
<section id='trim-the-kernel'>
|
|
<title>Trim the Kernel</title>
|
|
|
|
<para>
|
|
The kernel is built by including policies for hardware-independent
|
|
aspects.
|
|
What subsystems do you enable?
|
|
For what architecture are you building?
|
|
Which drivers do you build by default?
|
|
<note>You can modify the kernel source if you want to help
|
|
with boot time.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
Run the <filename>ksize.py</filename> script from the top-level
|
|
Linux build directory to get an idea of what is making up
|
|
the kernel:
|
|
<literallayout class='monospaced'>
|
|
$ cd <top-level-linux-build-directory>
|
|
$ ksize.py > ksize.log
|
|
$ cat ksize.log
|
|
</literallayout>
|
|
When you examine the log, you will see how much space is
|
|
taken up with the built-in <filename>.o</filename> files for
|
|
drivers, networking, core kernel files, filesystem, sound,
|
|
and so forth.
|
|
The sizes reported by the tool are uncompressed, and thus
|
|
will be smaller by a relatively constant factor in a compressed
|
|
kernel image.
|
|
Look to reduce the areas that are large and taking up around
|
|
the "90% rule."
|
|
</para>
|
|
|
|
<para>
|
|
To examine, or drill down, into any particular area, use the
|
|
<filename>-d</filename> option with the script:
|
|
<literallayout class='monospaced'>
|
|
$ ksize.py -d > ksize.log
|
|
</literallayout>
|
|
Using this option breaks out the individual file information
|
|
for each area of the kernel (e.g. drivers, networking, and
|
|
so forth).
|
|
</para>
|
|
|
|
<para>
|
|
Use your log file to see what you can eliminate from the kernel
|
|
based on features you can let go.
|
|
For example, if you are not going to need sound, you do not
|
|
need any drivers that support sound.
|
|
</para>
|
|
|
|
<para>
|
|
After figuring out what to eliminate, you need to reconfigure
|
|
the kernel to reflect those changes during the next build.
|
|
You could run <filename>menuconfig</filename> and make all your
|
|
changes at once.
|
|
However, that makes it difficult to see the effects of your
|
|
individual eliminations and also makes it difficult to replicate
|
|
the changes for perhaps another target device.
|
|
A better method is to start with no configurations using
|
|
<filename>allnoconfig</filename>, create configuration
|
|
fragments for individual changes, and then manage the
|
|
fragments into a single configuration file using
|
|
<filename>merge_config.sh</filename>.
|
|
The tool makes it easy for you to iterate using the
|
|
configuration change and build cycle.
|
|
</para>
|
|
|
|
<para>
|
|
Each time you make configuration changes, you need to rebuild
|
|
the kernel and check to see what impact your changes had on
|
|
the overall size.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='remove-package-management-requirements'>
|
|
<title>Remove Package Management Requirements</title>
|
|
|
|
<para>
|
|
Packaging requirements add size to the image.
|
|
One way to reduce the size of the image is to remove all the
|
|
packaging requirements from the image.
|
|
This reduction includes both removing the package manager
|
|
and its unique dependencies as well as removing the package
|
|
management data itself.
|
|
</para>
|
|
|
|
<para>
|
|
To eliminate all the packaging requirements for an image,
|
|
be sure that "package-management" is not part of your
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>
|
|
statement for the image.
|
|
When you remove this feature, you are removing the package
|
|
manager as well as its dependencies from the root filesystem.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='look-for-other-ways-to-minimize-size'>
|
|
<title>Look for Other Ways to Minimize Size</title>
|
|
|
|
<para>
|
|
Depending on your particular circumstances, other areas that you
|
|
can trim likely exist.
|
|
The key to finding these areas is through tools and methods
|
|
described here combined with experimentation and iteration.
|
|
Here are a couple of areas to experiment with:
|
|
<itemizedlist>
|
|
<listitem><para><filename>eglibc</filename>:
|
|
In general, follow this process:
|
|
<orderedlist>
|
|
<listitem><para>Remove <filename>eglibc</filename>
|
|
features from
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_FEATURES'><filename>DISTRO_FEATURES</filename></ulink>
|
|
that you think you do not need.</para></listitem>
|
|
<listitem><para>Build your distribution.
|
|
</para></listitem>
|
|
<listitem><para>If the build fails due to missing
|
|
symbols in a package, determine if you can
|
|
reconfigure the package to not need those
|
|
features.
|
|
For example, change the configuration to not
|
|
support wide character support as is done for
|
|
<filename>ncurses</filename>.
|
|
Or, if support for those characters is needed,
|
|
determine what <filename>eglibc</filename>
|
|
features provide the support and restore the
|
|
configuration.
|
|
</para></listitem>
|
|
<listitem><para>Rebuild and repeat the process.
|
|
</para></listitem>
|
|
</orderedlist></para></listitem>
|
|
<listitem><para><filename>busybox</filename>:
|
|
For BusyBox, use a process similar as described for
|
|
<filename>eglibc</filename>.
|
|
A difference is you will need to boot the resulting
|
|
system to see if you are able to do everything you
|
|
expect from the running system.
|
|
You need to be sure to integrate configuration fragments
|
|
into Busybox because BusyBox handles its own core
|
|
features and then allows you to add configuration
|
|
fragments on top.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='iterate-on-the-process'>
|
|
<title>Iterate on the Process</title>
|
|
|
|
<para>
|
|
If you have not reached your goals on system size, you need
|
|
to iterate on the process.
|
|
The process is the same.
|
|
Use the tools and see just what is taking up 90% of the root
|
|
filesystem and the kernel.
|
|
Decide what you can eliminate without limiting your device
|
|
beyond what you need.
|
|
</para>
|
|
|
|
<para>
|
|
Depending on your system, a good place to look might be
|
|
Busybox, which provides a stripped down
|
|
version of Unix tools in a single, executable file.
|
|
You might be able to drop virtual terminal services or perhaps
|
|
ipv6.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='working-with-packages'>
|
|
<title>Working with Packages</title>
|
|
|
|
<para>
|
|
This section describes a few tasks that involve packages:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
<link linkend='excluding-packages-from-an-image'>Excluding packages from an image</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='incrementing-a-package-revision-number'>Incrementing a package revision number</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='usingpoky-configuring-DISTRO_PN_ALIAS'>Handling a package name alias</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='handling-optional-module-packaging'>Handling optional module packaging</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='using-runtime-package-management'>Using Runtime Package Management</link>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<link linkend='testing-packages-with-ptest'>Setting up and running package test (ptest)</link>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<section id='excluding-packages-from-an-image'>
|
|
<title>Excluding Packages from an Image</title>
|
|
|
|
<para>
|
|
You might find it necessary to prevent specific packages
|
|
from being installed into an image.
|
|
If so, you can use several variables to direct the build
|
|
system to essentially ignore installing recommended packages
|
|
or to not install a package at all.
|
|
</para>
|
|
|
|
<para>
|
|
The following list introduces variables you can use to
|
|
prevent packages from being installed into your image.
|
|
Each of these variables only works with IPK and RPM
|
|
package types.
|
|
Support for Debian packages does not exist.
|
|
Also, you can use these variables from your
|
|
<filename>local.conf</filename> file or attach them to a
|
|
specific image recipe by using a recipe name override.
|
|
For more detail on the variables, see the descriptions in the
|
|
Yocto Project Reference Manual's glossary chapter.
|
|
<itemizedlist>
|
|
<listitem><para><ulink url='&YOCTO_DOCS_REF_URL;#var-BAD_RECOMMENDATIONS'><filename>BAD_RECOMMENDATIONS</filename></ulink>:
|
|
Use this variable to specify "recommended-only"
|
|
packages that you do not want installed.
|
|
</para></listitem>
|
|
<listitem><para><ulink url='&YOCTO_DOCS_REF_URL;#var-NO_RECOMMENDATIONS'><filename>NO_RECOMMENDATIONS</filename></ulink>:
|
|
Use this variable to prevent all "recommended-only"
|
|
packages from being installed.
|
|
</para></listitem>
|
|
<listitem><para><ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_EXCLUDE'><filename>PACKAGE_EXCLUDE</filename></ulink>:
|
|
Use this variable to prevent specific packages from
|
|
being installed regardless of whether they are
|
|
"recommended-only" or not.
|
|
You need to realize that the build process could
|
|
fail with an error when you
|
|
prevent the installation of a package whose presence
|
|
is required by an installed package.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='incrementing-a-package-revision-number'>
|
|
<title>Incrementing a Package Revision Number</title>
|
|
|
|
<para>
|
|
If a committed change results in changing the package output,
|
|
then the value of the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PR'><filename>PR</filename></ulink>
|
|
variable needs to be increased (or "bumped").
|
|
Increasing <filename>PR</filename> occurs one of two ways:
|
|
<itemizedlist>
|
|
<listitem><para>Automatically using a Package Revision
|
|
Service (PR Service).</para></listitem>
|
|
<listitem><para>Manually incrementing the
|
|
<filename>PR</filename> variable.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Given that one of the challenges any build system and its
|
|
users face is how to maintain a package feed that is compatible
|
|
with existing package manager applications such as
|
|
RPM, APT, and OPKG, using an automated system is much
|
|
preferred over a manual system.
|
|
In either system, the main requirement is that version
|
|
numbering increases in a linear fashion and that a number of
|
|
version components exist that support that linear progression.
|
|
</para>
|
|
|
|
<para>
|
|
The following two sections provide information on the PR Service
|
|
and on manual <filename>PR</filename> bumping.
|
|
</para>
|
|
|
|
<section id='working-with-a-pr-service'>
|
|
<title>Working With a PR Service</title>
|
|
|
|
<para>
|
|
As mentioned, attempting to maintain revision numbers in the
|
|
<ulink url='&YOCTO_DOCS_DEV_URL;#metadata'>Metadata</ulink>
|
|
is error prone, inaccurate, and causes problems for people
|
|
submitting recipes.
|
|
Conversely, the PR Service automatically generates
|
|
increasing numbers, particularly the revision field,
|
|
which removes the human element.
|
|
<note>
|
|
For additional information on using a PR Service, you
|
|
can see the
|
|
<ulink url='&YOCTO_WIKI_URL;/wiki/PR_Service'>PR Service</ulink>
|
|
wiki page.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
The Yocto Project uses variables in order of
|
|
decreasing priority to facilitate revision numbering (i.e.
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PE'><filename>PE</filename></ulink>,
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>, and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PR'><filename>PR</filename></ulink>
|
|
for epoch, version, and revision, respectively).
|
|
The values are highly dependent on the policies and
|
|
procedures of a given distribution and package feed.
|
|
</para>
|
|
|
|
<para>
|
|
Because the OpenEmbedded build system uses
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#checksums'>signatures</ulink>",
|
|
which are unique to a given build, the build system
|
|
knows when to rebuild packages.
|
|
All the inputs into a given task are represented by a
|
|
signature, which can trigger a rebuild when different.
|
|
Thus, the build system itself does not rely on the
|
|
<filename>PR</filename> numbers to trigger a rebuild.
|
|
The signatures, however, can be used to generate
|
|
<filename>PR</filename> values.
|
|
</para>
|
|
|
|
<para>
|
|
The PR Service works with both
|
|
<filename>OEBasic</filename> and
|
|
<filename>OEBasicHash</filename> generators.
|
|
The value of <filename>PR</filename> bumps when the
|
|
checksum changes and the different generator mechanisms
|
|
change signatures under different circumstances.
|
|
</para>
|
|
|
|
<para>
|
|
As implemented, the build system includes values from
|
|
the PR Service into the <filename>PR</filename> field as
|
|
an addition using the form "<filename>.x</filename>" so
|
|
<filename>r0</filename> becomes <filename>r0.1</filename>,
|
|
<filename>r0.2</filename> and so forth.
|
|
This scheme allows existing <filename>PR</filename> values
|
|
to be used for whatever reasons, which include manual
|
|
<filename>PR</filename> bumps, should it be necessary.
|
|
</para>
|
|
|
|
<para>
|
|
By default, the PR Service is not enabled or running.
|
|
Thus, the packages generated are just "self consistent".
|
|
The build system adds and removes packages and
|
|
there are no guarantees about upgrade paths but images
|
|
will be consistent and correct with the latest changes.
|
|
</para>
|
|
|
|
<para>
|
|
The simplest form for a PR Service is for it to exist
|
|
for a single host development system that builds the
|
|
package feed (building system).
|
|
For this scenario, you can enable a local PR Service by
|
|
setting
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PRSERV_HOST'><filename>PRSERV_HOST</filename></ulink>
|
|
in your <filename>local.conf</filename> file in the
|
|
<ulink url='&YOCTO_DOCS_DEV_URL;#build-directory'>Build Directory</ulink>:
|
|
<literallayout class='monospaced'>
|
|
PRSERV_HOST = "localhost:0"
|
|
</literallayout>
|
|
Once the service is started, packages will automatically
|
|
get increasing <filename>PR</filename> values and
|
|
BitBake will take care of starting and stopping the server.
|
|
</para>
|
|
|
|
<para>
|
|
If you have a more complex setup where multiple host
|
|
development systems work against a common, shared package
|
|
feed, you have a single PR Service running and it is
|
|
connected to each building system.
|
|
For this scenario, you need to start the PR Service using
|
|
the <filename>bitbake-prserv</filename> command:
|
|
<literallayout class='monospaced'>
|
|
bitbake-prserv ‐‐host <ip> ‐‐port <port> ‐‐start
|
|
</literallayout>
|
|
In addition to hand-starting the service, you need to
|
|
update the <filename>local.conf</filename> file of each
|
|
building system as described earlier so each system
|
|
points to the server and port.
|
|
</para>
|
|
|
|
<para>
|
|
It is also recommended you use build history, which adds
|
|
some sanity checks to package versions, in conjunction with
|
|
the server that is running the PR Service.
|
|
To enable build history, add the following to each building
|
|
system's <filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
# It is recommended to activate "buildhistory" for testing the PR service
|
|
INHERIT += "buildhistory"
|
|
BUILDHISTORY_COMMIT = "1"
|
|
</literallayout>
|
|
For information on build history, see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#maintaining-build-output-quality'>Maintaining Build Output Quality</ulink>"
|
|
section in the Yocto Project Reference Manual.
|
|
</para>
|
|
|
|
<note>
|
|
<para>The OpenEmbedded build system does not maintain
|
|
<filename>PR</filename> information as part of the
|
|
shared state (sstate) packages.
|
|
If you maintain an sstate feed, its expected that either
|
|
all your building systems that contribute to the sstate
|
|
feed use a shared PR Service, or you do not run a PR
|
|
Service on any of your building systems.
|
|
Having some systems use a PR Service while others do
|
|
not leads to obvious problems.</para>
|
|
<para>For more information on shared state, see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#shared-state-cache'>Shared State Cache</ulink>"
|
|
section in the Yocto Project Reference Manual.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id='manually-bumping-pr'>
|
|
<title>Manually Bumping PR</title>
|
|
|
|
<para>
|
|
The alternative to setting up a PR Service is to manually
|
|
bump the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PR'><filename>PR</filename></ulink>
|
|
variable.
|
|
</para>
|
|
|
|
<para>
|
|
If a committed change results in changing the package output,
|
|
then the value of the PR variable needs to be increased
|
|
(or "bumped") as part of that commit.
|
|
For new recipes you should add the <filename>PR</filename>
|
|
variable and set its initial value equal to "r0", which is the default.
|
|
Even though the default value is "r0", the practice of adding it to a new recipe makes
|
|
it harder to forget to bump the variable when you make changes
|
|
to the recipe in future.
|
|
</para>
|
|
|
|
<para>
|
|
If you are sharing a common <filename>.inc</filename> file with multiple recipes,
|
|
you can also use the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-INC_PR'>INC_PR</ulink></filename>
|
|
variable to ensure that
|
|
the recipes sharing the <filename>.inc</filename> file are rebuilt when the
|
|
<filename>.inc</filename> file itself is changed.
|
|
The <filename>.inc</filename> file must set <filename>INC_PR</filename>
|
|
(initially to "r0"), and all recipes referring to it should set <filename>PR</filename>
|
|
to "$(INC_PR).0" initially, incrementing the last number when the recipe is changed.
|
|
If the <filename>.inc</filename> file is changed then its
|
|
<filename>INC_PR</filename> should be incremented.
|
|
</para>
|
|
|
|
<para>
|
|
When upgrading the version of a package, assuming the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PV'>PV</ulink></filename>
|
|
changes, the <filename>PR</filename> variable should be
|
|
reset to "r0" (or "$(INC_PR).0" if you are using
|
|
<filename>INC_PR</filename>).
|
|
</para>
|
|
|
|
<para>
|
|
Usually, version increases occur only to packages.
|
|
However, if for some reason <filename>PV</filename> changes but does not
|
|
increase, you can increase the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PE'>PE</ulink></filename>
|
|
variable (Package Epoch).
|
|
The <filename>PE</filename> variable defaults to "0".
|
|
</para>
|
|
|
|
<para>
|
|
Version numbering strives to follow the
|
|
<ulink url='http://www.debian.org/doc/debian-policy/ch-controlfields.html'>
|
|
Debian Version Field Policy Guidelines</ulink>.
|
|
These guidelines define how versions are compared and what "increasing" a version means.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="usingpoky-configuring-DISTRO_PN_ALIAS">
|
|
<title>Handling a Package Name Alias</title>
|
|
<para>
|
|
Sometimes a package name you are using might exist under
|
|
an alias or as a similarly named package in a different
|
|
distribution.
|
|
The OpenEmbedded build system implements a
|
|
<filename>do_distro_check</filename>
|
|
task that automatically connects to major distributions
|
|
and checks for these situations.
|
|
If the package exists under a different name in a different
|
|
distribution, you get a <filename>distro_check</filename>
|
|
mismatch.
|
|
You can resolve this problem by defining a per-distro recipe
|
|
name alias using the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_PN_ALIAS'>DISTRO_PN_ALIAS</ulink></filename>
|
|
variable.
|
|
</para>
|
|
|
|
<para>
|
|
Following is an example that shows how you specify the <filename>DISTRO_PN_ALIAS</filename>
|
|
variable:
|
|
<literallayout class='monospaced'>
|
|
DISTRO_PN_ALIAS_pn-PACKAGENAME = "distro1=package_name_alias1 \
|
|
distro2=package_name_alias2 \
|
|
distro3=package_name_alias3 \
|
|
..."
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
If you have more than one distribution alias, separate them with a space.
|
|
Note that the build system currently automatically checks the
|
|
Fedora, OpenSUSE, Debian, Ubuntu,
|
|
and Mandriva distributions for source package recipes without having to specify them
|
|
using the <filename>DISTRO_PN_ALIAS</filename> variable.
|
|
For example, the following command generates a report that lists the Linux distributions
|
|
that include the sources for each of the recipes.
|
|
<literallayout class='monospaced'>
|
|
$ bitbake world -f -c distro_check
|
|
</literallayout>
|
|
The results are stored in the <filename>build/tmp/log/distro_check-${DATETIME}.results</filename>
|
|
file found in the
|
|
<link linkend='source-directory'>Source Directory</link>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='handling-optional-module-packaging'>
|
|
<title>Handling Optional Module Packaging</title>
|
|
|
|
<para>
|
|
Many pieces of software split functionality into optional
|
|
modules (or plug-ins) and the plug-ins that are built
|
|
might depend on configuration options.
|
|
To avoid having to duplicate the logic that determines what
|
|
modules are available in your recipe or to avoid having
|
|
to package each module by hand, the OpenEmbedded build system
|
|
provides functionality to handle module packaging dynamically.
|
|
</para>
|
|
|
|
<para>
|
|
To handle optional module packaging, you need to do two things:
|
|
<itemizedlist>
|
|
<listitem><para>Ensure the module packaging is actually
|
|
done.</para></listitem>
|
|
<listitem><para>Ensure that any dependencies on optional
|
|
modules from other recipes are satisfied by your recipe.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<section id='making-sure-the-packaging-is-done'>
|
|
<title>Making Sure the Packaging is Done</title>
|
|
|
|
<para>
|
|
To ensure the module packaging actually gets done, you use
|
|
the <filename>do_split_packages</filename> function within
|
|
the <filename>populate_packages</filename> Python function
|
|
in your recipe.
|
|
The <filename>do_split_packages</filename> function
|
|
searches for a pattern of files or directories under a
|
|
specified path and creates a package for each one it finds
|
|
by appending to the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'><filename>PACKAGES</filename></ulink>
|
|
variable and setting the appropriate values for
|
|
<filename>FILES_packagename</filename>,
|
|
<filename>RDEPENDS_packagename</filename>,
|
|
<filename>DESCRIPTION_packagename</filename>, and so forth.
|
|
Here is an example from the <filename>lighttpd</filename>
|
|
recipe:
|
|
<literallayout class='monospaced'>
|
|
python populate_packages_prepend () {
|
|
lighttpd_libdir = d.expand('${libdir}')
|
|
do_split_packages(d, lighttpd_libdir, '^mod_(.*)\.so$',
|
|
'lighttpd-module-%s', 'Lighttpd module for %s',
|
|
extra_depends='')
|
|
}
|
|
</literallayout>
|
|
The previous example specifies a number of things in the
|
|
call to <filename>do_split_packages</filename>.
|
|
<itemizedlist>
|
|
<listitem><para>A directory within the files installed
|
|
by your recipe through <filename>do_install</filename>
|
|
in which to search.</para></listitem>
|
|
<listitem><para>A regular expression used to match module
|
|
files in that directory.
|
|
In the example, note the parentheses () that mark
|
|
the part of the expression from which the module
|
|
name should be derived.</para></listitem>
|
|
<listitem><para>A pattern to use for the package names.
|
|
</para></listitem>
|
|
<listitem><para>A description for each package.
|
|
</para></listitem>
|
|
<listitem><para>An empty string for
|
|
<filename>extra_depends</filename>, which disables
|
|
the default dependency on the main
|
|
<filename>lighttpd</filename> package.
|
|
Thus, if a file in <filename>${libdir}</filename>
|
|
called <filename>mod_alias.so</filename> is found,
|
|
a package called <filename>lighttpd-module-alias</filename>
|
|
is created for it and the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DESCRIPTION'><filename>DESCRIPTION</filename></ulink>
|
|
is set to "Lighttpd module for alias".</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Often, packaging modules is as simple as the previous
|
|
example.
|
|
However, more advanced options exist that you can use
|
|
within <filename>do_split_packages</filename> to modify its
|
|
behavior.
|
|
And, if you need to, you can add more logic by specifying
|
|
a hook function that is called for each package.
|
|
It is also perfectly acceptable to call
|
|
<filename>do_split_packages</filename> multiple times if
|
|
you have more than one set of modules to package.
|
|
</para>
|
|
|
|
<para>
|
|
For more examples that show how to use
|
|
<filename>do_split_packages</filename>, see the
|
|
<filename>connman.inc</filename> file in the
|
|
<filename>meta/recipes-connectivity/connman/</filename>
|
|
directory of the <filename>poky</filename>
|
|
<link linkend='yocto-project-repositories'>source repository</link>.
|
|
You can also find examples in
|
|
<filename>meta/classes/kernel.bbclass</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Following is a reference that shows
|
|
<filename>do_split_packages</filename> mandatory and
|
|
optional arguments:
|
|
<literallayout class='monospaced'>
|
|
Mandatory arguments
|
|
|
|
root
|
|
The path in which to search
|
|
file_regex
|
|
Regular expression to match searched files.
|
|
Use parentheses () to mark the part of this
|
|
expression that should be used to derive the
|
|
module name (to be substituted where %s is
|
|
used in other function arguments as noted below)
|
|
output_pattern
|
|
Pattern to use for the package names. Must
|
|
include %s.
|
|
description
|
|
Description to set for each package. Must
|
|
include %s.
|
|
|
|
Optional arguments
|
|
|
|
postinst
|
|
Postinstall script to use for all packages
|
|
(as a string)
|
|
recursive
|
|
True to perform a recursive search - default
|
|
False
|
|
hook
|
|
A hook function to be called for every match.
|
|
The function will be called with the following
|
|
arguments (in the order listed):
|
|
|
|
f
|
|
Full path to the file/directory match
|
|
pkg
|
|
The package name
|
|
file_regex
|
|
As above
|
|
output_pattern
|
|
As above
|
|
modulename
|
|
The module name derived using file_regex
|
|
|
|
extra_depends
|
|
Extra runtime dependencies (RDEPENDS) to be
|
|
set for all packages. The default value of None
|
|
causes a dependency on the main package
|
|
(${PN}) - if you do not want this, pass empty
|
|
string '' for this parameter.
|
|
aux_files_pattern
|
|
Extra item(s) to be added to FILES for each
|
|
package. Can be a single string item or a list
|
|
of strings for multiple items. Must include %s.
|
|
postrm
|
|
postrm script to use for all packages (as a
|
|
string)
|
|
allow_dirs
|
|
True to allow directories to be matched -
|
|
default False
|
|
prepend
|
|
If True, prepend created packages to PACKAGES
|
|
instead of the default False which appends them
|
|
match_path
|
|
match file_regex on the whole relative path to
|
|
the root rather than just the file name
|
|
aux_files_pattern_verbatim
|
|
Extra item(s) to be added to FILES for each
|
|
package, using the actual derived module name
|
|
rather than converting it to something legal
|
|
for a package name. Can be a single string item
|
|
or a list of strings for multiple items. Must
|
|
include %s.
|
|
allow_links
|
|
True to allow symlinks to be matched - default
|
|
False
|
|
summary
|
|
Summary to set for each package. Must include %s;
|
|
defaults to description if not set.
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='satisfying-dependencies'>
|
|
<title>Satisfying Dependencies</title>
|
|
|
|
<para>
|
|
The second part for handling optional module packaging
|
|
is to ensure that any dependencies on optional modules
|
|
from other recipes are satisfied by your recipe.
|
|
You can be sure these dependencies are satisfied by
|
|
using the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES_DYNAMIC'><filename>PACKAGES_DYNAMIC</filename></ulink> variable.
|
|
Here is an example that continues with the
|
|
<filename>lighttpd</filename> recipe shown earlier:
|
|
<literallayout class='monospaced'>
|
|
PACKAGES_DYNAMIC = "lighttpd-module-.*"
|
|
</literallayout>
|
|
The name specified in the regular expression can of
|
|
course be anything.
|
|
In this example, it is <filename>lighttpd-module-</filename>
|
|
and is specified as the prefix to ensure that any
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-RDEPENDS'><filename>RDEPENDS</filename></ulink>
|
|
and <ulink url='&YOCTO_DOCS_REF_URL;#var-RRECOMMENDS'><filename>RRECOMMENDS</filename></ulink>
|
|
on a package name starting with the prefix are satisfied
|
|
during build time.
|
|
If you are using <filename>do_split_packages</filename>
|
|
as described in the previous section, the value you put in
|
|
<filename>PACKAGES_DYNAMIC</filename> should correspond to
|
|
the name pattern specified in the call to
|
|
<filename>do_split_packages</filename>.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='using-runtime-package-management'>
|
|
<title>Using Runtime Package Management</title>
|
|
|
|
<para>
|
|
During a build, BitBake always transforms a recipe into one or
|
|
more packages.
|
|
For example, BitBake takes the <filename>bash</filename> recipe
|
|
and currently produces the <filename>bash-dbg</filename>,
|
|
<filename>bash-staticdev</filename>,
|
|
<filename>bash-dev</filename>, <filename>bash-doc</filename>,
|
|
<filename>bash-locale</filename>, and
|
|
<filename>bash</filename> packages.
|
|
Not all generated packages are included in an image.
|
|
</para>
|
|
|
|
<para>
|
|
In several situations, you might need to update, add, remove,
|
|
or query the packages on a target device at runtime
|
|
(i.e. without having to generate a new image).
|
|
Examples of such situations include:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
You want to provide in-the-field updates to deployed
|
|
devices (e.g. security updates).
|
|
</para></listitem>
|
|
<listitem><para>
|
|
You want to have a fast turn-around development cycle
|
|
for one or more applications that run on your device.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
You want to temporarily install the "debug" packages
|
|
of various applications on your device so that
|
|
debugging can be greatly improved by allowing
|
|
access to symbols and source debugging.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
You want to deploy a more minimal package selection of
|
|
your device but allow in-the-field updates to add a
|
|
larger selection for customization.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
In all these situations, you have something similar to a more
|
|
traditional Linux distribution in that in-field devices
|
|
are able to receive pre-compiled packages from a server for
|
|
installation or update.
|
|
Being able to install these packages on a running,
|
|
in-field device is what is termed "runtime package
|
|
management".
|
|
</para>
|
|
|
|
<para>
|
|
In order to use runtime package management, you
|
|
need a host/server machine that serves up the pre-compiled
|
|
packages plus the required metadata.
|
|
You also need package manipulation tools on the target.
|
|
The build machine is a likely candidate to act as the server.
|
|
However, that machine does not necessarily have to be the
|
|
package server.
|
|
The build machine could push its artifacts to another machine
|
|
that acts as the server (e.g. Internet-facing).
|
|
</para>
|
|
|
|
<para>
|
|
A simple build that targets just one device produces
|
|
more than one package database.
|
|
In other words, the packages produced by a build are separated
|
|
out into a couple of different package groupings based on
|
|
criteria such as the target's CPU architecture, the target
|
|
board, or the C library used on the target.
|
|
For example, a build targeting the <filename>qemuarm</filename>
|
|
device produces the following three package databases:
|
|
<filename>all</filename>, <filename>armv5te</filename>, and
|
|
<filename>qemuarm</filename>.
|
|
If you wanted your <filename>qemuarm</filename> device to be
|
|
aware of all the packages that were available to it,
|
|
you would need to point it to each of these databases
|
|
individually.
|
|
In a similar way, a traditional Linux distribution usually is
|
|
configured to be aware of a number of software repositories
|
|
from which it retrieves packages.
|
|
</para>
|
|
|
|
<para>
|
|
Using runtime package management is completely optional and
|
|
not required for a successful build or deployment in any
|
|
way.
|
|
But if you want to make use of runtime package management,
|
|
you need to do a couple things above and beyond the basics.
|
|
The remainder of this section describes what you need to do.
|
|
</para>
|
|
|
|
<section id='runtime-package-management-build'>
|
|
<title>Build Considerations</title>
|
|
|
|
<para>
|
|
This section describes build considerations that you need
|
|
to be aware of in order to provide support for runtime
|
|
package management.
|
|
</para>
|
|
|
|
<para>
|
|
When BitBake generates packages it needs to know
|
|
what format or formats to use.
|
|
In your configuration, you use the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_CLASSES'><filename>PACKAGE_CLASSES</filename></ulink>
|
|
variable to specify the format.
|
|
<note>
|
|
You can choose to have more than one format but you must
|
|
provide at least one.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
If you would like your image to start off with a basic
|
|
package database of the packages in your current build
|
|
as well as have the relevant tools available on the
|
|
target for runtime package management, you can include
|
|
"package-management" in the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>
|
|
variable.
|
|
Including "package-management" in this
|
|
configuration variable ensures that when the image
|
|
is assembled for your target, the image includes
|
|
the currently-known package databases as well as
|
|
the target-specific tools required for runtime
|
|
package management to be performed on the target.
|
|
However, this is not strictly necessary.
|
|
You could start your image off without any databases
|
|
but only include the required on-target package
|
|
tool(s).
|
|
As an example, you could include "opkg" in your
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_INSTALL'><filename>IMAGE_INSTALL</filename></ulink>
|
|
variable if you are using the IPK package format.
|
|
You can then initialize your target's package database(s)
|
|
later once your image is up and running.
|
|
</para>
|
|
|
|
<para>
|
|
Whenever you perform any sort of build step that can
|
|
potentially generate a package or modify an existing
|
|
package, it is always a good idea to re-generate the
|
|
package index with:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake package-index
|
|
</literallayout>
|
|
Realize that it is not sufficient to simply do the
|
|
following:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake <some-package> package-index
|
|
</literallayout>
|
|
This is because BitBake does not properly schedule the
|
|
<filename>package-index</filename> target fully after any
|
|
other target has completed.
|
|
Thus, be sure to run the package update step separately.
|
|
</para>
|
|
|
|
<para>
|
|
As described below in the
|
|
"<link linkend='runtime-package-management-target-ipk'>Using IPK</link>"
|
|
section, if you are using IPK as your package format, you
|
|
can make use of the
|
|
<filename>distro-feed-configs</filename> recipe provided
|
|
by <filename>meta-oe</filename> in order to configure your
|
|
target to use your IPK databases.
|
|
</para>
|
|
|
|
<para>
|
|
When your build is complete, your packages reside in the
|
|
<filename>${TMPDIR}/deploy/<package-format></filename>
|
|
directory.
|
|
For example, if <filename>${TMPDIR}</filename>
|
|
is <filename>tmp</filename> and your selected package type
|
|
is IPK, then your IPK packages are available in
|
|
<filename>tmp/deploy/ipk</filename>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='runtime-package-management-server'>
|
|
<title>Host or Server Machine Setup</title>
|
|
|
|
<para>
|
|
Typically, packages are served from a server using
|
|
HTTP.
|
|
However, other protocols are possible.
|
|
If you want to use HTTP, then setup and configure a
|
|
web server, such as Apache 2 or lighttpd, on the machine
|
|
serving the packages.
|
|
</para>
|
|
|
|
<para>
|
|
As previously mentioned, the build machine can act as the
|
|
package server.
|
|
In the following sections that describe server machine
|
|
setups, the build machine is assumed to also be the server.
|
|
</para>
|
|
|
|
<section id='package-server-apache'>
|
|
<title>Serving Packages via Apache 2</title>
|
|
|
|
<para>
|
|
This example assumes you are using the Apache 2
|
|
server:
|
|
<orderedlist>
|
|
<listitem><para>
|
|
Add the directory to your Apache
|
|
configuration, which you can find at
|
|
<filename>/etc/httpd/conf/httpd.conf</filename>.
|
|
Use commands similar to these on the
|
|
development system.
|
|
These example commands assume a top-level
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
named <filename>poky</filename> in your home
|
|
directory.
|
|
The example also assumes an RPM package type.
|
|
If you are using a different package type, such
|
|
as IPK, use "ipk" in the pathnames:
|
|
<literallayout class='monospaced'>
|
|
<VirtualHost *:80>
|
|
....
|
|
Alias /rpm ~/poky/build/tmp/deploy/rpm
|
|
<Directory "~/poky/build/tmp/deploy/rpm">
|
|
Options +Indexes
|
|
</Directory>
|
|
</VirtualHost>
|
|
</literallayout></para></listitem>
|
|
<listitem><para>
|
|
Reload the Apache configuration as described
|
|
in this step.
|
|
For all commands, be sure you have root
|
|
privileges.
|
|
</para>
|
|
|
|
<para>
|
|
If your development system is using Fedora or
|
|
CentOS, use the following:
|
|
<literallayout class='monospaced'>
|
|
# service httpd reload
|
|
</literallayout>
|
|
For Ubuntu and Debian, use the following:
|
|
<literallayout class='monospaced'>
|
|
# /etc/init.d/apache2 reload
|
|
</literallayout>
|
|
For OpenSUSE, use the following:
|
|
<literallayout class='monospaced'>
|
|
# /etc/init.d/apache2 reload
|
|
</literallayout></para></listitem>
|
|
<listitem><para>
|
|
If you are using Security-Enhanced Linux
|
|
(SELinux), you need to label the files as
|
|
being accessible through Apache.
|
|
Use the following command from the development
|
|
host.
|
|
This example assumes RPM package types:
|
|
<literallayout class='monospaced'>
|
|
# chcon -R -h -t httpd_sys_content_t tmp/deploy/rpm
|
|
</literallayout></para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='package-server-lighttpd'>
|
|
<title>Serving Packages via lighttpd</title>
|
|
|
|
<para>
|
|
If you are using lighttpd, all you need
|
|
to do is to provide a link from your
|
|
<filename>${TMPDIR}/deploy/<package-format></filename>
|
|
directory to lighttpd's document-root.
|
|
You can determine the specifics of your lighttpd
|
|
installation by looking through its configuration file,
|
|
which is usually found at:
|
|
<filename>/etc/lighttpd/lighttpd.conf</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
For example, if you are using IPK, lighttpd's
|
|
document-root is set to
|
|
<filename>/var/www/lighttpd</filename>, and you had
|
|
packages for a target named "BOARD",
|
|
then you might create a link from your build location
|
|
to lighttpd's document-root as follows:
|
|
<literallayout class='monospaced'>
|
|
# ln -s $(PWD)/tmp/deploy/ipk /var/www/lighttpd/BOARD-dir
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
At this point, you need to start the lighttpd server.
|
|
The method used to start the server varies by
|
|
distribution.
|
|
However, one basic method that starts it by hand is:
|
|
<literallayout class='monospaced'>
|
|
# lighttpd -f /etc/lighttpd/lighttpd.conf
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='runtime-package-management-target'>
|
|
<title>Target Setup</title>
|
|
|
|
<para>
|
|
Setting up the target differs depending on the
|
|
package management system.
|
|
This section provides information for RPM and IPK.
|
|
</para>
|
|
|
|
<section id='runtime-package-management-target-rpm'>
|
|
<title>Using RPM</title>
|
|
|
|
<para>
|
|
The application for performing runtime package
|
|
management of RPM packages on the target is called
|
|
<filename>smart</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
On the target machine, you need to inform
|
|
<filename>smart</filename> of every package database
|
|
you want to use.
|
|
As an example, suppose your target device can use the
|
|
following three package databases from a server named
|
|
<filename>server.name</filename>:
|
|
<filename>all</filename>, <filename>i586</filename>,
|
|
and <filename>qemux86</filename>.
|
|
Given this example, issue the following commands on the
|
|
target:
|
|
<literallayout class='monospaced'>
|
|
# smart channel ‐‐add all type=rpm-md baseurl=http://server.name/rpm/all
|
|
# smart channel ‐‐add i585 type=rpm-md baseurl=http://server.name/rpm/i586
|
|
# smart channel ‐‐add qemux86 type=rpm-md baseurl=http://server.name/rpm/qemux86
|
|
</literallayout>
|
|
Also from the target machine, fetch the repository
|
|
information using this command:
|
|
<literallayout class='monospaced'>
|
|
# smart update
|
|
</literallayout>
|
|
You can now use the <filename>smart query</filename>
|
|
and <filename>smart install</filename> commands to
|
|
find and install packages from the repositories.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='runtime-package-management-target-ipk'>
|
|
<title>Using IPK</title>
|
|
|
|
<para>
|
|
The application for performing runtime package
|
|
management of IPK packages on the target is called
|
|
<filename>opkg</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
In order to inform <filename>opkg</filename> of the
|
|
package databases you want to use, simply create one
|
|
or more <filename>*.conf</filename> files in the
|
|
<filename>/etc/opkg</filename> directory on the target.
|
|
The <filename>opkg</filename> application uses them
|
|
to find its available package databases.
|
|
As an example, suppose you configured your HTTP server
|
|
on your machine named
|
|
<filename>www.mysite.com</filename> to serve files
|
|
from a <filename>BOARD-dir</filename> directory under
|
|
its document-root.
|
|
In this case, you might create a configuration
|
|
file on the target called
|
|
<filename>/etc/opkg/base-feeds.conf</filename> that
|
|
contains:
|
|
<literallayout class='monospaced'>
|
|
src/gz all http://www.mysite.com/BOARD-dir/all
|
|
src/gz armv7a http://www.mysite.com/BOARD-dir/armv7a
|
|
src/gz beaglebone http://www.mysite.com/BOARD-dir/beaglebone
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
As a way of making it easier to generate and make
|
|
these IPK configuration files available on your
|
|
target, simply define
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-FEED_DEPLOYDIR_BASE_URI'><filename>FEED_DEPLOYDIR_BASE_URI</filename></ulink>
|
|
to point to your server and the location within the
|
|
document-root which contains the databases.
|
|
For example: if you are serving your packages over
|
|
HTTP, your server's IP address is 192.168.7.1, and
|
|
your databases are located in a directory called
|
|
<filename>BOARD-dir</filename> underneath your HTTP
|
|
server's document-root, you need to set
|
|
<filename>FEED_DEPLOYDIR_BASE_URI</filename> to
|
|
<filename>http://192.168.7.1/BOARD-dir</filename> and
|
|
a set of configuration files will be generated for you
|
|
in your target to work with this feed.
|
|
</para>
|
|
|
|
<para>
|
|
On the target machine, fetch (or refresh) the
|
|
repository information using this command:
|
|
<literallayout class='monospaced'>
|
|
# opkg update
|
|
</literallayout>
|
|
You can now use the <filename>opkg list</filename> and
|
|
<filename>opkg install</filename> commands to find and
|
|
install packages from the repositories.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='testing-packages-with-ptest'>
|
|
<title>Testing Packages With ptest</title>
|
|
|
|
<para>
|
|
A Package Test (ptest) runs tests against packages built
|
|
by the OpenEmbedded build system on the target machine.
|
|
A ptest contains at least two items: the actual test, and
|
|
a shell script (<filename>run-ptest</filename>) that starts
|
|
the test.
|
|
The shell script that starts the test must not contain
|
|
the actual test, the script only starts it.
|
|
On the other hand, the test can be anything from a simple
|
|
shell script that runs a binary and checks the output to
|
|
an elaborate system of test binaries and data files.
|
|
</para>
|
|
|
|
<para>
|
|
The test generates output in the format used by
|
|
Automake:
|
|
<literallayout class='monospaced'>
|
|
<result>: <testname>
|
|
</literallayout>
|
|
where the result can be <filename>PASS</filename>,
|
|
<filename>FAIL</filename>, or <filename>SKIP</filename>,
|
|
and the testname can be any identifying string.
|
|
</para>
|
|
|
|
<note>
|
|
A recipe is "ptest-enabled" if it inherits the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-ptest'><filename>ptest</filename></ulink>
|
|
class.
|
|
</note>
|
|
|
|
<section id='adding-ptest-to-your-build'>
|
|
<title>Adding ptest to Your Build</title>
|
|
|
|
<para>
|
|
To add package testing to your build, add the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_FEATURES'><filename>DISTRO_FEATURES</filename></ulink>
|
|
and <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_IMAGE_FEATURES'><filename>EXTRA_IMAGE_FEATURES</filename></ulink>
|
|
variables to your <filename>local.conf</filename> file,
|
|
which is found in the
|
|
<link linkend='build-directory'>Build Directory</link>:
|
|
<literallayout class='monospaced'>
|
|
DISTRO_FEATURES_append = " ptest"
|
|
EXTRA_IMAGE_FEATURES += "ptest-pkgs"
|
|
</literallayout>
|
|
Once your build is complete, the ptest files are installed
|
|
into the <filename>/usr/lib/<package>/ptest</filename>
|
|
directory within the image, where
|
|
<filename><package></filename> is the name of the
|
|
package.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='running-ptest'>
|
|
<title>Running ptest</title>
|
|
|
|
<para>
|
|
The <filename>ptest-runner</filename> package installs a
|
|
shell script that loops through all installed ptest test
|
|
suites and runs them in sequence.
|
|
Consequently, you might want to add this package to
|
|
your image.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='getting-your-package-ready'>
|
|
<title>Getting Your Package Ready</title>
|
|
|
|
<para>
|
|
In order to enable a recipe to run installed ptests
|
|
on target hardware,
|
|
you need to prepare the recipes that build the packages
|
|
you want to test.
|
|
Here is what you have to do for each recipe:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Be sure the recipe
|
|
inherits the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-ptest'><filename>ptest</filename></ulink>
|
|
class:</emphasis>
|
|
Include the following line in each recipe:
|
|
<literallayout class='monospaced'>
|
|
inherit ptest
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Create <filename>run-ptest</filename>:</emphasis>
|
|
This script starts your test.
|
|
Locate the script where you will refer to it
|
|
using
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>.
|
|
Here is an example that starts a test for
|
|
<filename>dbus</filename>:
|
|
<literallayout class='monospaced'>
|
|
#!/bin/sh
|
|
cd test
|
|
make -k runtest-TESTS
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Ensure dependencies are
|
|
met:</emphasis>
|
|
If the test adds build or runtime dependencies
|
|
that normally do not exist for the package
|
|
(such as requiring "make" to run the test suite),
|
|
use the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>
|
|
and
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-RDEPENDS'><filename>RDEPENDS</filename></ulink>
|
|
variables in your recipe in order for the package
|
|
to meet the dependencies.
|
|
Here is an example where the package has a runtime
|
|
dependency on "make":
|
|
<literallayout class='monospaced'>
|
|
RDEPENDS_${PN}-ptest += "make"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Add a function to build the
|
|
test suite:</emphasis>
|
|
Not many packages support cross-compilation of
|
|
their test suites.
|
|
Consequently, you usually need to add a
|
|
cross-compilation function to the package.
|
|
</para>
|
|
<para>Many packages based on Automake compile and
|
|
run the test suite by using a single command
|
|
such as <filename>make check</filename>.
|
|
However, the native <filename>make check</filename>
|
|
builds and runs on the same computer, while
|
|
cross-compiling requires that the package is built
|
|
on the host but executed on the target.
|
|
The built version of Automake that ships with the
|
|
Yocto Project includes a patch that separates
|
|
building and execution.
|
|
Consequently, packages that use the unaltered,
|
|
patched version of <filename>make check</filename>
|
|
automatically cross-compiles.</para>
|
|
<para>However, you still must add a
|
|
<filename>do_compile_ptest</filename> function to
|
|
build the test suite.
|
|
Add a function similar to the following to your
|
|
recipe:
|
|
<literallayout class='monospaced'>
|
|
do_compile_ptest() {
|
|
oe_runmake buildtest-TESTS
|
|
}
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Ensure special configurations
|
|
are set:</emphasis>
|
|
If the package requires special configurations
|
|
prior to compiling the test code, you must
|
|
insert a <filename>do_configure_ptest</filename>
|
|
function into the recipe.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Install the test
|
|
suite:</emphasis>
|
|
The <filename>ptest</filename> class
|
|
automatically copies the file
|
|
<filename>run-ptest</filename> to the target and
|
|
then runs make <filename>install-ptest</filename>
|
|
to run the tests.
|
|
If this is not enough, you need to create a
|
|
<filename>do_install_ptest</filename> function and
|
|
make sure it gets called after the
|
|
"make install-ptest" completes.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='working-with-source-files'>
|
|
<title>Working with Source Files</title>
|
|
|
|
<para>
|
|
The OpenEmbedded build system works with source files located
|
|
through the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
variable.
|
|
When you build something using BitBake, a big part of the operation
|
|
is locating and downloading all the source tarballs.
|
|
For images, downloading all the source for various packages can
|
|
take a significant amount of time.
|
|
</para>
|
|
|
|
<para>
|
|
This section presents information for working with source
|
|
files that can lead to more efficient use of resources and
|
|
time.
|
|
</para>
|
|
|
|
<section id='setting-up-effective-mirrors'>
|
|
<title>Setting up Effective Mirrors</title>
|
|
|
|
<para>
|
|
As mentioned, a good deal that goes into a Yocto Project
|
|
build is simply downloading all of the source tarballs.
|
|
Maybe you have been working with another build system
|
|
(OpenEmbedded or Angstrom) for which you have built up a
|
|
sizable directory of source tarballs.
|
|
Or, perhaps someone else has such a directory for which you
|
|
have read access.
|
|
If so, you can save time by adding statements to your
|
|
configuration file so that the build process checks local
|
|
directories first for existing tarballs before checking the
|
|
Internet.
|
|
</para>
|
|
|
|
<para>
|
|
Here is an efficient way to set it up in your
|
|
<filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
SOURCE_MIRROR_URL ?= "file:///home/you/your-download-dir/"
|
|
INHERIT += "own-mirrors"
|
|
BB_GENERATE_MIRROR_TARBALLS = "1"
|
|
# BB_NO_NETWORK = "1"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
In the previous example, the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BB_GENERATE_MIRROR_TARBALLS'><filename>BB_GENERATE_MIRROR_TARBALLS</filename></ulink>
|
|
variable causes the OpenEmbedded build system to generate
|
|
tarballs of the Git repositories and store them in the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DL_DIR'><filename>DL_DIR</filename></ulink>
|
|
directory.
|
|
Due to performance reasons, generating and storing these
|
|
tarballs is not the build system's default behavior.
|
|
</para>
|
|
|
|
<para>
|
|
You can also use the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PREMIRRORS'><filename>PREMIRRORS</filename></ulink>
|
|
variable.
|
|
For an example, see the variable's glossary entry in the
|
|
Yocto Project Reference Manual.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='getting-source-files-and-suppressing-the-build'>
|
|
<title>Getting Source Files and Suppressing the Build</title>
|
|
|
|
<para>
|
|
Another technique you can use to ready yourself for a
|
|
successive string of build operations, is to pre-fetch
|
|
all the source files without actually starting a build.
|
|
This technique lets you work through any download issues
|
|
and ultimately gathers all the source files into your
|
|
download directory
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-build-downloads'><filename>build/downloads</filename></ulink>,
|
|
which is located with
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DL_DIR'><filename>DL_DIR</filename></ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
Use the following BitBake command form to fetch all the
|
|
necessary sources without starting the build:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake -c fetchall <target>
|
|
</literallayout>
|
|
This variation of the BitBake command guarantees that you
|
|
have all the sources for that BitBake target should you
|
|
disconnect from the Internet and want to do the build
|
|
later offline.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="building-software-from-an-external-source">
|
|
<title>Building Software from an External Source</title>
|
|
|
|
<para>
|
|
By default, the OpenEmbedded build system uses the
|
|
<link linkend='build-directory'>Build Directory</link> to
|
|
build source code.
|
|
The build process involves fetching the source files, unpacking
|
|
them, and then patching them if necessary before the build takes
|
|
place.
|
|
</para>
|
|
|
|
<para>
|
|
Situations exist where you might want to build software from source
|
|
files that are external to and thus outside of the
|
|
OpenEmbedded build system.
|
|
For example, suppose you have a project that includes a new BSP with
|
|
a heavily customized kernel.
|
|
And, you want to minimize exposing the build system to the
|
|
development team so that they can focus on their project and
|
|
maintain everyone's workflow as much as possible.
|
|
In this case, you want a kernel source directory on the development
|
|
machine where the development occurs.
|
|
You want the recipe's
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
variable to point to the external directory and use it as is, not
|
|
copy it.
|
|
</para>
|
|
|
|
<para>
|
|
To build from software that comes from an external source, all you
|
|
need to do is inherit the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-externalsrc'><filename>externalsrc</filename></ulink>
|
|
class and then set the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-EXTERNALSRC'><filename>EXTERNALSRC</filename></ulink>
|
|
variable to point to your external source code.
|
|
Here are the statements to put in your
|
|
<filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
INHERIT += "externalsrc"
|
|
EXTERNALSRC_pn-myrecipe = "/some/path/to/your/source/tree"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
By default, <filename>externalsrc.bbclass</filename> builds
|
|
the source code in a directory separate from the external source
|
|
directory as specified by
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-EXTERNALSRC'><filename>EXTERNALSRC</filename></ulink>.
|
|
If you need to have the source built in the same directory in
|
|
which it resides, or some other nominated directory, you can set
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-EXTERNALSRC_BUILD'><filename>EXTERNALSRC_BUILD</filename></ulink>
|
|
to point to that directory:
|
|
<literallayout class='monospaced'>
|
|
EXTERNALSRC_BUILD_pn-myrecipe = "/path/to/my/source/tree"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="selecting-an-initialization-manager">
|
|
<title>Selecting an Initialization Manager</title>
|
|
|
|
<para>
|
|
By default, the Yocto Project uses SysVinit as the initialization
|
|
manager.
|
|
However, support also exists for systemd,
|
|
which is a full replacement for init with
|
|
parallel starting of services, reduced shell overhead and other
|
|
features that are used by many distributions.
|
|
</para>
|
|
|
|
<para>
|
|
If you want to use SysVinit, you do
|
|
not have to do anything.
|
|
But, if you want to use systemd, you must
|
|
take some steps as described in the following sections.
|
|
</para>
|
|
|
|
<section id='using-systemd-exclusively'>
|
|
<title>Using systemd Exclusively</title>
|
|
|
|
<para>
|
|
Set the these variables in your distribution configuration
|
|
file as follows:
|
|
<literallayout class='monospaced'>
|
|
DISTRO_FEATURES_append = " systemd"
|
|
VIRTUAL-RUNTIME_init_manager = "systemd"
|
|
</literallayout>
|
|
You can also prevent the SysVinit
|
|
distribution feature from
|
|
being automatically enabled as follows:
|
|
<literallayout class='monospaced'>
|
|
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
|
|
</literallayout>
|
|
Doing so removes any redundant SysVinit scripts.
|
|
</para>
|
|
|
|
<para>
|
|
To remove initscripts from your image altogether,
|
|
set this variable also:
|
|
<literallayout class='monospaced'>
|
|
VIRTUAL-RUNTIME_initscripts = ""
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
For information on the backfill variable, see
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_FEATURES_BACKFILL_CONSIDERED'><filename>DISTRO_FEATURES_BACKFILL_CONSIDERED</filename></ulink>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='using-systemd-for-the-main-image-and-using-sysvinit-for-the-rescue-image'>
|
|
<title>Using systemd for the Main Image and Using SysVinit for the Rescue Image</title>
|
|
|
|
<para>
|
|
Set the these variables in your distribution configuration
|
|
file as follows:
|
|
<literallayout class='monospaced'>
|
|
DISTRO_FEATURES_append = " systemd"
|
|
VIRTUAL-RUNTIME_init_manager = "systemd"
|
|
</literallayout>
|
|
Doing so causes your main image to use the
|
|
<filename>packagegroup-core-boot.bb</filename> recipe and
|
|
systemd.
|
|
The rescue/minimal image cannot use this package group.
|
|
However, it can install SysVinit
|
|
and the appropriate packages will have support for both
|
|
systemd and SysVinit.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="platdev-appdev-srcrev">
|
|
<title>Using an External SCM</title>
|
|
|
|
<para>
|
|
If you're working on a recipe that pulls from an external Source
|
|
Code Manager (SCM), it is possible to have the OpenEmbedded build
|
|
system notice new recipe changes added to the SCM and then build
|
|
the resulting packages that depend on the new recipes by using
|
|
the latest versions.
|
|
This only works for SCMs from which it is possible to get a
|
|
sensible revision number for changes.
|
|
Currently, you can do this with Apache Subversion (SVN), Git, and
|
|
Bazaar (BZR) repositories.
|
|
</para>
|
|
|
|
<para>
|
|
To enable this behavior, the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PV'><filename>PV</filename></ulink>
|
|
of the recipe needs to reference
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRCPV'><filename>SRCPV</filename></ulink>.
|
|
Here is an example:
|
|
<literallayout class='monospaced'>
|
|
PV = "1.2.3+git${SRCPV}
|
|
</literallayout>
|
|
Then, you can add the following to your
|
|
<filename>local.conf</filename>:
|
|
<literallayout class='monospaced'>
|
|
SRCREV_pn-<PN> = "${AUTOREV}"
|
|
</literallayout>
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink>
|
|
is the name of the recipe for which you want to enable automatic source
|
|
revision updating.
|
|
</para>
|
|
|
|
<para>
|
|
If you do not want to update your local configuration file, you can
|
|
add the following directly to the recipe to finish enabling
|
|
the feature:
|
|
<literallayout class='monospaced'>
|
|
SRCREV = "${AUTOREV}"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
The Yocto Project provides a distribution named
|
|
<filename>poky-bleeding</filename>, whose configuration
|
|
file contains the line:
|
|
<literallayout class='monospaced'>
|
|
require conf/distro/include/poky-floating-revisions.inc
|
|
</literallayout>
|
|
This line pulls in the listed include file that contains
|
|
numerous lines of exactly that form:
|
|
<literallayout class='monospaced'>
|
|
SRCREV_pn-gconf-dbus ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-common ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-config-gtk ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-desktop ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-keyboard ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-panel ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-panel-2 ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-themes-extra ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-terminal ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-wm ?= "${AUTOREV}"
|
|
SRCREV_pn-matchbox-wm-2 ?= "${AUTOREV}"
|
|
SRCREV_pn-settings-daemon ?= "${AUTOREV}"
|
|
SRCREV_pn-screenshot ?= "${AUTOREV}"
|
|
SRCREV_pn-libfakekey ?= "${AUTOREV}"
|
|
SRCREV_pn-oprofileui ?= "${AUTOREV}"
|
|
.
|
|
.
|
|
.
|
|
</literallayout>
|
|
These lines allow you to experiment with building a
|
|
distribution that tracks the latest development source
|
|
for numerous packages.
|
|
<note><title>Caution</title>
|
|
The <filename>poky-bleeding</filename> distribution
|
|
is not tested on a regular basis.
|
|
Keep this in mind if you use it.
|
|
</note>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-a-read-only-root-filesystem'>
|
|
<title>Creating a Read-Only Root Filesystem</title>
|
|
|
|
<para>
|
|
Suppose, for security reasons, you need to disable
|
|
your target device's root filesystem's write permissions
|
|
(i.e. you need a read-only root filesystem).
|
|
Or, perhaps you are running the device's operating system
|
|
from a read-only storage device.
|
|
For either case, you can customize your image for
|
|
that behavior.
|
|
</para>
|
|
|
|
<note>
|
|
Supporting a read-only root filesystem requires that the system and
|
|
applications do not try to write to the root filesystem.
|
|
You must configure all parts of the target system to write
|
|
elsewhere, or to gracefully fail in the event of attempting to
|
|
write to the root filesystem.
|
|
</note>
|
|
|
|
<section id='creating-the-root-filesystem'>
|
|
<title>Creating the Root Filesystem</title>
|
|
|
|
<para>
|
|
To create the read-only root filesystem, simply add the
|
|
"read-only-rootfs" feature to your image.
|
|
Using either of the following statements in your
|
|
image recipe or from within the
|
|
<filename>local.conf</filename> file found in the
|
|
<link linkend='build-directory'>Build Directory</link>
|
|
causes the build system to create a read-only root filesystem:
|
|
<literallayout class='monospaced'>
|
|
IMAGE_FEATURES = "read-only-rootfs"
|
|
</literallayout>
|
|
or
|
|
<literallayout class='monospaced'>
|
|
EXTRA_IMAGE_FEATURES += "read-only-rootfs"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
For more information on how to use these variables, see the
|
|
"<link linkend='usingpoky-extend-customimage-imagefeatures'>Customizing Images Using Custom <filename>IMAGE_FEATURES</filename> and <filename>EXTRA_IMAGE_FEATURES</filename></link>"
|
|
section.
|
|
For information on the variables, see
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>
|
|
and <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_IMAGE_FEATURES'><filename>EXTRA_IMAGE_FEATURES</filename></ulink>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='post-installation-scripts'>
|
|
<title>Post-Installation Scripts</title>
|
|
|
|
<para>
|
|
It is very important that you make sure all
|
|
post-Installation (<filename>pkg_postinst</filename>) scripts
|
|
for packages that are installed into the image can be run
|
|
at the time when the root filesystem is created during the
|
|
build on the host system.
|
|
These scripts cannot attempt to run during first-boot on the
|
|
target device.
|
|
With the "read-only-rootfs" feature enabled,
|
|
the build system checks during root filesystem creation to make
|
|
sure all post-installation scripts succeed.
|
|
If any of these scripts still need to be run after the root
|
|
filesystem is created, the build immediately fails.
|
|
These build-time checks ensure that the build fails
|
|
rather than the target device fails later during its
|
|
initial boot operation.
|
|
</para>
|
|
|
|
<para>
|
|
Most of the common post-installation scripts generated by the
|
|
build system for the out-of-the-box Yocto Project are engineered
|
|
so that they can run during root filesystem creation
|
|
(e.g. post-installation scripts for caching fonts).
|
|
However, if you create and add custom scripts, you need
|
|
to be sure they can be run during this file system creation.
|
|
</para>
|
|
|
|
<para>
|
|
Here are some common problems that prevent
|
|
post-installation scripts from running during root filesystem
|
|
creation:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
<emphasis>Not using $D in front of absolute
|
|
paths:</emphasis>
|
|
The build system defines
|
|
<filename>$</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-D'><filename>D</filename></ulink>
|
|
when the root filesystem is created.
|
|
Furthermore, <filename>$D</filename> is blank when the
|
|
script is run on the target device.
|
|
This implies two purposes for <filename>$D</filename>:
|
|
ensuring paths are valid in both the host and target
|
|
environments, and checking to determine which
|
|
environment is being used as a method for taking
|
|
appropriate actions.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<emphasis>Attempting to run processes that are
|
|
specific to or dependent on the target
|
|
architecture:</emphasis>
|
|
You can work around these attempts by using native
|
|
tools to accomplish the same tasks, or
|
|
by alternatively running the processes under QEMU,
|
|
which has the <filename>qemu_run_binary</filename>
|
|
function.
|
|
For more information, see the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-qemu'><filename>qemu</filename></ulink>
|
|
class.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='areas-with-write-access'>
|
|
<title>Areas With Write Access</title>
|
|
|
|
<para>
|
|
With the "read-only-rootfs" feature enabled,
|
|
any attempt by the target to write to the root filesystem at
|
|
runtime fails.
|
|
Consequently, you must make sure that you configure processes
|
|
and applications that attempt these types of writes do so
|
|
to directories with write access (e.g.
|
|
<filename>/tmp</filename> or <filename>/var/run</filename>).
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="performing-automated-runtime-testing">
|
|
<title>Performing Automated Runtime Testing</title>
|
|
|
|
<para>
|
|
The OpenEmbedded build system makes available a series of automated
|
|
tests for images to verify runtime functionality.
|
|
You can run these tests on either QEMU or actual target hardware.
|
|
Tests are written in Python making use of the
|
|
<filename>unittest</filename> module, and the majority of them
|
|
run commands on the target system over SSH.
|
|
This section describes how you set up the environment to use these
|
|
tests, run available tests, and write and add your own tests.
|
|
</para>
|
|
|
|
<section id='enabling-tests'>
|
|
<title>Enabling Tests</title>
|
|
|
|
<para>
|
|
Depending on whether you are planning on running tests using
|
|
QEMU or on running them on the hardware, you have to take
|
|
different steps to enable the tests.
|
|
See the following subsections for information on how to
|
|
enable both types of tests.
|
|
</para>
|
|
|
|
<section id='qemu-image-enabling-tests'>
|
|
<title>Enabling Runtime Tests on QEMU</title>
|
|
|
|
<para>
|
|
In order to run tests, you need to do the following:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Set up to avoid interaction
|
|
with <filename>sudo</filename> for networking:</emphasis>
|
|
To accomplish this, you must do one of the
|
|
following:
|
|
<itemizedlist>
|
|
<listitem><para>Add
|
|
<filename>NOPASSWD</filename> for your user
|
|
in <filename>/etc/sudoers</filename> either for
|
|
ALL commands or just for
|
|
<filename>runqemu-ifup</filename>.
|
|
You must provide the full path as that can
|
|
change if you are using multiple clones of the
|
|
source repository.
|
|
<note>
|
|
On some distributions, you also need to
|
|
comment out "Defaults requiretty" in
|
|
<filename>/etc/sudoers</filename>.
|
|
</note></para></listitem>
|
|
<listitem><para>Manually configure a tap interface
|
|
for your system.</para></listitem>
|
|
<listitem><para>Run as root the script in
|
|
<filename>scripts/runqemu-gen-tapdevs</filename>,
|
|
which should generate a list of tap devices.
|
|
This is the option typically chosen for
|
|
Autobuilder-type environments.
|
|
</para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
<listitem><para><emphasis>Set the
|
|
<filename>DISPLAY</filename> variable:</emphasis>
|
|
You need to set this variable so that you have an X
|
|
server available (e.g. start
|
|
<filename>vncserver</filename> for a headless machine).
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Be sure your host's firewall
|
|
accepts incoming connections from
|
|
192.168.7.0/24:</emphasis>
|
|
Some of the tests (in particular smart tests) start an
|
|
HTTP server on a random high number port, which is
|
|
used to serve files to the target.
|
|
The smart module serves
|
|
<filename>${DEPLOY_DIR}/rpm</filename> so it can run
|
|
smart channel commands. That means your host's firewall
|
|
must accept incoming connections from 192.168.7.0/24,
|
|
which is the default IP range used for tap devices
|
|
by <filename>runqemu</filename>.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Once you start running the tests, the following happens:
|
|
<itemizedlist>
|
|
<listitem><para>A copy of the root filesystem is written
|
|
to <filename>${WORKDIR}/testimage</filename>.
|
|
</para></listitem>
|
|
<listitem><para>The image is booted under QEMU using the
|
|
standard <filename>runqemu</filename> script.
|
|
</para></listitem>
|
|
<listitem><para>A default timeout of 500 seconds occurs
|
|
to allow for the boot process to reach the login prompt.
|
|
You can change the timeout period by setting
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_QEMUBOOT_TIMEOUT'><filename>TEST_QEMUBOOT_TIMEOUT</filename></ulink>
|
|
in the <filename>local.conf</filename> file.
|
|
</para></listitem>
|
|
<listitem><para>Once the boot process is reached and the
|
|
login prompt appears, the tests run.
|
|
The full boot log is written to
|
|
<filename>${WORKDIR}/testimage/qemu_boot_log</filename>.
|
|
</para></listitem>
|
|
<listitem><para>Each test module loads in the order found
|
|
in <filename>TEST_SUITES</filename>.
|
|
You can find the full output of the commands run over
|
|
SSH in
|
|
<filename>${WORKDIR}/testimgage/ssh_target_log</filename>.
|
|
</para></listitem>
|
|
<listitem><para>If no failures occur, the task running the
|
|
tests ends successfully.
|
|
You can find the output from the
|
|
<filename>unittest</filename> in the task log at
|
|
<filename>${WORKDIR}/temp/log.do_testimage</filename>.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='hardware-image-enabling-tests'>
|
|
<title>Enabling Runtime Tests on Hardware</title>
|
|
|
|
<para>
|
|
The OpenEmbedded build system can run tests on real
|
|
hardware, and for certain devices it can also deploy
|
|
the image to be tested onto the device beforehand.
|
|
</para>
|
|
|
|
<para>
|
|
For automated deployment, a "master image" is installed
|
|
onto the hardware once as part of setup.
|
|
Then, each time tests are to be run, the following
|
|
occurs:
|
|
<orderedlist>
|
|
<listitem><para>The master image is booted into and
|
|
used to write the image to be tested to
|
|
a second partition.
|
|
</para></listitem>
|
|
<listitem><para>The device is then rebooted using an
|
|
external script that you need to provide.
|
|
</para></listitem>
|
|
<listitem><para>The device boots into the image to be
|
|
tested.
|
|
</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
|
|
<para>
|
|
When running tests (independent of whether the image
|
|
has been deployed automatically or not), the device is
|
|
expected to be connected to a network on a
|
|
pre-determined IP address.
|
|
You can either use static IP addresses written into
|
|
the image, or set the image to use DHCP and have your
|
|
DHCP server on the test network assign a known IP address
|
|
based on the MAC address of the device.
|
|
</para>
|
|
|
|
<para>
|
|
In order to run tests on hardware, you need to set
|
|
<filename>TEST_TARGET</filename> to an appropriate value.
|
|
For QEMU, you do not have to change anything, the default
|
|
value is "QemuTarget".
|
|
For running tests on hardware, two options exist:
|
|
"SimpleRemoteTarget" and "GummibootTarget".
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>"SimpleRemoteTarget":</emphasis>
|
|
Choose "SimpleRemoteTarget" if you are going to
|
|
run tests on a target system that is already
|
|
running the image to be tested and is available
|
|
on the network.
|
|
You can use "SimpleRemoteTarget" in conjunction
|
|
with either real hardware or an image running
|
|
within a separately started QEMU or any
|
|
other virtual machine manager.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>"GummibootTarget":</emphasis>
|
|
Choose "GummibootTarget" if your hardware is
|
|
an EFI-based machine with
|
|
<filename>gummiboot</filename> as bootloader and
|
|
<filename>core-image-testmaster</filename>
|
|
(or something similar) is installed.
|
|
Also, your hardware under test must be in a
|
|
DHCP-enabled network that gives it the same IP
|
|
address for each reboot.</para>
|
|
<para>If you choose "GummibootTarget", there are
|
|
additional requirements and considerations.
|
|
See the
|
|
"<link linkend='selecting-gummiboottarget'>Selecting GummibootTarget</link>"
|
|
section, which follows, for more information.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='selecting-gummiboottarget'>
|
|
<title>Selecting GummibootTarget</title>
|
|
|
|
<para>
|
|
If you did not set <filename>TEST_TARGET</filename> to
|
|
"GummibootTarget", then you do not need any information
|
|
in this section.
|
|
You can skip down to the
|
|
"<link linkend='qemu-image-running-tests'>Running Tests</link>"
|
|
section.
|
|
</para>
|
|
|
|
<para>
|
|
If you did set <filename>TEST_TARGET</filename> to
|
|
"GummibootTarget", you also need to perform a one-time
|
|
setup of your master image by doing the following:
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Set <filename>EFI_PROVIDER</filename>:</emphasis>
|
|
Be sure that <filename>EFI_PROVIDER</filename>
|
|
is as follows:
|
|
<literallayout class='monospaced'>
|
|
EFI_PROVIDER = "gummiboot"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Build the master image:</emphasis>
|
|
Build the <filename>core-image-testmaster</filename>
|
|
image.
|
|
The <filename>core-image-testmaster</filename>
|
|
recipe is provided as an example for a
|
|
"master" image and you can customize the image
|
|
recipe as you would any other recipe.
|
|
</para>
|
|
<para>Here are the image recipe requirements:
|
|
<itemizedlist>
|
|
<listitem><para>Inherits
|
|
<filename>core-image</filename>
|
|
so that kernel modules are installed.
|
|
</para></listitem>
|
|
<listitem><para>Installs normal linux utilities
|
|
not busybox ones (e.g.
|
|
<filename>bash</filename>,
|
|
<filename>coreutils</filename>,
|
|
<filename>tar</filename>,
|
|
<filename>gzip</filename>, and
|
|
<filename>kmod</filename>).
|
|
</para></listitem>
|
|
<listitem><para>Uses a custom
|
|
initramfs image with a custom installer.
|
|
A normal image that you can install usually
|
|
creates a single rootfs partition.
|
|
This image uses another installer that
|
|
creates a specific partition layout.
|
|
Not all Board Support Packages (BSPs)
|
|
can use an installer.
|
|
For such cases, you need to manually create
|
|
the following partition layout on the
|
|
target:
|
|
<itemizedlist>
|
|
<listitem><para>First partition mounted
|
|
under <filename>/boot</filename>,
|
|
labeled "boot".
|
|
</para></listitem>
|
|
<listitem><para>The main rootfs
|
|
partition where this image gets
|
|
installed, which is mounted under
|
|
<filename>/</filename>.
|
|
</para></listitem>
|
|
<listitem><para>Another partition
|
|
labeled "testrootfs" where test
|
|
images get deployed.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Install image:</emphasis>
|
|
Install the image that you just built on the target
|
|
system.
|
|
</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
|
|
<para>
|
|
The final thing you need to do when setting
|
|
<filename>TEST_TARGET</filename> to "GummibootTarget" is
|
|
to set up the test image:
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Set up your <filename>local.conf</filename> file:</emphasis>
|
|
Make sure you have the following statements in
|
|
your <filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
IMAGE_FSTYPES += "tar.gz"
|
|
INHERIT += "testimage"
|
|
TEST_TARGET = "GummibootTarget"
|
|
TEST_TARGET_IP = "192.168.2.3"
|
|
</literallayout>
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Build your test image:</emphasis>
|
|
Use BitBake to build the image:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake core-image-sato
|
|
</literallayout>
|
|
</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Here is some additional information regarding running
|
|
"GummibootTarget" as your test target:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
You can use
|
|
<filename>TEST_POWERCONTROL_CMD</filename>
|
|
together with
|
|
<filename>TEST_POWERCONTROL_EXTRA_ARGS</filename>
|
|
as a command that runs on the host and does power
|
|
cycling.
|
|
The test code passes one argument to that command:
|
|
off, on or cycle (off then on).
|
|
Here is an example that could appear in your
|
|
<filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
TEST_POWERCONTROL_CMD = "powercontrol.exp test 10.11.12.1 nuc1"
|
|
</literallayout>
|
|
In this example, the expect script does the
|
|
following:
|
|
<literallayout class='monospaced'>
|
|
ssh test@10.11.12.1 "pyctl nuc1 <arg>"
|
|
</literallayout>
|
|
It then runs a Python script that controls power
|
|
for a label called <filename>nuc1</filename>.
|
|
<note>
|
|
You need to customize
|
|
<filename>TEST_POWERCONTROL_CMD</filename>
|
|
and
|
|
<filename>TEST_POWERCONTROL_EXTRA_ARGS</filename>
|
|
for your own setup.
|
|
The one requirement is that it accepts
|
|
"on", "off", and "cycle" as the last argument.
|
|
</note>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
When no command is defined, it connects to the
|
|
device over SSH and uses the classic reboot command
|
|
to reboot the device.
|
|
Classic reboot is fine as long as the machine
|
|
actually reboots (i.e. the SSH test has not
|
|
failed).
|
|
It is useful for scenarios where you have a simple
|
|
setup, typically with a single board, and where
|
|
some manual interaction is okay from time to time.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="qemu-image-running-tests">
|
|
<title>Running Tests</title>
|
|
|
|
<para>
|
|
You can start the tests automatically or manually:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Automatically running tests:</emphasis>
|
|
To run the tests automatically after the
|
|
OpenEmbedded build system successfully creates an image,
|
|
first set the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_IMAGE'><filename>TEST_IMAGE</filename></ulink>
|
|
variable to "1" in your <filename>local.conf</filename>
|
|
file in the
|
|
<ulink url='&YOCTO_DOCS_DEV_URL;#build-directory'>Build Directory</ulink>:
|
|
<literallayout class='monospaced'>
|
|
TEST_IMAGE = "1"
|
|
</literallayout>
|
|
Next, build your image.
|
|
If the image successfully builds, the tests will be
|
|
run:
|
|
<literallayout class='monospaced'>
|
|
bitbake core-image-sato
|
|
</literallayout></para></listitem>
|
|
<listitem><para><emphasis>Manually running tests:</emphasis>
|
|
To manually run the tests, first globally inherit the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-testimage'><filename>testimage</filename></ulink>
|
|
class by editing your <filename>local.conf</filename>
|
|
file:
|
|
<literallayout class='monospaced'>
|
|
INHERIT += "testimage"
|
|
</literallayout>
|
|
Next, use BitBake to run the tests:
|
|
<literallayout class='monospaced'>
|
|
bitbake -c testimage <image>
|
|
</literallayout></para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
All test files reside in
|
|
<filename>meta/lib/oeqa/runtime</filename> in the
|
|
<link linkend='source-directory'>Source Directory</link>.
|
|
A test name maps directly to a Python module.
|
|
Each test module may contain a number of individual tests.
|
|
Tests are usually grouped together by the area
|
|
tested (e.g tests for systemd reside in
|
|
<filename>meta/lib/oeqa/runtime/systemd.py</filename>).
|
|
</para>
|
|
|
|
<para>
|
|
You can add tests to any layer provided you place them in the
|
|
proper area and you extend
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBPATH'><filename>BBPATH</filename></ulink>
|
|
in the <filename>local.conf</filename> file as normal.
|
|
Be sure that tests reside in
|
|
<filename><layer>/lib/oeqa/runtime</filename>.
|
|
<note>
|
|
Be sure that module names do not collide with module names
|
|
used in the default set of test modules in
|
|
<filename>meta/lib/oeqa/runtime</filename>.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
You can change the set of tests run by appending or overriding
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_SUITES'><filename>TEST_SUITES</filename></ulink>
|
|
variable in <filename>local.conf</filename>.
|
|
Each name in <filename>TEST_SUITES</filename> represents a
|
|
required test for the image.
|
|
Test modules named within <filename>TEST_SUITES</filename>
|
|
cannot be skipped even if a test is not suitable for an image
|
|
(e.g. running the RPM tests on an image without
|
|
<filename>rpm</filename>).
|
|
Appending "auto" to <filename>TEST_SUITES</filename> causes the
|
|
build system to try to run all tests that are suitable for the
|
|
image (i.e. each test module may elect to skip itself).
|
|
</para>
|
|
|
|
<para>
|
|
The order you list tests in <filename>TEST_SUITES</filename>
|
|
is important and influences test dependencies.
|
|
Consequently, tests that depend on other tests should be added
|
|
after the test on which they depend.
|
|
For example, since the <filename>ssh</filename> test
|
|
depends on the
|
|
<filename>ping</filename> test, "ssh" needs to come after
|
|
"ping" in the list.
|
|
The test class provides no re-ordering or dependency handling.
|
|
<note>
|
|
Each module can have multiple classes with multiple test
|
|
methods.
|
|
And, Python <filename>unittest</filename> rules apply.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
Here are some things to keep in mind when running tests:
|
|
<itemizedlist>
|
|
<listitem><para>The default tests for the image are defined
|
|
as:
|
|
<literallayout class='monospaced'>
|
|
DEFAULT_TEST_SUITES_pn-<image> = "ping ssh df connman syslog xorg scp vnc date rpm smart dmesg"
|
|
</literallayout></para></listitem>
|
|
<listitem><para>Add your own test to the list of the
|
|
by using the following:
|
|
<literallayout class='monospaced'>
|
|
TEST_SUITES_append = " mytest"
|
|
</literallayout></para></listitem>
|
|
<listitem><para>Run a specific list of tests as follows:
|
|
<literallayout class='monospaced'>
|
|
TEST_SUITES = "test1 test2 test3"
|
|
</literallayout>
|
|
Remember, order is important.
|
|
Be sure to place a test that is dependent on another test
|
|
later in the order.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="exporting-tests">
|
|
<title>Exporting Tests</title>
|
|
|
|
<para>
|
|
You can export tests so that they can run independently of
|
|
the build system.
|
|
Exporting tests is required if you want to be able to hand
|
|
the test execution off to a scheduler.
|
|
You can only export tests that are defined in
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_SUITES'><filename>TEST_SUITES</filename></ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
If you image is already built, make sure the following are set
|
|
in your <filename>local.conf</filename> file.
|
|
Be sure to provide the IP address you need:
|
|
<literallayout class='monospaced'>
|
|
TEST_EXPORT_ONLY = "1"
|
|
TEST_TARGET = "simpleremote"
|
|
TEST_TARGET_IP = "192.168.7.2"
|
|
TEST_SERVER_IP = "192.168.7.1"
|
|
</literallayout>
|
|
You can then export the tests with the following:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake core-image-sato -c testimage
|
|
</literallayout>
|
|
Exporting the tests places them in the
|
|
<link linkend='build-directory'>Build Directory</link> in
|
|
<filename>tmp/testimage/core-image-sato</filename>, which
|
|
is controlled by the
|
|
<filename>TEST_EXPORT_DIR</filename> variable.
|
|
</para>
|
|
|
|
<para>
|
|
The exported data (i.e. <filename>testdata.json</filename>)
|
|
contains paths to the Build Directory.
|
|
Thus, the contents of the directory can be moved
|
|
to another machine as long as you update some paths in the
|
|
JSON.
|
|
Usually you only care about the
|
|
${DEPLOY_DIR}/rpm directory (assuming the RPM and Smart tests
|
|
are enabled).
|
|
Consequently, running the tests on other machine
|
|
means that you have to move the contents and call
|
|
<filename>runexported</filename> with "‐‐deploy-dir PATH:
|
|
./runexported.py ‐‐deploy-dir /new/path/on/this/machine testdata.json
|
|
runexported.py accepts other arguments as well, see ‐‐help.
|
|
</para>
|
|
|
|
<para>
|
|
You can now run the tests outside of the build environment:
|
|
<literallayout class='monospaced'>
|
|
$ cd tmp/testimage/core-image-sato
|
|
$ ./runexported.py testdata.json
|
|
</literallayout>
|
|
<note>
|
|
This "export" feature does not deploy or boot the target
|
|
image.
|
|
Your target (be it a Qemu or hardware one)
|
|
has to already be up and running when you call
|
|
<filename>runexported.py</filename>
|
|
</note>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="qemu-image-writing-new-tests">
|
|
<title>Writing New Tests</title>
|
|
|
|
<para>
|
|
As mentioned previously, all new test files need to be in the
|
|
proper place for the build system to find them.
|
|
New tests for additional functionality outside of the core
|
|
should be added to the layer that adds the functionality, in
|
|
<filename><layer>/lib/oeqa/runtime</filename> (as
|
|
long as
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-BBPATH'><filename>BBPATH</filename></ulink>
|
|
is extended in the layer's
|
|
<filename>layer.conf</filename> file as normal).
|
|
Just remember that filenames need to map directly to test
|
|
(module) names and that you do not use module names that
|
|
collide with existing core tests.
|
|
</para>
|
|
|
|
<para>
|
|
To create a new test, start by copying an existing module
|
|
(e.g. <filename>syslog.py</filename> or
|
|
<filename>gcc.py</filename> are good ones to use).
|
|
Test modules can use code from
|
|
<filename>meta/lib/oeqa/utils</filename>, which are helper
|
|
classes.
|
|
</para>
|
|
|
|
<note>
|
|
Structure shell commands such that you rely on them and they
|
|
return a single code for success.
|
|
Be aware that sometimes you will need to parse the output.
|
|
See the <filename>df.py</filename> and
|
|
<filename>date.py</filename> modules for examples.
|
|
</note>
|
|
|
|
<para>
|
|
You will notice that all test classes inherit
|
|
<filename>oeRuntimeTest</filename>, which is found in
|
|
<filename>meta/lib/oetest.py</filename>.
|
|
This base class offers some helper attributes, which are
|
|
described in the following sections:
|
|
</para>
|
|
|
|
<section id='qemu-image-writing-tests-class-methods'>
|
|
<title>Class Methods</title>
|
|
|
|
<para>
|
|
Class methods are as follows:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>hasPackage(pkg)</filename>:</emphasis>
|
|
Returns "True" if <filename>pkg</filename> is in the
|
|
installed package list of the image, which is based
|
|
on the manifest file that is generated during the
|
|
<filename>do_rootfs</filename> task.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>hasFeature(feature)</filename>:</emphasis>
|
|
Returns "True" if the feature is in
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>
|
|
or
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_FEATURES'><filename>DISTRO_FEATURES</filename></ulink>.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='qemu-image-writing-tests-class-attributes'>
|
|
<title>Class Attributes</title>
|
|
|
|
<para>
|
|
Class attributes are as follows:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>pscmd</filename>:</emphasis>
|
|
Equals "ps -ef" if <filename>procps</filename> is
|
|
installed in the image.
|
|
Otherwise, <filename>pscmd</filename> equals
|
|
"ps" (busybox).
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>tc</filename>:</emphasis>
|
|
The called text context, which gives access to the
|
|
following attributes:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>d</filename>:</emphasis>
|
|
The BitBake datastore, which allows you to
|
|
use stuff such as
|
|
<filename>oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager")</filename>.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>testslist</filename> and <filename>testsrequired</filename>:</emphasis>
|
|
Used internally.
|
|
The tests do not need these.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>filesdir</filename>:</emphasis>
|
|
The absolute path to
|
|
<filename>meta/lib/oeqa/runtime/files</filename>,
|
|
which contains helper files for tests meant
|
|
for copying on the target such as small
|
|
files written in C for compilation.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>target</filename>:</emphasis>
|
|
The target controller object used to deploy
|
|
and start an image on a particular target
|
|
(e.g. QemuTarget, SimpleRemote, and
|
|
GummibootTarget).
|
|
Tests usually use the following:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>ip</filename>:</emphasis>
|
|
The target's IP address.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>server_ip</filename>:</emphasis>
|
|
The host's IP address, which is
|
|
usually used by the "smart" test
|
|
suite.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>run(cmd, timeout=None)</filename>:</emphasis>
|
|
The single, most used method.
|
|
This command is a wrapper for:
|
|
<filename>ssh root@host "cmd"</filename>.
|
|
The command returns a tuple:
|
|
(status, output), which are what
|
|
their names imply - the return code
|
|
of 'cmd' and whatever output
|
|
it produces.
|
|
The optional timeout argument
|
|
represents the number of seconds the
|
|
test should wait for 'cmd' to
|
|
return.
|
|
If the argument is "None", the
|
|
test uses the default instance's
|
|
timeout period, which is 300
|
|
seconds.
|
|
If the argument is "0", the test
|
|
runs until the command returns.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>copy_to(localpath, remotepath)</filename>:</emphasis>
|
|
<filename>scp localpath root@ip:remotepath</filename>.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>copy_from(remotepath, localpath)</filename>:</emphasis>
|
|
<filename>scp root@host:remotepath localpath</filename>.
|
|
</para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
</itemizedlist></para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='qemu-image-writing-tests-instance-attributes'>
|
|
<title>Instance Attributes</title>
|
|
|
|
<para>
|
|
A single instance attribute exists, which is
|
|
<filename>target</filename>.
|
|
The <filename>target</filename> instance attribute is
|
|
identical to the class attribute of the same name, which
|
|
is described in the previous section.
|
|
This attribute exists as both an instance and class
|
|
attribute so tests can use
|
|
<filename>self.target.run(cmd)</filename> in instance
|
|
methods instead of
|
|
<filename>oeRuntimeTest.tc.target.run(cmd)</filename>.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="platdev-gdb-remotedebug">
|
|
<title>Debugging With the GNU Project Debugger (GDB) Remotely</title>
|
|
|
|
<para>
|
|
GDB allows you to examine running programs, which in turn helps you to understand and fix problems.
|
|
It also allows you to perform post-mortem style analysis of program crashes.
|
|
GDB is available as a package within the Yocto Project and is
|
|
installed in SDK images by default.
|
|
See the "<ulink url='&YOCTO_DOCS_REF_URL;#ref-images'>Images</ulink>" chapter
|
|
in the Yocto Project Reference Manual for a description of these images.
|
|
You can find information on GDB at <ulink url="http://sourceware.org/gdb/"/>.
|
|
</para>
|
|
|
|
<tip>
|
|
For best results, install DBG (<filename>-dbg</filename>) packages
|
|
for the applications you are going to debug.
|
|
Doing so makes extra debug symbols available that give you more
|
|
meaningful output.
|
|
</tip>
|
|
|
|
<para>
|
|
Sometimes, due to memory or disk space constraints, it is not possible
|
|
to use GDB directly on the remote target to debug applications.
|
|
These constraints arise because GDB needs to load the debugging information and the
|
|
binaries of the process being debugged.
|
|
Additionally, GDB needs to perform many computations to locate information such as function
|
|
names, variable names and values, stack traces and so forth - even before starting the
|
|
debugging process.
|
|
These extra computations place more load on the target system and can alter the
|
|
characteristics of the program being debugged.
|
|
</para>
|
|
|
|
<para>
|
|
To help get past the previously mentioned constraints, you can use Gdbserver.
|
|
Gdbserver runs on the remote target and does not load any debugging information
|
|
from the debugged process.
|
|
Instead, a GDB instance processes the debugging information that is run on a
|
|
remote computer - the host GDB.
|
|
The host GDB then sends control commands to Gdbserver to make it stop or start the debugged
|
|
program, as well as read or write memory regions of that debugged program.
|
|
All the debugging information loaded and processed as well
|
|
as all the heavy debugging is done by the host GDB.
|
|
Offloading these processes gives the Gdbserver running on the target a chance to remain
|
|
small and fast.
|
|
</para>
|
|
|
|
<para>
|
|
Because the host GDB is responsible for loading the debugging information and
|
|
for doing the necessary processing to make actual debugging happen, the
|
|
user has to make sure the host can access the unstripped binaries complete
|
|
with their debugging information and also be sure the target is compiled with no optimizations.
|
|
The host GDB must also have local access to all the libraries used by the
|
|
debugged program.
|
|
Because Gdbserver does not need any local debugging information, the binaries on
|
|
the remote target can remain stripped.
|
|
However, the binaries must also be compiled without optimization
|
|
so they match the host's binaries.
|
|
</para>
|
|
|
|
<para>
|
|
To remain consistent with GDB documentation and terminology, the binary being debugged
|
|
on the remote target machine is referred to as the "inferior" binary.
|
|
For documentation on GDB see the
|
|
<ulink url="http://sourceware.org/gdb/documentation/">GDB site</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
The remainder of this section describes the steps you need to take
|
|
to debug using the GNU project debugger.
|
|
</para>
|
|
|
|
<section id='platdev-gdb-remotedebug-setup'>
|
|
<title>Set Up the Cross-Development Debugging Environment</title>
|
|
|
|
<para>
|
|
Before you can initiate a remote debugging session, you need
|
|
to be sure you have set up the cross-development environment,
|
|
toolchain, and sysroot.
|
|
The "<ulink url='&YOCTO_DOCS_ADT_URL;#adt-prepare'>Preparing for Application Development</ulink>"
|
|
chapter of the Yocto Project Application Developer's Guide
|
|
describes this process.
|
|
Be sure you have read that chapter and have set up
|
|
your environment.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-gdb-remotedebug-launch-gdbserver">
|
|
<title>Launch Gdbserver on the Target</title>
|
|
|
|
<para>
|
|
Make sure Gdbserver is installed on the target.
|
|
If it is not, install the package
|
|
<filename>gdbserver</filename>, which needs the
|
|
<filename>libthread-db1</filename> package.
|
|
</para>
|
|
|
|
<para>
|
|
Here is an example that when entered from the host
|
|
connects to the target and launches Gdbserver in order to
|
|
"debug" a binary named <filename>helloworld</filename>:
|
|
<literallayout class='monospaced'>
|
|
$ gdbserver localhost:2345 /usr/bin/helloworld
|
|
</literallayout>
|
|
Gdbserver should now be listening on port 2345 for debugging
|
|
commands coming from a remote GDB process that is running on
|
|
the host computer.
|
|
Communication between Gdbserver and the host GDB are done
|
|
using TCP.
|
|
To use other communication protocols, please refer to the
|
|
<ulink url='http://www.gnu.org/software/gdb/'>Gdbserver documentation</ulink>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-gdb-remotedebug-launch-gdb">
|
|
<title>Launch GDB on the Host Computer</title>
|
|
|
|
<para>
|
|
Running GDB on the host computer takes a number of stages, which
|
|
this section describes.
|
|
</para>
|
|
|
|
<section id="platdev-gdb-remotedebug-launch-gdb-buildcross">
|
|
<title>Build the Cross-GDB Package</title>
|
|
<para>
|
|
A suitable GDB cross-binary is required that runs on your
|
|
host computer but also knows about the the ABI of the
|
|
remote target.
|
|
You can get this binary from the
|
|
<link linkend='cross-development-toolchain'>Cross-Development Toolchain</link>.
|
|
Here is an example where the toolchain has been installed
|
|
in the default directory
|
|
<filename>/opt/poky/&DISTRO;</filename>:
|
|
<literallayout class='monospaced'>
|
|
/opt/poky/&DISTRO;/sysroots/i686-pokysdk-linux/usr/bin/armv7a-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi-gdb
|
|
</literallayout>
|
|
where <filename>arm</filename> is the target architecture
|
|
and <filename>linux-gnueabi</filename> is the target ABI.
|
|
</para>
|
|
|
|
<para>
|
|
Alternatively, you can use BitBake to build the
|
|
<filename>gdb-cross</filename> binary.
|
|
Here is an example:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake gdb-cross
|
|
</literallayout>
|
|
Once the binary is built, you can find it here:
|
|
<literallayout class='monospaced'>
|
|
tmp/sysroots/<host-arch>/usr/bin/<target-platform>/<target-abi>-gdb
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='create-the-gdb-initialization-file'>
|
|
<title>Create the GDB Initialization File and Point to Your Root Filesystem</title>
|
|
|
|
<para>
|
|
Aside from the GDB cross-binary, you also need a GDB
|
|
initialization file in the same top directory in which
|
|
your binary resides.
|
|
When you start GDB on your host development system, GDB
|
|
finds this initialization file and executes all the
|
|
commands within.
|
|
For information on the <filename>.gdbinit</filename>, see
|
|
"<ulink url='http://sourceware.org/gdb/onlinedocs/gdb/'>Debugging with GDB</ulink>",
|
|
which is maintained by
|
|
<ulink url='http://www.sourceware.org'>sourceware.org</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
You need to add a statement in the
|
|
<filename>.gdbinit</filename> file that points to your
|
|
root filesystem.
|
|
Here is an example that points to the root filesystem for
|
|
an ARM-based target device:
|
|
<literallayout class='monospaced'>
|
|
set sysroot /home/jzhang/sysroot_arm
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-gdb-remotedebug-launch-gdb-launchhost">
|
|
<title>Launch the Host GDB</title>
|
|
|
|
<para>
|
|
Before launching the host GDB, you need to be sure
|
|
you have sourced the cross-debugging environment script,
|
|
which if you installed the root filesystem in the default
|
|
location is at <filename>/opt/poky/&DISTRO;</filename>
|
|
and begins with the string "environment-setup".
|
|
For more information, see the
|
|
"<ulink url='&YOCTO_DOCS_ADT_URL;#setting-up-the-cross-development-environment'>Setting Up the Cross-Development Environment</ulink>"
|
|
section in the Yocto Project Application Developer's
|
|
Guide.
|
|
</para>
|
|
|
|
<para>
|
|
Finally, switch to the directory where the binary resides
|
|
and run the <filename>cross-gdb</filename> binary.
|
|
Provide the binary file you are going to debug.
|
|
For example, the following command continues with the
|
|
example used in the previous section by loading
|
|
the <filename>helloworld</filename> binary as well as the
|
|
debugging information:
|
|
<literallayout class='monospaced'>
|
|
$ arm-poky-linux-gnuabi-gdb helloworld
|
|
</literallayout>
|
|
The commands in your <filename>.gdbinit</filename> execute
|
|
and the GDB prompt appears.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='platdev-gdb-connect-to-the-remote-gdb-server'>
|
|
<title>Connect to the Remote GDB Server</title>
|
|
|
|
<para>
|
|
From the target, you need to connect to the remote GDB
|
|
server that is running on the host.
|
|
You need to specify the remote host and port.
|
|
Here is the command continuing with the example:
|
|
<literallayout class='monospaced'>
|
|
target remote 192.168.7.2:2345
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-gdb-remotedebug-launch-gdb-using">
|
|
<title>Use the Debugger</title>
|
|
|
|
<para>
|
|
You can now proceed with debugging as normal - as if you were debugging
|
|
on the local machine.
|
|
For example, to instruct GDB to break in the "main" function and then
|
|
continue with execution of the inferior binary use the following commands
|
|
from within GDB:
|
|
<literallayout class='monospaced'>
|
|
(gdb) break main
|
|
(gdb) continue
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
For more information about using GDB, see the project's online documentation at
|
|
<ulink url="http://sourceware.org/gdb/download/onlinedocs/"/>.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='debugging-parallel-make-races'>
|
|
<title>Debugging Parallel Make Races</title>
|
|
|
|
<para>
|
|
A parallel <filename>make</filename> race occurs when the build
|
|
consists of several parts that are run simultaneously and
|
|
a situation occurs when the output or result of one
|
|
part is not ready for use with a different part of the build that
|
|
depends on that output.
|
|
Parallel make races are annoying and can sometimes be difficult
|
|
to reproduce and fix.
|
|
However, some simple tips and tricks exist that can help
|
|
you debug and fix them.
|
|
This section presents a real-world example of an error encountered
|
|
on the Yocto Project autobuilder and the process used to fix it.
|
|
</para>
|
|
|
|
<section id='the-failure'>
|
|
<title>The Failure</title>
|
|
|
|
<para>
|
|
For this example, assume that you are building an image that
|
|
depends on the "neard" package.
|
|
And, during the build, BitBake runs into problems and
|
|
creates the following output.
|
|
<note>
|
|
This example log file has longer lines artificially
|
|
broken to make the listing easier to read.
|
|
</note>
|
|
If you examine the output or the log file, you see the
|
|
failure during <filename>make</filename>:
|
|
<literallayout class='monospaced'>
|
|
| DEBUG: SITE files ['endian-little', 'bit-32', 'ix86-common', 'common-linux', 'common-glibc', 'i586-linux', 'common']
|
|
| DEBUG: Executing shell function do_compile
|
|
| NOTE: make -j 16
|
|
| make ‐‐no-print-directory all-am
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/types.h include/near/types.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/log.h include/near/log.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/plugin.h include/near/plugin.h
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/tag.h include/near/tag.h
|
|
| /bin/mkdir -p include/near
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/adapter.h include/near/adapter.h
|
|
| /bin/mkdir -p include/near
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/ndef.h include/near/ndef.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/tlv.h include/near/tlv.h
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/setting.h include/near/setting.h
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| /bin/mkdir -p include/near
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/device.h include/near/device.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/nfc_copy.h include/near/nfc_copy.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/snep.h include/near/snep.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/version.h include/near/version.h
|
|
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
|
|
0.14-r0/neard-0.14/include/dbus.h include/near/dbus.h
|
|
| ./src/genbuiltin nfctype1 nfctype2 nfctype3 nfctype4 p2p > src/builtin.h
|
|
| i586-poky-linux-gcc -m32 -march=i586 ‐‐sysroot=/home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/
|
|
build/build/tmp/sysroots/qemux86 -DHAVE_CONFIG_H -I. -I./include -I./src -I./gdbus -I/home/pokybuild/
|
|
yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/sysroots/qemux86/usr/include/glib-2.0
|
|
-I/home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/sysroots/qemux86/usr/
|
|
lib/glib-2.0/include -I/home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/
|
|
tmp/sysroots/qemux86/usr/include/dbus-1.0 -I/home/pokybuild/yocto-autobuilder/yocto-slave/
|
|
nightly-x86/build/build/tmp/sysroots/qemux86/usr/lib/dbus-1.0/include -I/home/pokybuild/yocto-autobuilder/
|
|
yocto-slave/nightly-x86/build/build/tmp/sysroots/qemux86/usr/include/libnl3
|
|
-DNEAR_PLUGIN_BUILTIN -DPLUGINDIR=\""/usr/lib/near/plugins"\"
|
|
-DCONFIGDIR=\""/etc/neard\"" -O2 -pipe -g -feliminate-unused-debug-types -c
|
|
-o tools/snep-send.o tools/snep-send.c
|
|
| In file included from tools/snep-send.c:16:0:
|
|
| tools/../src/near.h:41:23: fatal error: near/dbus.h: No such file or directory
|
|
| #include <near/dbus.h>
|
|
| ^
|
|
| compilation terminated.
|
|
| make[1]: *** [tools/snep-send.o] Error 1
|
|
| make[1]: *** Waiting for unfinished jobs....
|
|
| make: *** [all] Error 2
|
|
| ERROR: oe_runmake failed
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='reproducing-the-error'>
|
|
<title>Reproducing the Error</title>
|
|
|
|
<para>
|
|
Because race conditions are intermittent, they do not
|
|
manifest themselves every time you do the build.
|
|
In fact, most times the build will complete without problems
|
|
even though the potential race condition exists.
|
|
Thus, once the error surfaces, you need a way to reproduce it.
|
|
</para>
|
|
|
|
<para>
|
|
In this example, compiling the "neard" package is causing the
|
|
problem.
|
|
So the first thing to do is build "neard" locally.
|
|
Before you start the build, set the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKE'><filename>PARALLEL_MAKE</filename></ulink>
|
|
variable in your <filename>local.conf</filename> file to
|
|
a high number (e.g. "-j 20").
|
|
Using a high value for <filename>PARALLEL_MAKE</filename>
|
|
increases the chances of the race condition showing up:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake neard
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Once the local build for "neard" completes, start a
|
|
<filename>devshell</filename> build:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake neard -c devshell
|
|
</literallayout>
|
|
For information on how to use a
|
|
<filename>devshell</filename>, see the
|
|
"<link linkend='platdev-appdev-devshell'>Using a Development Shell</link>"
|
|
section.
|
|
</para>
|
|
|
|
<para>
|
|
In the <filename>devshell</filename>, do the following:
|
|
<literallayout class='monospaced'>
|
|
$ make clean
|
|
$ make tools/snep-send.o
|
|
</literallayout>
|
|
The <filename>devshell</filename> commands cause the failure
|
|
to clearly be visible.
|
|
In this case, a missing dependency exists for the "neard"
|
|
Makefile target.
|
|
Here is some abbreviated, sample output with the
|
|
missing dependency clearly visible at the end:
|
|
<literallayout class='monospaced'>
|
|
i586-poky-linux-gcc -m32 -march=i586 ‐‐sysroot=/home/scott-lenovo/......
|
|
.
|
|
.
|
|
.
|
|
tools/snep-send.c
|
|
In file included from tools/snep-send.c:16:0:
|
|
tools/../src/near.h:41:23: fatal error: near/dbus.h: No such file or directory
|
|
#include <near/dbus.h>
|
|
^
|
|
compilation terminated.
|
|
make: *** [tools/snep-send.o] Error 1
|
|
$
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='creating-a-patch-for-the-fix'>
|
|
<title>Creating a Patch for the Fix</title>
|
|
|
|
<para>
|
|
Because there is a missing dependency for the Makefile
|
|
target, you need to patch the
|
|
<filename>Makefile.am</filename> file, which is generated
|
|
from <filename>Makefile.in</filename>.
|
|
You can use Quilt to create the patch:
|
|
<literallayout class='monospaced'>
|
|
$ quilt new parallelmake.patch
|
|
Patch patches/parallelmake.patch is now on top
|
|
$ quilt add Makefile.am
|
|
File Makefile.am added to patch patches/parallelmake.patch
|
|
</literallayout>
|
|
For more information on using Quilt, see the
|
|
"<link linkend='using-a-quilt-workflow'>Using a Quilt Workflow</link>"
|
|
section.
|
|
</para>
|
|
|
|
<para>
|
|
At this point you need to make the edits to
|
|
<filename>Makefile.am</filename> to add the missing
|
|
dependency.
|
|
For our example, you have to add the following line
|
|
to the file:
|
|
<literallayout class='monospaced'>
|
|
tools/snep-send.$(OBJEXT): include/near/dbus.h
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
Once you have edited the file, use the
|
|
<filename>refresh</filename> command to create the patch:
|
|
<literallayout class='monospaced'>
|
|
$ quilt refresh
|
|
Refreshed patch patches/parallelmake.patch
|
|
</literallayout>
|
|
Once the patch file exists, you need to add it back to the
|
|
originating recipe folder.
|
|
Here is an example assuming a top-level
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
named <filename>poky</filename>:
|
|
<literallayout class='monospaced'>
|
|
$ cp patches/parallelmake.patch poky/meta/recipes-connectivity/neard/neard
|
|
</literallayout>
|
|
The final thing you need to do to implement the fix in the
|
|
build is to update the "neard" recipe (i.e.
|
|
<filename>neard-0.14.bb</filename> so that the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
|
|
statement includes the patch file.
|
|
The recipe file is in the folder above the patch.
|
|
Here is what the edited <filename>SRC_URI</filename>
|
|
statement would look like:
|
|
<literallayout class='monospaced'>
|
|
SRC_URI = "${KERNELORG_MIRROR}/linux/network/nfc/${BPN}-${PV}.tar.xz \
|
|
file://neard.in \
|
|
file://neard.service.in \
|
|
file://parallelmake.patch \
|
|
"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
With the patch complete and moved to the correct folder and
|
|
the <filename>SRC_URI</filename> statement updated, you can
|
|
exit the <filename>devshell</filename>:
|
|
<literallayout class='monospaced'>
|
|
$ exit
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='testing-the-build'>
|
|
<title>Testing the Build</title>
|
|
|
|
<para>
|
|
With everything in place, you can get back to trying the
|
|
build again locally:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake neard
|
|
</literallayout>
|
|
This build should succeed.
|
|
</para>
|
|
|
|
<para>
|
|
Now you can open up a <filename>devshell</filename> again
|
|
and repeat the clean and make operations as follows:
|
|
<literallayout class='monospaced'>
|
|
$ bitbake neard -c devshell
|
|
$ make clean
|
|
$ make tools/snep-send.o
|
|
</literallayout>
|
|
The build should work without issue.
|
|
</para>
|
|
|
|
<para>
|
|
As with all solved problems, if they originated upstream, you
|
|
need to submit the fix for the recipe in OE-Core and upstream
|
|
so that the problem is taken care of at its source.
|
|
See the
|
|
"<link linkend='how-to-submit-a-change'>How to Submit a Change</link>"
|
|
section for more information.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="examining-builds-using-toaster">
|
|
<title>Examining Builds Using the Toaster API</title>
|
|
|
|
<para>
|
|
Toaster is an Application Programming Interface (API) and
|
|
web-based interface to the OpenEmbedded build system, which uses
|
|
BitBake.
|
|
Both interfaces are based on a Representational State Transfer
|
|
(REST) API that queries for and returns build information using
|
|
<filename>GET</filename> and <filename>JSON</filename>.
|
|
These types of search operations retrieve sets of objects from
|
|
a datastore used to collect build information.
|
|
The results contain all the data for the objects being returned.
|
|
You can order the results of the search by key and the search
|
|
parameters are consistent for all object types.
|
|
</para>
|
|
|
|
<para>
|
|
Using the interfaces you can do the following:
|
|
<itemizedlist>
|
|
<listitem><para>See information about the tasks executed
|
|
and reused during the build.</para></listitem>
|
|
<listitem><para>See what is built (recipes and
|
|
packages) and what packages were installed into the final
|
|
image.</para></listitem>
|
|
<listitem><para>See performance-related information such
|
|
as build time, CPU usage, and disk I/O.</para></listitem>
|
|
<listitem><para>Examine error, warning and trace messages
|
|
to aid in debugging.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<note>
|
|
<para>This release of Toaster provides you with information
|
|
about a BitBake run.
|
|
The tool does not allow you to configure and launch a build.
|
|
However, future development includes plans to integrate the
|
|
configuration and build launching capabilities of
|
|
<ulink url='&YOCTO_HOME_URL;/tools-resources/projects/hob'>Hob</ulink>.
|
|
</para>
|
|
<para>For more information on using Hob to build an image,
|
|
see the
|
|
"<link linkend='image-development-using-hob'>Image Development Using Hob</link>"
|
|
section.</para>
|
|
</note>
|
|
|
|
<para>
|
|
The remainder of this section describes what you need to have in
|
|
place to use Toaster, how to start it, use it, and stop it.
|
|
For additional information on installing and running Toaster, see the
|
|
"<ulink url='https://wiki.yoctoproject.org/wiki/Toaster#Installation_and_Running'>Installation and Running</ulink>"
|
|
section of the "Toaster" wiki page.
|
|
For complete information on the API and its search operation
|
|
URI, parameters, and responses, see the
|
|
<ulink url='https://wiki.yoctoproject.org/wiki/REST_API_Contracts'>REST API Contracts</ulink>
|
|
Wiki page.
|
|
</para>
|
|
|
|
<section id='starting-toaster'>
|
|
<title>Starting Toaster</title>
|
|
|
|
<para>
|
|
Getting set up to use and start Toaster is simple.
|
|
First, be sure you have met the following requirements:
|
|
<itemizedlist>
|
|
<listitem><para>You have set up your
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
by cloning the upstream <filename>poky</filename>
|
|
repository.
|
|
See the
|
|
<link linkend='local-yp-release'>Yocto Project Release</link>
|
|
item for information on how to set up the Source
|
|
Directory.</para></listitem>
|
|
<listitem><para>Be sure your build machine has
|
|
<ulink url='http://en.wikipedia.org/wiki/Django_%28web_framework%29'>Django</ulink>
|
|
version 1.5 installed.</para></listitem>
|
|
<listitem><para>Make sure that port 8000 and 8200 are
|
|
free (i.e. they have no servers on them).
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
Once you have met the requirements, follow these steps to
|
|
start Toaster running in the background of your shell:
|
|
<orderedlist>
|
|
<listitem><para><emphasis>Set up your build environment:</emphasis>
|
|
Source a build environment script (i.e.
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
|
or
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#structure-memres-core-script'><filename>oe-init-build-env-memres</filename></ulink>).
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Start Toaster:</emphasis>
|
|
Start the Toaster service using this
|
|
command from within your
|
|
<link linkend='build-directory'>Build Directory</link>:
|
|
<literallayout class='monospaced'>
|
|
$ source toaster start
|
|
</literallayout></para></listitem>
|
|
<note>
|
|
The Toaster must be started and running in order
|
|
for it to collect data.
|
|
</note>
|
|
</orderedlist>
|
|
</para>
|
|
|
|
<para>
|
|
When Toaster starts, it creates some additional files in your
|
|
Build Directory.
|
|
Deleting these files will cause you to lose data or interrupt
|
|
Toaster:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis><filename>toaster.sqlite</filename>:</emphasis>
|
|
Toaster's database file.</para></listitem>
|
|
<listitem><para><emphasis><filename>toaster_web.log</filename>:</emphasis>
|
|
The log file of the web server.</para></listitem>
|
|
<listitem><para><emphasis><filename>toaster_ui.log</filename>:</emphasis>
|
|
The log file of the user interface component.
|
|
</para></listitem>
|
|
<listitem><para><emphasis><filename>toastermain.pid</filename>:</emphasis>
|
|
The PID of the web server.</para></listitem>
|
|
<listitem><para><emphasis><filename>toasterui.pid</filename>:</emphasis>
|
|
The PID of the DSI data bridge.</para></listitem>
|
|
<listitem><para><emphasis><filename>bitbake-cookerdaemon.log</filename>:</emphasis>
|
|
The BitBake server's log file.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='using-toaster'>
|
|
<title>Using Toaster</title>
|
|
|
|
<para>
|
|
Once Toaster is running, it logs information for any BitBake
|
|
run from your Build Directory.
|
|
This logging is automatic.
|
|
All you need to do is access and use the information.
|
|
</para>
|
|
|
|
<para>
|
|
You access the information one of two ways:
|
|
<itemizedlist>
|
|
<listitem><para>Open a Browser and enter
|
|
<filename>http://localhost:8000</filename>
|
|
for the URL.
|
|
</para></listitem>
|
|
<listitem><para>Use the <filename>xdg-open</filename>
|
|
tool from the shell and pass it the same URL.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
Either method opens the home page for the Toaster interface.
|
|
</para>
|
|
|
|
<note><title>Notes</title>
|
|
<para>
|
|
For information on how to delete information from the Toaster
|
|
database, see the
|
|
<ulink url='https://wiki.yoctoproject.org/wiki/Toaster#Deleting_a_Build_from_the_Toaster_Database'>Deleting a Build from the Toaster Database</ulink>
|
|
wiki page.
|
|
</para>
|
|
|
|
<para>
|
|
For information on how to set up an instance of Toaster on
|
|
a remote host, see the
|
|
<ulink url='https://wiki.yoctoproject.org/wiki/Toaster#Setting_up_a_Toaster_Instance_on_a_Remote_Host'>Setting Up a Toaster Instance on a Remote Host</ulink>
|
|
wiki page.
|
|
</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id='examining-toaster-data'>
|
|
<title>Examining Toaster Data</title>
|
|
|
|
<para>
|
|
The Toaster database is persistent regardless of whether you
|
|
start or stop the service.
|
|
</para>
|
|
|
|
<para>
|
|
Toaster's interface shows you a list of builds
|
|
(successful and unsuccessful) for which it has data.
|
|
You can click on any build to see related information.
|
|
This information includes configuration details, information
|
|
about tasks, all recipes and packages built and their
|
|
dependencies, packages and their directory structure as
|
|
installed in your final image,
|
|
execution time, CPU usage and disk I/O per task.
|
|
</para>
|
|
|
|
<para>
|
|
For details on the interface, see the
|
|
<ulink url='https://www.yoctoproject.org/documentation/toaster-manual'>Toaster Manual</ulink>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='stopping-toaster'>
|
|
<title>Stopping Toaster</title>
|
|
|
|
<para>
|
|
Stop the Toaster service with the following command
|
|
from with the
|
|
<link linkend='build-directory'>Build Directory</link>:
|
|
<literallayout class='monospaced'>
|
|
$ source toaster stop
|
|
</literallayout>
|
|
The service stops but the Toaster database remains persistent.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="platdev-oprofile">
|
|
<title>Profiling with OProfile</title>
|
|
|
|
<para>
|
|
<ulink url="http://oprofile.sourceforge.net/">OProfile</ulink> is a
|
|
statistical profiler well suited for finding performance
|
|
bottlenecks in both user-space software and in the kernel.
|
|
This profiler provides answers to questions like "Which functions does my application spend
|
|
the most time in when doing X?"
|
|
Because the OpenEmbedded build system is well integrated with OProfile, it makes profiling
|
|
applications on target hardware straight forward.
|
|
<note>
|
|
For more information on how to set up and run OProfile, see the
|
|
"<ulink url='&YOCTO_DOCS_PROF_URL;#profile-manual-oprofile'>oprofile</ulink>"
|
|
section in the Yocto Project Profiling and Tracing Manual.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
To use OProfile, you need an image that has OProfile installed.
|
|
The easiest way to do this is with "tools-profile" in the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'>IMAGE_FEATURES</ulink></filename> variable.
|
|
You also need debugging symbols to be available on the system where the analysis
|
|
takes place.
|
|
You can gain access to the symbols by using "dbg-pkgs" in the
|
|
<filename>IMAGE_FEATURES</filename> variable or by
|
|
installing the appropriate DBG (<filename>-dbg</filename>) packages.
|
|
</para>
|
|
|
|
<para>
|
|
For successful call graph analysis, the binaries must preserve the frame
|
|
pointer register and should also be compiled with the
|
|
<filename>-fno-omit-framepointer</filename> flag.
|
|
You can achieve this by setting the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-SELECTED_OPTIMIZATION'>SELECTED_OPTIMIZATION</ulink></filename>
|
|
variable with the following options:
|
|
<literallayout class='monospaced'>
|
|
-fexpensive-optimizations
|
|
-fno-omit-framepointer
|
|
-frename-registers
|
|
-O2
|
|
</literallayout>
|
|
You can also achieve it by setting the
|
|
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-DEBUG_BUILD'>DEBUG_BUILD</ulink></filename>
|
|
variable to "1" in the <filename>local.conf</filename> configuration file.
|
|
If you use the <filename>DEBUG_BUILD</filename> variable,
|
|
you also add extra debugging information that can make the debug
|
|
packages large.
|
|
</para>
|
|
|
|
<section id="platdev-oprofile-target">
|
|
<title>Profiling on the Target</title>
|
|
|
|
<para>
|
|
Using OProfile, you can perform all the profiling work on the target device.
|
|
A simple OProfile session might look like the following:
|
|
</para>
|
|
|
|
<para>
|
|
<literallayout class='monospaced'>
|
|
# opcontrol ‐‐reset
|
|
# opcontrol ‐‐start ‐‐separate=lib ‐‐no-vmlinux -c 5
|
|
.
|
|
.
|
|
[do whatever is being profiled]
|
|
.
|
|
.
|
|
# opcontrol ‐‐stop
|
|
$ opreport -cl
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
In this example, the <filename>reset</filename> command clears any previously profiled data.
|
|
The next command starts OProfile.
|
|
The options used when starting the profiler separate dynamic library data
|
|
within applications, disable kernel profiling, and enable callgraphing up to
|
|
five levels deep.
|
|
<note>
|
|
To profile the kernel, you would specify the
|
|
<filename>‐‐vmlinux=/path/to/vmlinux</filename> option.
|
|
The <filename>vmlinux</filename> file is usually in the source directory in the
|
|
<filename>/boot/</filename> directory and must match the running kernel.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
After you perform your profiling tasks, the next command stops the profiler.
|
|
After that, you can view results with the <filename>opreport</filename> command with options
|
|
to see the separate library symbols and callgraph information.
|
|
</para>
|
|
|
|
<para>
|
|
Callgraphing logs information about time spent in functions and about a function's
|
|
calling function (parent) and called functions (children).
|
|
The higher the callgraphing depth, the more accurate the results.
|
|
However, higher depths also increase the logging overhead.
|
|
Consequently, you should take care when setting the callgraphing depth.
|
|
<note>
|
|
On ARM, binaries need to have the frame pointer enabled for callgraphing to work.
|
|
To accomplish this use the <filename>-fno-omit-framepointer</filename> option
|
|
with <filename>gcc</filename>.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
For more information on using OProfile, see the OProfile
|
|
online documentation at
|
|
<ulink url="http://oprofile.sourceforge.net/docs/"/>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-oprofile-oprofileui">
|
|
<title>Using OProfileUI</title>
|
|
|
|
<para>
|
|
A graphical user interface for OProfile is also available.
|
|
You can download and build this interface from the Yocto Project at
|
|
<ulink url="&YOCTO_GIT_URL;/cgit.cgi/oprofileui/"></ulink>.
|
|
If the "tools-profile" image feature is selected, all necessary binaries
|
|
are installed onto the target device for OProfileUI interaction.
|
|
For a list of image features that ship with the Yocto Project,
|
|
see the
|
|
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-features-image'>Image Features</ulink>"
|
|
section in the Yocto Project Reference Manual.
|
|
</para>
|
|
|
|
<para>
|
|
Even though the source directory usually includes all needed patches on the target device, you
|
|
might find you need other OProfile patches for recent OProfileUI features.
|
|
If so, see the <ulink url='&YOCTO_GIT_URL;/cgit.cgi/oprofileui/tree/README'>
|
|
OProfileUI README</ulink> for the most recent information.
|
|
</para>
|
|
|
|
<section id="platdev-oprofile-oprofileui-online">
|
|
<title>Online Mode</title>
|
|
|
|
<para>
|
|
Using OProfile in online mode assumes a working network connection with the target
|
|
hardware.
|
|
With this connection, you just need to run "oprofile-server" on the device.
|
|
By default, OProfile listens on port 4224.
|
|
<note>
|
|
You can change the port using the <filename>‐‐port</filename> command-line
|
|
option.
|
|
</note>
|
|
</para>
|
|
|
|
<para>
|
|
The client program is called <filename>oprofile-viewer</filename> and its UI is relatively
|
|
straight forward.
|
|
You access key functionality through the buttons on the toolbar, which
|
|
are duplicated in the menus.
|
|
Here are the buttons:
|
|
<itemizedlist>
|
|
<listitem><para><emphasis>Connect:</emphasis> Connects to the remote host.
|
|
You can also supply the IP address or hostname.</para></listitem>
|
|
<listitem><para><emphasis>Disconnect:</emphasis> Disconnects from the target.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Start:</emphasis> Starts profiling on the device.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Stop:</emphasis> Stops profiling on the device and
|
|
downloads the data to the local host.
|
|
Stopping the profiler generates the profile and displays it in the viewer.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Download:</emphasis> Downloads the data from the
|
|
target and generates the profile, which appears in the viewer.</para></listitem>
|
|
<listitem><para><emphasis>Reset:</emphasis> Resets the sample data on the device.
|
|
Resetting the data removes sample information collected from previous
|
|
sampling runs.
|
|
Be sure you reset the data if you do not want to include old sample information.
|
|
</para></listitem>
|
|
<listitem><para><emphasis>Save:</emphasis> Saves the data downloaded from the
|
|
target to another directory for later examination.</para></listitem>
|
|
<listitem><para><emphasis>Open:</emphasis> Loads previously saved data.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
The client downloads the complete profile archive from
|
|
the target to the host for processing.
|
|
This archive is a directory that contains the sample data, the object files,
|
|
and the debug information for the object files.
|
|
The archive is then converted using the <filename>oparchconv</filename> script, which is
|
|
included in this distribution.
|
|
The script uses <filename>opimport</filename> to convert the archive from
|
|
the target to something that can be processed on the host.
|
|
</para>
|
|
|
|
<para>
|
|
Downloaded archives reside in the
|
|
<link linkend='build-directory'>Build Directory</link> in
|
|
<filename>tmp</filename> and are cleared up when they are no longer in use.
|
|
</para>
|
|
|
|
<para>
|
|
If you wish to perform kernel profiling, you need to be sure
|
|
a <filename>vmlinux</filename> file that matches the running kernel is available.
|
|
In the source directory, that file is usually located in
|
|
<filename>/boot/vmlinux-KERNELVERSION</filename>, where
|
|
<filename>KERNEL-version</filename> is the version of the kernel.
|
|
The OpenEmbedded build system generates separate <filename>vmlinux</filename>
|
|
packages for each kernel it builds.
|
|
Thus, it should just be a question of making sure a matching package is
|
|
installed (e.g. <filename>opkg install kernel-vmlinux</filename>).
|
|
The files are automatically installed into development and profiling images
|
|
alongside OProfile.
|
|
A configuration option exists within the OProfileUI settings page that you can use to
|
|
enter the location of the <filename>vmlinux</filename> file.
|
|
</para>
|
|
|
|
<para>
|
|
Waiting for debug symbols to transfer from the device can be slow, and it
|
|
is not always necessary to actually have them on the device for OProfile use.
|
|
All that is needed is a copy of the filesystem with the debug symbols present
|
|
on the viewer system.
|
|
The "<link linkend='platdev-gdb-remotedebug-launch-gdb'>Launch GDB on the Host Computer</link>"
|
|
section covers how to create such a directory within
|
|
the source directory and how to use the OProfileUI Settings
|
|
Dialog to specify the location.
|
|
If you specify the directory, it will be used when the file checksums
|
|
match those on the system you are profiling.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="platdev-oprofile-oprofileui-offline">
|
|
<title>Offline Mode</title>
|
|
|
|
<para>
|
|
If network access to the target is unavailable, you can generate
|
|
an archive for processing in <filename>oprofile-viewer</filename> as follows:
|
|
<literallayout class='monospaced'>
|
|
# opcontrol ‐‐reset
|
|
# opcontrol ‐‐start ‐‐separate=lib ‐‐no-vmlinux -c 5
|
|
.
|
|
.
|
|
[do whatever is being profiled]
|
|
.
|
|
.
|
|
# opcontrol ‐‐stop
|
|
# oparchive -o my_archive
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
In the above example, <filename>my_archive</filename> is the name of the
|
|
archive directory where you would like the profile archive to be kept.
|
|
After the directory is created, you can copy it to another host and load it
|
|
using <filename>oprofile-viewer</filename> open functionality.
|
|
If necessary, the archive is converted.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='maintaining-open-source-license-compliance-during-your-products-lifecycle'>
|
|
<title>Maintaining Open Source License Compliance During Your Product's Lifecycle</title>
|
|
|
|
<para>
|
|
One of the concerns for a development organization using open source
|
|
software is how to maintain compliance with various open source
|
|
licensing during the lifecycle of the product.
|
|
While this section does not provide legal advice or
|
|
comprehensively cover all scenarios, it does
|
|
present methods that you can use to
|
|
assist you in meeting the compliance requirements during a software
|
|
release.
|
|
</para>
|
|
|
|
<para>
|
|
With hundreds of different open source licenses that the Yocto
|
|
Project tracks, it is difficult to know the requirements of each
|
|
and every license.
|
|
However, the requirements of the major FLOSS licenses can begin
|
|
to be covered by
|
|
assuming that three main areas of concern exist:
|
|
<itemizedlist>
|
|
<listitem><para>Source code must be provided.</para></listitem>
|
|
<listitem><para>License text for the software must be
|
|
provided.</para></listitem>
|
|
<listitem><para>Compilation scripts and modifications to the
|
|
source code must be provided.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
There are other requirements beyond the scope of these
|
|
three and the methods described in this section
|
|
(e.g. the mechanism through which source code is distributed).
|
|
</para>
|
|
|
|
<para>
|
|
As different organizations have different methods of complying with
|
|
open source licensing, this section is not meant to imply that
|
|
there is only one single way to meet your compliance obligations,
|
|
but rather to describe one method of achieving compliance.
|
|
The remainder of this section describes methods supported to meet the
|
|
previously mentioned three requirements.
|
|
Once you take steps to meet these requirements,
|
|
and prior to releasing images, sources, and the build system,
|
|
you should audit all artifacts to ensure completeness.
|
|
<note>
|
|
The Yocto Project generates a license manifest during
|
|
image creation that is located
|
|
in <filename>${DEPLOY_DIR}/licenses/<image_name-datestamp></filename>
|
|
to assist with any audits.
|
|
</note>
|
|
</para>
|
|
|
|
<section id='providing-the-source-code'>
|
|
<title>Providing the Source Code</title>
|
|
|
|
<para>
|
|
Compliance activities should begin before you generate the
|
|
final image.
|
|
The first thing you should look at is the requirement that
|
|
tops the list for most compliance groups - providing
|
|
the source.
|
|
The Yocto Project has a few ways of meeting this
|
|
requirement.
|
|
</para>
|
|
|
|
<para>
|
|
One of the easiest ways to meet this requirement is
|
|
to provide the entire
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-DL_DIR'><filename>DL_DIR</filename></ulink>
|
|
used by the build.
|
|
This method, however, has a few issues.
|
|
The most obvious is the size of the directory since it includes
|
|
all sources used in the build and not just the source used in
|
|
the released image.
|
|
It will include toolchain source, and other artifacts, which
|
|
you would not generally release.
|
|
However, the more serious issue for most companies is accidental
|
|
release of proprietary software.
|
|
The Yocto Project provides an
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-archiver'><filename>archiver</filename></ulink>
|
|
class to help avoid some of these concerns.
|
|
</para>
|
|
|
|
<para>
|
|
Before you employ <filename>DL_DIR</filename> or the
|
|
archiver class, you need to decide how you choose to
|
|
provide source.
|
|
The source archiver class can generate tarballs and SRPMs
|
|
and can create them with various levels of compliance in mind.
|
|
</para>
|
|
|
|
<para>
|
|
One way of doing this (but certainly not the only way) is to
|
|
release just the source as a tarball.
|
|
You can do this by adding the following to the
|
|
<filename>local.conf</filename> file found in the
|
|
<link linkend='build-directory'>Build Directory</link>:
|
|
<literallayout class='monospaced'>
|
|
INHERIT += "archiver"
|
|
ARCHIVER_MODE[src] = "original"
|
|
</literallayout>
|
|
During the creation of your image, the source from all
|
|
recipes that deploy packages to the image is placed within
|
|
subdirectories of
|
|
<filename>DEPLOY_DIR/sources</filename> based on the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#var-LICENSE'><filename>LICENSE</filename></ulink>
|
|
for each recipe.
|
|
Releasing the entire directory enables you to comply with
|
|
requirements concerning providing the unmodified source.
|
|
It is important to note that the size of the directory can
|
|
get large.
|
|
</para>
|
|
|
|
<para>
|
|
A way to help mitigate the size issue is to only release
|
|
tarballs for licenses that require the release of
|
|
source.
|
|
Let us assume you are only concerned with GPL code as
|
|
identified with the following:
|
|
<literallayout class='monospaced'>
|
|
$ cd poky/build/tmp/deploy/sources
|
|
$ mkdir ~/gpl_source_release
|
|
$ for dir in */*GPL*; do cp -r $dir ~/gpl_source_release; done
|
|
</literallayout>
|
|
At this point, you could create a tarball from the
|
|
<filename>gpl_source_release</filename> directory and
|
|
provide that to the end user.
|
|
This method would be a step toward achieving compliance
|
|
with section 3a of GPLv2 and with section 6 of GPLv3.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='providing-license-text'>
|
|
<title>Providing License Text</title>
|
|
|
|
<para>
|
|
One requirement that is often overlooked is inclusion
|
|
of license text.
|
|
This requirement also needs to be dealt with prior to
|
|
generating the final image.
|
|
Some licenses require the license text to accompany
|
|
the binary.
|
|
You can achieve this by adding the following to your
|
|
<filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
COPY_LIC_MANIFEST = "1"
|
|
COPY_LIC_DIRS = "1"
|
|
</literallayout>
|
|
Adding these statements to the configuration file ensures
|
|
that the licenses collected during package generation
|
|
are included on your image.
|
|
As the source archiver has already archived the original
|
|
unmodified source that contains the license files,
|
|
you would have already met the requirements for inclusion
|
|
of the license information with source as defined by the GPL
|
|
and other open source licenses.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='providing-compilation-scripts-and-source-code-modifications'>
|
|
<title>Providing Compilation Scripts and Source Code Modifications</title>
|
|
|
|
<para>
|
|
At this point, we have addressed all we need to address
|
|
prior to generating the image.
|
|
The next two requirements are addressed during the final
|
|
packaging of the release.
|
|
</para>
|
|
|
|
<para>
|
|
By releasing the version of the OpenEmbedded build system
|
|
and the layers used during the build, you will be providing both
|
|
compilation scripts and the source code modifications in one
|
|
step.
|
|
</para>
|
|
|
|
<para>
|
|
If the deployment team has a
|
|
<ulink url='&YOCTO_DOCS_BSP_URL;#bsp-layers'>BSP layer</ulink>
|
|
and a distro layer, and those those layers are used to patch,
|
|
compile, package, or modify (in any way) any open source
|
|
software included in your released images, you
|
|
might be required to to release those layers under section 3 of
|
|
GPLv2 or section 1 of GPLv3.
|
|
One way of doing that is with a clean
|
|
checkout of the version of the Yocto Project and layers used
|
|
during your build.
|
|
Here is an example:
|
|
<literallayout class='monospaced'>
|
|
# We built using the &DISTRO_NAME; branch of the poky repo
|
|
$ git clone -b &DISTRO_NAME; git://git.yoctoproject.org/poky
|
|
$ cd poky
|
|
# We built using the release_branch for our layers
|
|
$ git clone -b release_branch git://git.mycompany.com/meta-my-bsp-layer
|
|
$ git clone -b release_branch git://git.mycompany.com/meta-my-software-layer
|
|
# clean up the .git repos
|
|
$ find . -name ".git" -type d -exec rm -rf {} \;
|
|
</literallayout>
|
|
One thing a development organization might want to consider
|
|
for end-user convenience is to modify
|
|
<filename>meta-yocto/conf/bblayers.conf.sample</filename> to
|
|
ensure that when the end user utilizes the released build
|
|
system to build an image, the development organization's
|
|
layers are included in the <filename>bblayers.conf</filename>
|
|
file automatically:
|
|
<literallayout class='monospaced'>
|
|
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
|
|
# changes incompatibly
|
|
LCONF_VERSION = "6"
|
|
|
|
BBPATH = "${TOPDIR}"
|
|
BBFILES ?= ""
|
|
|
|
BBLAYERS ?= " \
|
|
##OEROOT##/meta \
|
|
##OEROOT##/meta-yocto \
|
|
##OEROOT##/meta-yocto-bsp \
|
|
##OEROOT##/meta-mylayer \
|
|
"
|
|
|
|
BBLAYERS_NON_REMOVABLE ?= " \
|
|
##OEROOT##/meta \
|
|
##OEROOT##/meta-yocto \
|
|
"
|
|
</literallayout>
|
|
Creating and providing an archive of the
|
|
<link linkend='metadata'>Metadata</link> layers
|
|
(recipes, configuration files, and so forth)
|
|
enables you to meet your
|
|
requirements to include the scripts to control compilation
|
|
as well as any modifications to the original source.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='using-the-error-reporting-tool'>
|
|
<title>Using the Error Reporting Tool</title>
|
|
|
|
<para>
|
|
The error reporting tool allows you to
|
|
submit errors encountered during builds to a central database.
|
|
Outside of the build environment, you can use a web interface to
|
|
browse errors, view statistics, and query for errors.
|
|
The tool works using a client-server system where the client
|
|
portion is integrated with the installed Yocto Project
|
|
<link linkend='source-directory'>Source Directory</link>
|
|
(e.g. <filename>poky</filename>).
|
|
The server receives the information collected and saves it in a
|
|
database.
|
|
</para>
|
|
|
|
<para>
|
|
A live instance of the error reporting server exists at
|
|
<ulink url='http://errors.yoctoproject.org'></ulink>.
|
|
This server exists so that when you want to get help with
|
|
build failures, you can submit all of the information on the
|
|
failure easily and then point to the URL in your bug report
|
|
or send an email to the mailing list.
|
|
<note>
|
|
If you send error reports to this server, the reports become
|
|
publicly visible.
|
|
</note>
|
|
</para>
|
|
|
|
<section id='enabling-and-using-the-tool'>
|
|
<title>Enabling and Using the Tool</title>
|
|
|
|
<para>
|
|
By default, the error reporting tool is disabled.
|
|
You can enable it by inheriting the
|
|
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-report-error'><filename>report-error</filename></ulink>
|
|
class by adding the following statement to the end of
|
|
your <filename>local.conf</filename> file in your
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
<literallayout class='monospaced'>
|
|
INHERIT += "report-error"
|
|
</literallayout>
|
|
</para>
|
|
|
|
<para>
|
|
By default, the error reporting feature stores information in
|
|
<filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-LOG_DIR'><filename>LOG_DIR</filename></ulink><filename>}/error-report</filename>.
|
|
However, you can specify a directory to use by adding the following
|
|
to your <filename>local.conf</filename> file:
|
|
<literallayout class='monospaced'>
|
|
ERR_REPORT_DIR = "path"
|
|
</literallayout>
|
|
Enabling error reporting causes the build process to collect
|
|
the errors and store them in a file as previously described.
|
|
When the build system encounters an error, it includes a command
|
|
as part of the console output.
|
|
You can run the command to send the error file to the server.
|
|
For example, the following command sends the errors to an upstream
|
|
server:
|
|
<literallayout class='monospaced'>
|
|
send-error-report /home/brandusa/project/poky/build/tmp/log/error-report/error_report_201403141617.txt [server]
|
|
</literallayout>
|
|
In the above example, the <filename>server</filename> parameter is
|
|
optional.
|
|
By default, the errors are sent to a database used by the entire
|
|
community.
|
|
If you specify a particular server, you can send them to a different
|
|
database.
|
|
</para>
|
|
|
|
<para>
|
|
When sending the error file, you receive a link that corresponds
|
|
to your entry in the database.
|
|
For example, here is a typical link:
|
|
<literallayout class='monospaced'>
|
|
http://localhost:8000/Errors/Search/1/158
|
|
</literallayout>
|
|
Following the link takes you to a web interface where you can
|
|
browse, query the errors, and view statistics.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='disabling-the-tool'>
|
|
<title>Disabling the Tool</title>
|
|
|
|
<para>
|
|
To disable the error reporting feature, simply remove or comment
|
|
out the following statement from the end of your
|
|
<filename>local.conf</filename> file in your
|
|
<link linkend='build-directory'>Build Directory</link>.
|
|
<literallayout class='monospaced'>
|
|
INHERIT += "report-error"
|
|
</literallayout>
|
|
</para>
|
|
</section>
|
|
|
|
<section id='setting-up-your-own-error-reporting-server'>
|
|
<title>Setting Up Your Own Error Reporting Server</title>
|
|
|
|
<para>
|
|
If you want to set up your own error reporting server, you
|
|
can obtain the code from the Git repository at
|
|
<ulink url='http://git.yoctoproject.org/cgit/cgit.cgi/error-report-web/'></ulink>.
|
|
Instructions on how to set it up are in the README document.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
</chapter>
|
|
|
|
<!--
|
|
vim: expandtab tw=80 ts=4
|
|
-->
|