diff options
author | Patrick Williams <patrick@stwcx.xyz> | 2015-09-15 22:41:29 +0300 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2015-09-15 22:41:29 +0300 |
commit | 21f9b84b4b729fbd7acbd465e7a3f726e4d20f91 (patch) | |
tree | eb2d091d427ca0813b445509d59cc8e27e8ad25f /yocto-poky/documentation/dev-manual/dev-manual-common-tasks.xml | |
parent | 101cef31e2bf54c678501155cd2106251acbd076 (diff) | |
parent | c124f4f2e04dca16a428a76c89677328bc7bf908 (diff) | |
download | openbmc-21f9b84b4b729fbd7acbd465e7a3f726e4d20f91.tar.xz |
Merge commit 'c124f4f2e04dca16a428a76c89677328bc7bf908' as 'yocto-poky'
Diffstat (limited to 'yocto-poky/documentation/dev-manual/dev-manual-common-tasks.xml')
-rw-r--r-- | yocto-poky/documentation/dev-manual/dev-manual-common-tasks.xml | 10049 |
1 files changed, 10049 insertions, 0 deletions
diff --git a/yocto-poky/documentation/dev-manual/dev-manual-common-tasks.xml b/yocto-poky/documentation/dev-manual/dev-manual-common-tasks.xml new file mode 100644 index 000000000..e927a89be --- /dev/null +++ b/yocto-poky/documentation/dev-manual/dev-manual-common-tasks.xml @@ -0,0 +1,10049 @@ +<!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-selftest</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 = "3" + </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 recipe 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/</filename><replaceable>package</replaceable><filename>/</filename><replaceable>file</replaceable><filename>.inc</filename> + instead of <filename>require </filename><replaceable>file</replaceable><filename>.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 should try to address that + deficiency instead of overlaying the include file. + For example, you could address this by getting the + maintainer of the include file to add a variable or + variables to make it easy to override the parts needing + to be overridden. + </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> + As an actual example, here's a line from the recipe for + the OProfile profiler, which lists an extra build-time + dependency when building specifically for 64-bit PowerPC: + <literallayout class='monospaced'> + DEPENDS_append_powerpc64 = " libpfm4" + </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-<replaceable>layer_name</replaceable></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 \ + " + </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 = "r45" + + SRC_URI = "file://config file://machconfig" + S = "${WORKDIR}" + + PACKAGE_ARCH = "${MACHINE_ARCH}" + INHIBIT_DEFAULT_DEPS = "1" + + do_install() { + # Install file only if it has contents + install -d ${D}${sysconfdir}/formfactor/ + install -m 0644 ${S}/config ${D}${sysconfdir}/formfactor/ + if [ -s "${S}/machconfig" ]; then + install -m 0644 ${S}/machconfig ${D}${sysconfdir}/formfactor/ + fi + } + </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 + Emenlow BSP Layer named + <filename>meta-intel/meta-emenlow</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-emenlow/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" as part of the + <filename>FILESEXTRAPATHS</filename> 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, your append file would not even + use the <filename>FILESEXTRAPATHS</filename> 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 <replaceable>command</replaceable> [<replaceable>arguments</replaceable>] + </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>add-layer:</emphasis></filename> + Adds a layer to <filename>bblayers.conf</filename>. + </para></listitem> + <listitem><para><filename><emphasis>remove-layer:</emphasis></filename> + Removes a layer from <filename>bblayers.conf</filename> + </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><replaceable>layer</replaceable>.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><replaceable>layer</replaceable>/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><replaceable>layer</replaceable>/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 \ + " + </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>. + This class lists out the available + <ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink> + of which most map to package groups while some, such as + <filename>debug-tweaks</filename> and + <filename>read-only-rootfs</filename>, resolve as general + configuration settings. + </para> + + <para> + In summary, the file looks at the contents of the + <filename>IMAGE_FEATURES</filename> variable and then maps + or configures the feature accordingly. + Based on this information, the build system automatically + adds the appropriate packages or configurations to the + <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>glibc-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-base.bb</filename>. + </para> + + <para> + If you examine that recipe, you see that the + <filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'>PACKAGES</ulink></filename> + variable lists the package group packages to produce. + The <filename>inherit packagegroup</filename> statement + sets appropriate default values and automatically adds + <filename>-dev</filename>, <filename>-dbg</filename>, and + <filename>-ptest</filename> complementary packages for each + package specified in the <filename>PACKAGES</filename> + statement. + <note> + The <filename>inherit packages</filename> should be + located near the top of the recipe, certainly before + the <filename>PACKAGES</filename> statement. + </note> + </para> + + <para> + 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. + You can see examples of these further down in the + <filename>packagegroup-base.bb</filename> recipe. + </para> + + <para> + Here is a short, fabricated example showing the same basic + pieces: + <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-tools" + + 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 id='usingpoky-extend-customimage-image-name'> + <title>Customizing an Image Hostname</title> + + <para> + By default, the configured hostname (i.e. + <filename>/etc/hostname</filename>) in an image is the + same as the machine name. + For example, if + <ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink> + equals "qemux86", the configured hostname written to + <filename>/etc/hostname</filename> is "qemux86". + </para> + + <para> + You can customize this name by altering the value of the + "hostname" variable in the + <filename>base-files</filename> recipe using either + an append file or a configuration file. + Use the following in an append file: + <literallayout class='monospaced'> + hostname="myhostname" + </literallayout> + Use the following in a configuration file: + <literallayout class='monospaced'> + hostname_pn-base-files = "myhostname" + </literallayout> + </para> + + <para> + Changing the default value of the variable "hostname" can be + useful in certain situations. + For example, suppose you need to do extensive testing on an + image and you would like to easily identify the image + under test from existing images with typical default + hostnames. + In this situation, you could change the default hostname to + "testme", which results in all the images using the name + "testme". + Once testing is complete and you do not need to rebuild the + image for test any longer, you can easily reset the default + hostname. + </para> + + <para> + Another point of interest is that if you unset the variable, + the image will have no default hostname in the filesystem. + Here is an example that unsets the variable in a + configuration file: + <literallayout class='monospaced'> + hostname_pn-base-files = "" + </literallayout> + Having no default hostname in the filesystem is suitable for + environments that use dynamic hostnames such as virtual + machines. + </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-or-automatically-create-a-base-recipe'> + <title>Locate or Automatically Create a Base Recipe</title> + + <para> + You can always write a recipe from scratch. + However, two choices exist that can help you quickly get a + start on a new recipe: + <itemizedlist> + <listitem><para><emphasis><filename>recipetool</filename>:</emphasis> + A tool provided by the Yocto Project that automates + creation of a base recipe based on the source + files. + </para></listitem> + <listitem><para><emphasis>Existing Recipes:</emphasis> + Location and modification of an existing recipe that is + similar in function to the recipe you need. + </para></listitem> + </itemizedlist> + </para> + + <section id='new-recipe-creating-the-base-recipe-using-recipetool'> + <title>Creating the Base Recipe Using <filename>recipetool</filename></title> + + <para> + <filename>recipetool</filename> automates creation of + a base recipe given a set of source code files. + As long as you can extract or point to the source files, + the tool will construct a recipe and automatically + configure all pre-build information into the recipe. + For example, suppose you have an application that builds + using Autotools. + Creating the base recipe using + <filename>recipetool</filename> results in a recipe + that has the pre-build dependencies, license requirements, + and checksums configured. + </para> + + <para> + To run the tool, you just need to be in your + <link linkend='build-directory'>Build Directory</link> + and have sourced the build environment setup script + (i.e. + <ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>oe-init-build-env</filename></ulink> + or + <ulink url='&YOCTO_DOCS_REF_URL;#structure-memres-core-script'><filename>oe-init-build-env-memres</filename></ulink>). + Here is the basic <filename>recipetool</filename> syntax: + <note> + Running <filename>recipetool -h</filename> or + <filename>recipetool create -h</filename> produces the + Python-generated help, which presented differently + than what follows here. + </note> + <literallayout class='monospaced'> + recipetool -h + recipetool create [-h] + recipetool [-d] [-q] [--color auto | always | never ] create -o <replaceable>OUTFILE</replaceable> [-m] [-x <replaceable>EXTERNALSRC</replaceable>] <replaceable>source</replaceable> + + -d Enables debug output. + -q Outputs only errors (quiet mode). + --color Colorizes the output automatically, always, or never. + -h Displays Python generated syntax for recipetool. + create Causes recipetool to create a base recipe. The create + command is further defined with these options: + + -o <replaceable>OUTFILE</replaceable> Specifies the full path and filename for the generated + recipe. + -m Causes the recipe to be machine-specific rather than + architecture-specific (default). + -x <replaceable>EXTERNALSRC</replaceable> Fetches and extracts source files from <replaceable>source</replaceable> + and places them in <replaceable>EXTERNALSRC</replaceable>. + <replaceable>source</replaceable> must be a URL. + -h Displays Python-generated syntax for create. + <replaceable>source</replaceable> Specifies the source code on which to base the + recipe. + </literallayout> + </para> + + <para> + Running <filename>recipetool create -o</filename> <replaceable>OUTFILE</replaceable> + creates the base recipe and locates it properly in the + layer that contains your source files. + Following are some syntax examples: + </para> + + <para> + Use this syntax to generate a recipe based on <replaceable>source</replaceable>. + Once generated, the recipe resides in the existing source + code layer: + <literallayout class='monospaced'> + recipetool create -o <replaceable>OUTFILE</replaceable> <replaceable>source</replaceable> + </literallayout> + Use this syntax to generate a recipe using code that you + extract from <replaceable>source</replaceable>. + The extracted code is placed in its own layer defined + by <replaceable>EXTERNALSRC</replaceable>. + <literallayout class='monospaced'> + recipetool create -o <replaceable>OUTFILE</replaceable> -x <replaceable>EXTERNALSRC</replaceable> <replaceable>source</replaceable> + </literallayout> + Use this syntax to generate a recipe based on <replaceable>source</replaceable>. + The options direct <filename>recipetool</filename> to + run in "quiet mode" and to generate debugging information. + Once generated, the recipe resides in the existing source + code layer: + <literallayout class='monospaced'> + recipetool create -o <replaceable>OUTFILE</replaceable> <replaceable>source</replaceable> + </literallayout> + </para> + </section> + + <section id='new-recipe-locating-and-using-a-similar-recipe'> + <title>Locating and Using a Similar 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> + If for some reason you do not want to use + <filename>recipetool</filename> and you cannot + find an existing recipe that is close to meeting + your needs, you can use the following structure to + provide the fundamental areas of a new recipe. + <literallayout class='monospaced'> + DESCRIPTION = "" + HOMEPAGE = "" + LICENSE = "" + SECTION = "" + DEPENDS = "" + LIC_FILES_CHKSUM = "" + + SRC_URI = "" + </literallayout> + </para></listitem> + </itemizedlist> + </para> + </section> + </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'> + <replaceable>basename</replaceable>_<replaceable>version</replaceable>.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 complement + 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 + rmdir ${D}${bindir}/ + } + </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 complementing the + default functions. + You can implement functions in Python + instead of shell. + Both of these options are not seen in the majority of + recipes.</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>${<replaceable>varname</replaceable>}</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>"<replaceable>value</replaceable>"</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. + 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 = "-I${S}/myincludes " + </literallayout> + </para></listitem> + <listitem><para><emphasis>Overrides:</emphasis> - + You can use overrides to set a value conditionally, + typically based 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>${@<replaceable>python_code</replaceable>}</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>${@<replaceable>python_code</replaceable>}</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 file. + </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><replaceable>basename</replaceable></filename> of the recipe as described + in the previous section: + <literallayout class='monospaced'> + $ bitbake <replaceable>basename</replaceable> + </literallayout> + + </para> + + <para> + During the build, the OpenEmbedded build system creates a + temporary work directory for each 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 per-recipe temporary work directory is constructed as follows and + depends on several factors: + <literallayout class='monospaced'> + BASE_WORKDIR ?= "${TMPDIR}/work" + WORKDIR = "${BASE_WORKDIR}/${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.<replaceable>taskname</replaceable></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 which + 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.01a20.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> + Proper values for <filename>md5</filename> and + <filename>sha256</filename> checksums might be available + with other signatures on the download page for the upstream + source (e.g. <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> + If no <filename>SRC_URI</filename> checksums are specified + when you attempt to build the recipe, or you provide an + incorrect checksum, the build will produce an error for each + missing or incorrect checksum. + As part of the error message, the build system provides + the checksum string corresponding to the fetched file. + Once you have the correct checksums, you can copy and paste + them into your recipe and then run the build again to continue. + <note> + As mentioned, if the upstream source provides signatures + for verifying the downloaded source code, you should + verify those manually before setting the checksum values + in the recipe and continuing with the build. + </note> + </para> + + <para> + This final example is a bit more complicated and is from the + <filename>meta/recipes-sato/rxvt-unicode/rxvt-unicode_9.20.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-BP'><filename>BP</filename></ulink><filename>}</filename>, + <filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-BPN'><filename>BPN</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 usually end in + <filename>.patch</filename> or <filename>.diff</filename> but + can end with compressed suffixes such as + <filename>diff.gz</filename> and + <filename>patch.bz2</filename>, for example. + 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> or compressed versions of these + suffixes (e.g. <filename>diff.gz</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-BP'><filename>BP</filename></ulink> + and + <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. + See the + "<link linkend='new-recipe-fetching-code'>Fetching Code</link>" + section for additional information. + </para> + + <para> + 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 + modifying 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 + modifying 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, + enabled, or both 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> + <para> + For information on parallel Makefile issues, see the + "<link linkend='debugging-parallel-make-races'>Debugging Parallel Make Races</link>" + section. + </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 + the "Manual" bulleted item 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><title>Notes</title> + <itemizedlist> + <listitem><para> + 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. + </para></listitem> + <listitem><para> + <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. + </para></listitem> + </itemizedlist> + </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.bbclass</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 + <ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-insane'><filename>insane</filename></ulink> + 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;#ref-classes-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 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 + "<replaceable>previous_version</replaceable>+<replaceable>current_version</replaceable>". + 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() { + # 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() { + 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 GNU <filename>make</filename> 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" + + # Use the latest version at 26 Oct, 2013 + SRCREV = "9f107132a6a073cce37434ca9cda6917dd8d866b" + SRC_URI = "git://git.infradead.org/mtd-utils.git \ + file://add-exclusion-to-mkfs-jffs2-git-2.patch \ + " + + PV = "1.5.1+git${SRCPV}" + + S = "${WORKDIR}/git/" + + EXTRA_OEMAKE = "'CC=${CC}' 'RANLIB=${RANLIB}' 'AR=${AR}' 'CFLAGS=${CFLAGS} -I${S}/include -DWITHOUT_XATTR' 'BUILDDIR=${S}'" + + do_install () { + oe_runmake install DESTDIR=${D} SBINDIR=${sbindir} MANDIR=${mandir} INCLUDEDIR=${includedir} + } + + PACKAGES =+ "mtd-utils-jffs2 mtd-utils-ubifs mtd-utils-misc" + + FILES_mtd-utils-jffs2 = "${sbindir}/mkfs.jffs2 ${sbindir}/jffs2dump ${sbindir}/jffs2reader ${sbindir}/sumtool" + FILES_mtd-utils-ubifs = "${sbindir}/mkfs.ubifs ${sbindir}/ubi*" + FILES_mtd-utils-misc = "${sbindir}/nftl* ${sbindir}/ftl* ${sbindir}/rfd* ${sbindir}/doc* ${sbindir}/serve_image ${sbindir}/recv_image" + + PARALLEL_MAKE = "" + + BBCLASSEXTEND = "native" + </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 = "Xpm: X Pixmap extension library" + LICENSE = "BSD" + LIC_FILES_CHKSUM = "file://COPYING;md5=51f4270b012ecd4ab1a164f5f4ed6cf7" + DEPENDS += "libxext libsm libxt" + PE = "1" + + XORG_PN = "libXpm" + + PACKAGES =+ "sxpm cxpm" + FILES_cxpm = "${bindir}/cxpm" + FILES_sxpm = "${bindir}/sxpm" + </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>. + The <filename>bin_package</filename> class works well when + the files extracted into <filename>${S}</filename> are + already laid out in the way they should be laid out + on the target. + 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 straightforward + process. + This section describes how to add machines that are similar + to those that the Yocto Project already supports. + <note> + Although well within the capabilities of the Yocto Project, + adding a totally new architecture might require + changes to <filename>gcc/glibc</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 or include from a lower-level 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> + </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> + For more information on <filename>defconfig</filename> files, + 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> + + <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 includes + <filename>${PN}-staticdev</filename>, which represents 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, where + you can see how the static library files are defined: + <literallayout class='monospaced'> + PACKAGE_BEFORE_PN ?= "" + PACKAGES = "${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}" + PACKAGES_DYNAMIC = "^${PN}-locale-.*" + FILES = "" + + FILES_${PN} = "${bindir}/* ${sbindir}/* ${libexecdir}/* ${libdir}/lib*${SOLIBS} \ + ${sysconfdir} ${sharedstatedir} ${localstatedir} \ + ${base_bindir}/* ${base_sbindir}/* \ + ${base_libdir}/*${SOLIBS} \ + ${base_prefix}/lib/udev/rules.d ${prefix}/lib/udev/rules.d \ + ${datadir}/${BPN} ${libdir}/${BPN}/* \ + ${datadir}/pixmaps ${datadir}/applications \ + ${datadir}/idl ${datadir}/omf ${datadir}/sounds \ + ${libdir}/bonobo/servers" + + FILES_${PN}-bin = "${bindir}/* ${sbindir}/*" + + FILES_${PN}-doc = "${docdir} ${mandir} ${infodir} ${datadir}/gtk-doc \ + ${datadir}/gnome/help" + SECTION_${PN}-doc = "doc" + + FILES_SOLIBSDEV ?= "${base_libdir}/lib*${SOLIBSDEV} ${libdir}/lib*${SOLIBSDEV}" + FILES_${PN}-dev = "${includedir} ${FILES_SOLIBSDEV} ${libdir}/*.la \ + ${libdir}/*.o ${libdir}/pkgconfig ${datadir}/pkgconfig \ + ${datadir}/aclocal ${base_libdir}/*.o \ + ${libdir}/${BPN}/*.la ${base_libdir}/*.la" + SECTION_${PN}-dev = "devel" + ALLOW_EMPTY_${PN}-dev = "1" + RDEPENDS_${PN}-dev = "${PN} (= ${EXTENDPKGV})" + + FILES_${PN}-staticdev = "${libdir}/*.a ${base_libdir}/*.a ${libdir}/${BPN}/*.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 a different set 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 + <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES_DYNAMIC'><filename>PACKAGES_DYNAMIC</filename></ulink> + 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 straightforward 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 through 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>boot-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> + 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 build several native tools: + <literallayout class='monospaced'> + $ bitbake parted-native dosfstools-native mtools-native + </literallayout> + </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 <replaceable>command</replaceable> + </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 <replaceable>help_topic</replaceable> + </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 <replaceable>image</replaceable> help + </literallayout> + where <filename><replaceable>image</replaceable></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 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. + + -s, --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 --label msdos --active --align 1024 + + part / --source rootfs --ondisk sda --fstype=ext3 --label platform --align 1024 + + part swap --ondisk sda --size 44 --label swap1 --fstype=swap + + bootloader --timeout=10 --append="rootwait rootfstype=ext3 console=ttyPCH0,115200 console=tty0 vmalloc=256MB snd-hda-intel.enable_msi=0" + </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 the exact 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 + 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 <replaceable>mntpoint</replaceable> + </literallayout> + The <filename><replaceable>mntpoint</replaceable></filename> + is where the + partition will be mounted and must be of one of the + following forms: + <itemizedlist> + <listitem><para><filename>/<replaceable>path</replaceable></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 <replaceable>plugin-name</replaceable></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. + You can also save known configurations in a + <filename>defconfig</filename> file that the build system can use + for kernel configuration. + </para> + + <para> + This section describes how to use <filename>menuconfig</filename>, + create and use configuration fragments, and how to interactively + modify 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>. + You must also be sure of the state of your build in the + <link linkend='source-directory'>Source Directory</link>. + The following commands run <filename>menuconfig</filename> + assuming the Source Directory's top-level folder is + <filename>~/poky</filename>: + <literallayout class='monospaced'> + $ cd poky + $ source oe-init-build-env + $ bitbake linux-yocto -c kernel_configme -f + $ 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-a-defconfig-file'> + <title>Creating a <filename>defconfig</filename> File</title> + + <para> + A <filename>defconfig</filename> file is simply a + <filename>.config</filename> renamed to "defconfig". + You can use a <filename>defconfig</filename> file + to retain a known set of kernel configurations from which the + OpenEmbedded build system can draw to create the final + <filename>.config</filename> file. + <note> + Out-of-the-box, the Yocto Project never ships a + <filename>defconfig</filename> or + <filename>.config</filename> file. + The OpenEmbedded build system creates the final + <filename>.config</filename> file used to configure the + kernel. + </note> + </para> + + <para> + To create a <filename>defconfig</filename>, start with a + complete, working Linux kernel <filename>.config</filename> + file. + Copy that file to the appropriate + <filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink><filename>}</filename> + directory in your layer's + <filename>recipes-kernel/linux</filename> directory, and rename + the copied file to "defconfig". + Then, add the following lines to the linux-yocto + <filename>.bbappend</filename> file in your layer: + <literallayout class='monospaced'> + FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + SRC_URI += "file://defconfig" + </literallayout> + The + <ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink> + tells the build system how to search for the file, while the + <ulink url='&YOCTO_DOCS_REF_URL;#var-FILESEXTRAPATHS'><filename>FILESEXTRAPATHS</filename></ulink> + extends the + <ulink url='&YOCTO_DOCS_REF_URL;#var-FILESPATH'><filename>FILESPATH</filename></ulink> + variable (search directories) to include the + <filename>${PN}</filename> directory you created to hold the + configuration changes. + <note> + The build system applies the configurations from the + <filename>defconfig</filename> file before applying any + subsequent configuration fragments. + The final kernel configuration is a combination of the + configurations in the <filename>defconfig</filename> + file and any configuration fragments you provide. + You need to realize that if you have any configuration + fragments, the build system applies these on top of and + after applying the existing defconfig file configurations. + </note> + For more information on configuring the kernel, see the + "<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;#changing-the-configuration'>Changing the Configuration</ulink>" + and + "<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;#generating-configuration-files'>Generating Configuration Files</ulink>" + sections, both in the Yocto Project Linux Kernel Development + Manual. + </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>: + <literallayout class='monospaced'> + tmp/work/<replaceable>arch</replaceable>-poky-linux/linux-yocto-<replaceable>release_specific_string</replaceable>/linux-<replaceable>arch</replaceable>-<replaceable>build_type</replaceable> + </literallayout> + </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 fragment 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 fragment files? + You can place these 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 picks up the configuration and + adds 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 + configuration 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. + </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 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-devtool-in-your-workflow'><filename>devtool</filename></link> and + <link linkend='using-a-quilt-workflow'>Quilt</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 \ + " + </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 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 for 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 one of your selected + <ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_FEATURES'><filename>IMAGE_FEATURES</filename></ulink>. + When creating a new project, the default is to provide you + with an initial <filename>local.conf</filename> file that + enables this feature using the + <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_IMAGE_FEATURES'><filename>EXTRA_IMAGE_FEATURES</filename></ulink> variable with the line: + <literallayout class='monospaced'> + EXTRA_IMAGE_FEATURES = "debug-tweaks" + </literallayout> + To disable that feature, simply comment out that line in your + <filename>local.conf</filename> file, or + make sure <filename>IMAGE_FEATURES</filename> does not contain + "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 + <ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-extrausers'><filename>extrausers</filename></ulink> + 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. + You can find more information in the + <ulink url='http://git.yoctoproject.org/cgit/cgit.cgi/meta-selinux/'><filename>meta-selinux</filename></ulink> + layer. + </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 <replaceable>bitbake_target</replaceable></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 modify 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 <replaceable>root-directory-of-image</replaceable> + $ 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 <replaceable>image-directory</replaceable> + $ bitbake -u depexp -g <replaceable>image</replaceable> + </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 <replaceable>top-level-linux-build-directory</replaceable> + $ 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>glibc</filename>: + In general, follow this process: + <orderedlist> + <listitem><para>Remove <filename>glibc</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>glibc</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>glibc</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='building-images-for-more-than-one-machine'> + <title>Building Images for More than One Machine</title> + + <para> + A common scenario developers face is creating images for several + different machines that use the same software environment. + In this situation, it is tempting to set the + tunings and optimization flags for each build specifically for + the targeted hardware (i.e. "maxing out" the tunings). + Doing so can considerably add to build times and package feed + maintenance collectively for the machines. + For example, selecting tunes that are extremely specific to a + CPU core used in a system might enable some micro optimizations + in GCC for that particular system but would otherwise not gain + you much of a performance difference across the other systems + as compared to using a more general tuning across all the builds + (e.g. setting + <ulink url='var-DEFAULTTUNE'><filename>DEFAULTTUNE</filename></ulink> + specifically for each machine's build). + Rather than "max out" each build's tunings, you can take steps that + cause the OpenEmbedded build system to reuse software across the + various machines where it makes sense. + </para> + <para> + If build speed and package feed maintenance are considerations, + you should consider the points in this section that can help you + optimize your tunings to best consider build times and package + feed maintenance. + <itemizedlist> + <listitem><para><emphasis>Share the Build Directory:</emphasis> + If at all possible, share the + <ulink url='&YOCTO_DOCS_REF_URL;#var-TMPDIR'><filename>TMPDIR</filename></ulink> + across builds. + The Yocto Project supports switching between different + <ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink> + values in the same <filename>TMPDIR</filename>. + This practice is well supported and regularly used by + developers when building for multiple machines. + When you use the same <filename>TMPDIR</filename> for + multiple machine builds, the OpenEmbedded build system can + reuse the existing native and often cross-recipes for + multiple machines. + Thus, build time decreases. + <note> + If + <ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO'><filename>DISTRO</filename></ulink> + settings change or fundamental configuration settings + such as the filesystem layout, you need to work with + a clean <filename>TMPDIR</filename>. + Sharing <filename>TMPDIR</filename> under these + circumstances might work but since it is not + guaranteed, you should use a clean + <filename>TMPDIR</filename>. + </note> + </para></listitem> + <listitem><para><emphasis>Enable the Appropriate Package Architecture:</emphasis> + By default, the OpenEmbedded build system enables three + levels of package architectures: "all", "tune" or "package", + and "machine". + Any given recipe usually selects one of these package + architectures (types) for its output. + Depending for what a given recipe creates packages, making + sure you enable the appropriate package architecture can + directly impact the build time.</para> + <para>A recipe that just generates scripts can enable + "all" architecture because there are no binaries to build. + To specifically enable "all" architecture, be sure your + recipe inherits the + <ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-allarch'><filename>allarch</filename></ulink> + class. + This class is useful for "all" architectures because it + configures many variables so packages can be used across + multiple architectures.</para> + <para>If your recipe needs to generate packages that are + machine-specific or when one of the build or runtime + dependencies is already machine-architecture dependent, + which makes your recipe also machine-architecture dependent, + make sure your recipe enables the "machine" package + architecture through the + <ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE_ARCH'><filename>MACHINE_ARCH</filename></ulink> + variable: + <literallayout class='monospaced'> + PACKAGE_ARCH = "${MACHINE_ARCH}" + </literallayout> + When you do not specifically enable a package + architecture through the + <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_ARCH'><filename>PACKAGE_ARCH</filename></ulink>, + The OpenEmbedded build system defaults to the + <ulink url='&YOCTO_DOCS_REF_URL;#var-TUNE_PKGARCH'><filename>TUNE_PKGARCH</filename></ulink> + setting: + <literallayout class='monospaced'> + PACKAGE_ARCH = "${TUNE_PKGARCH}" + </literallayout> + </para></listitem> + <listitem><para><emphasis>Choose a Generic Tuning File if Possible:</emphasis> + Some tunes are more generic and can run on multiple targets + (e.g. an <filename>armv5</filename> set of packages could + run on <filename>armv6</filename> and + <filename>armv7</filename> processors in most cases). + Similarly, <filename>i486</filename> binaries could work + on <filename>i586</filename> and higher processors. + You should realize, however, that advances on newer + processor versions would not be used.</para> + <para>If you select the same tune for several different + machines, the OpenEmbedded build system reuses software + previously built, thus speeding up the overall build time. + Realize that even though a new sysroot for each machine is + generated, the software is not recompiled and only one + package feed exists. + </para></listitem> + <listitem><para><emphasis>Manage Granular Level Packaging:</emphasis> + Sometimes cases exist where injecting another level + of package architecture beyond the three higher levels + noted earlier can be useful. + For example, consider the <filename>emgd</filename> + graphics stack in the + <filename>meta-intel</filename> layer. + In this layer, a subset of software exists that is + compiled against something different from the rest of the + generic packages. + You can examine the key code in the + <ulink url='http://git.yoctoproject.org/cgit/cgit.cgi'>Source Repositories</ulink> + "daisy" branch in + <filename>classes/emgd-gl.bbclass</filename>. + For a specific set of packages, the code redefines + <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_ARCH'><filename>PACKAGE_ARCH</filename></ulink>. + <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_EXTRA_ARCHS'><filename>PACKAGE_EXTRA_ARCHS</filename></ulink> + is then appended with this extra tune name in + <filename>meta-intel-emgd.inc</filename>. + The result is that when searching for packages, the + build system uses a four-level search and the packages + in this new level are preferred as compared to the standard + tune. + The overall result is that the build system reuses most + software from the common tune except for specific cases + as needed. + </para></listitem> + <listitem><para><emphasis>Use Tools to Debug Issues:</emphasis> + Sometimes you can run into situations where software is + being rebuilt when you think it should not be. + For example, the OpenEmbedded build system might not be + using shared state between machines when you think it + should be. + These types of situations are usually due to references + to machine-specific variables such as + <ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE'><filename>MACHINE</filename></ulink>, + <ulink url='&YOCTO_DOCS_REF_URL;#var-SERIAL_CONSOLE'><filename>SERIAL_CONSOLE</filename></ulink>, + <ulink url='&YOCTO_DOCS_REF_URL;#var-XSERVER'><filename>XSERVER</filename></ulink>, + <ulink url='&YOCTO_DOCS_REF_URL;#var-MACHINE_FEATURES'><filename>MACHINE_FEATURES</filename></ulink>, + and so forth in code that is supposed to only be + tune-specific or when the recipe depends + (<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-RRECOMMENDS'><filename>RRECOMMENDS</filename></ulink>, + <ulink url='&YOCTO_DOCS_REF_URL;#var-RSUGGESTS'><filename>RSUGGESTS</filename></ulink>, + and so forth) on some other recipe that already has + <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_ARCH'><filename>PACKAGE_ARCH</filename></ulink> + defined as "${MACHINE_ARCH}". + <note> + Patches to fix any issues identified are most welcome + as these issues occasionally do occur. + </note></para> + <para>For such cases, you can use some tools to help you + sort out the situation: + <itemizedlist> + <listitem><para><emphasis><filename>sstate-diff-machines.sh</filename>:</emphasis> + You can find this tool in the + <filename>scripts</filename> directory of the + Source Repositories. + See the comments in the script for information on + how to use the tool. + </para></listitem> + <listitem><para><emphasis>BitBake's "-S printdiff" Option:</emphasis> + Using this option causes BitBake to try to + establish the closest signature match it can + (e.g. in the shared state cache) and then run + <filename>bitbake-diffsigs</filename> over the + matches to determine the stamps and delta where + these two stamp trees diverge. + </para></listitem> + </itemizedlist> + </para></listitem> + </itemizedlist> + </para> + </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='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 <replaceable>ip</replaceable> --port <replaceable>port</replaceable> --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='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 <replaceable>some-package</replaceable> 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/<replaceable>package-format</replaceable></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/<replaceable>package-format</replaceable></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 the test. + 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'> + <replaceable>result</replaceable>: <replaceable>testname</replaceable> + </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> + + <para> + For a list of Yocto Project recipes that are already + enabled with ptest, see the + <ulink url='https://wiki.yoctoproject.org/wiki/Ptest'>Ptest</ulink> + wiki page. + <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> + </para> + + <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/<replaceable>package</replaceable>/ptest</filename> + directory within the image, where + <filename><replaceable>package</replaceable></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>Regardless, 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 <replaceable>target</replaceable> + </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> when + building 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-<replaceable>myrecipe</replaceable> = "<replaceable>path-to-your-source-tree</replaceable>" + </literallayout> + </para> + + <para> + This next example shows how to accomplish the same thing by setting + <filename>EXTERNALSRC</filename> in the recipe itself or in the + recipe's append file: + <literallayout class='monospaced'> + EXTERNALSRC = "<replaceable>path</replaceable>" + EXTERNALSRC_BUILD = "<replaceable>path</replaceable>" + </literallayout> + <note> + In order for these settings to take effect, you must globally + or locally inherit the + <ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-externalsrc'><filename>externalsrc</filename></ulink> + class. + </note> + </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-<replaceable>myrecipe</replaceable> = "<replaceable>path-to-your-source-tree</replaceable>" + </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 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="selecting-dev-manager"> + <title>Selecting a Device Manager</title> + + <para> + The Yocto Project provides multiple ways to manage the device + manager (<filename>/dev</filename>): + <itemizedlist> + <listitem><para><emphasis>Persistent and Pre-Populated<filename>/dev</filename>:</emphasis> + For this case, the <filename>/dev</filename> directory + is persistent and the required device nodes are created + during the build. + </para></listitem> + <listitem><para><emphasis>Use <filename>devtmpfs</filename> with a Device Manager:</emphasis> + For this case, the <filename>/dev</filename> directory + is provided by the kernel as an in-memory file system and + is automatically populated by the kernel at runtime. + Additional configuration of device nodes is done in user + space by a device manager like + <filename>udev</filename> or + <filename>busybox-mdev</filename>. + </para></listitem> + </itemizedlist> + </para> + + <section id="static-dev-management"> + <title>Using Persistent and Pre-Populated<filename>/dev</filename></title> + + <para> + To use the static method for device population, you need to + set the + <ulink url='&YOCTO_DOCS_REF_URL;#var-USE_DEVFS'><filename>USE_DEVFS</filename></ulink> + variable to "0" as follows: + <literallayout class='monospaced'> + USE_DEVFS = "0" + </literallayout> + </para> + + <para> + The content of the resulting <filename>/dev</filename> + directory is defined in a Device Table file. + The + <ulink url='&YOCTO_DOCS_REF_URL;#var-IMAGE_DEVICE_TABLES'><filename>IMAGE_DEVICE_TABLES</filename></ulink> + variable defines the Device Table to use and should be set + in the machine or distro configuration file. + Alternatively, you can set this variable in your + <filename>local.conf</filename> configuration file. + </para> + + <para> + If you do not define the + <filename>IMAGE_DEVICE_TABLES</filename> variable, the default + <filename>device_table-minimal.txt</filename> is used: + <literallayout class='monospaced'> + IMAGE_DEVICE_TABLES = "device_table-mymachine.txt" + </literallayout> + </para> + + <para> + The population is handled by the <filename>makedevs</filename> + utility during image creation: + </para> + </section> + + <section id="devtmpfs-dev-management"> + <title>Using <filename>devtmpfs</filename> and a Device Manager</title> + + <para> + To use the dynamic method for device population, you need to + use (or be sure to set) the + <ulink url='&YOCTO_DOCS_REF_URL;#var-USE_DEVFS'><filename>USE_DEVFS</filename></ulink> + variable to "1", which is the default: + <literallayout class='monospaced'> + USE_DEVFS = "1" + </literallayout> + With this setting, the resulting <filename>/dev</filename> + directory is populated by the kernel using + <filename>devtmpfs</filename>. + Make sure the corresponding kernel configuration variable + <filename>CONFIG_DEVTMPFS</filename> is set when building + you build a Linux kernel. + </para> + + <para> + All devices created by <filename>devtmpfs</filename> will be + owned by <filename>root</filename> and have permissions + <filename>0600</filename>. + </para> + + <para> + To have more control over the device nodes, you can use a + device manager like <filename>udev</filename> or + <filename>busybox-mdev</filename>. + You choose the device manager by defining the + <filename>VIRTUAL-RUNTIME_dev_manager</filename> variable + in your machine or distro configuration file. + Alternatively, you can set this variable in your + <filename>local.conf</filename> configuration file: + <literallayout class='monospaced'> + VIRTUAL-RUNTIME_dev_manager = "udev" + + # Some alternative values + # VIRTUAL-RUNTIME_dev_manager = "busybox-mdev" + # VIRTUAL-RUNTIME_dev_manager = "systemd" + </literallayout> + </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-<replaceable>PN</replaceable> = "${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 to run tests using + QEMU or 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: + <orderedlist> + <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> + </orderedlist> + </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, the following options exist: + <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> + <listitem><para><emphasis>"BeagleBoneTarget":</emphasis> + Choose "BeagleBoneTarget" if you are deploying + images and running tests on the BeagleBone + "Black" or original "White" hardware. + For information on how to use these tests, see the + comments at the top of the BeagleBoneTarget + <filename>meta-yocto-bsp/lib/oeqa/controllers/beaglebonetarget.py</filename> + file. + </para></listitem> + <listitem><para><emphasis>"EdgeRouterTarget":</emphasis> + Choose "EdgeRouterTarget" is you are deploying + images and running tests on the Ubiquiti Networks + EdgeRouter Lite. + For information on how to use these tests, see the + comments at the top of the EdgeRouterTarget + <filename>meta-yocto-bsp/lib/oeqa/controllers/edgeroutertarget.py</filename> + file. + </para></listitem> + <listitem><para><emphasis>"GrubTarget":</emphasis> + Choose the "supports deploying images and running + tests on any generic PC that boots using GRUB. + For information on how to use these tests, see the + comments at the top of the GrubTarget + <filename>meta-yocto-bsp/lib/oeqa/controllers/grubtarget.py</filename> + file. + </para></listitem> + <listitem><para><emphasis>"<replaceable>your-target</replaceable>":</emphasis> + Create your own custom target if you want to run + tests when you are deploying images and running + tests on a custom machine within your BSP layer. + To do this, you need to add a Python unit that + defines the target class under + <filename>lib/oeqa/controllers/</filename> within + your layer. + You must also provide an empty + <filename>__init__.py</filename>. + For examples, see files in + <filename>meta-yocto-bsp/lib/oeqa/controllers/</filename>. + </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 + Initial RAM Disk (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> + </section> + + <section id='power-control'> + <title>Power Control</title> + + <para> + For most hardware targets other than SimpleRemoteTarget, + you can control power: + <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 <replaceable>arg</replaceable>" + </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> + If you have no hardware to automatically perform power + control but still wish to experiment with automated + hardware testing, you can use the dialog-power-control + script that shows a dialog prompting you to perform the + required power action. + This script requires either KDialog or Zenity to be + installed. + To use this script, set the + <ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_POWERCONTROL_CMD'><filename>TEST_POWERCONTROL_CMD</filename></ulink> + variable as follows: + <literallayout class='monospaced'> + TEST_POWERCONTROL_CMD = "${COREBASE}/scripts/contrib/dialog-power-control" + </literallayout> + </para> + </section> + + <section id='serial-console-connection'> + <title>Serial Console Connection</title> + + <para> + For test target classes requiring a serial console + to interact with the bootloader (e.g. BeagleBoneTarget, + EdgeRouterTarget, and GrubTarget), you need to + specify a command to use to connect to the serial console + of the target machine by using the + <ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_SERIALCONTROL_CMD'><filename>TEST_SERIALCONTROL_CMD</filename></ulink> + variable and optionally the + <ulink url='&YOCTO_DOCS_REF_URL;#var-TEST_SERIALCONTROL_EXTRA_ARGS'><filename>TEST_SERIALCONTROL_EXTRA_ARGS</filename></ulink> + variable. + </para> + + <para> + These cases could be a serial terminal program if the + machine is connected to a local serial port, or a + <filename>telnet</filename> or + <filename>ssh</filename> command connecting to a remote + console server. + Regardless of the case, the command simply needs to + connect to the serial console and forward that connection + to standard input and output as any normal terminal + program does. + For example, to use the picocom terminal program on + serial device <filename>/dev/ttyUSB0</filename> + at 115200bps, you would set the variable as follows: + <literallayout class='monospaced'> + TEST_SERIALCONTROL_CMD = "picocom /dev/ttyUSB0 -b 115200" + </literallayout> + For local devices where the serial port device disappears + when the device reboots, an additional "serdevtry" wrapper + script is provided. + To use this wrapper, simply prefix the terminal command + with + <filename>${COREBASE}/scripts/contrib/serdevtry</filename>: + <literallayout class='monospaced'> + TEST_SERIALCONTROL_CMD = "${COREBASE}/scripts/contrib/serdevtry picocom -b +115200 /dev/ttyUSB0" + </literallayout> + </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 <replaceable>image</replaceable> + </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><replaceable>layer</replaceable>/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-<replaceable>image</replaceable> = "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 your 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> + 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> + + <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 + <filename>${DEPLOY_DIR}/rpm</filename> 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.py</filename> with + "--deploy-dir <replaceable>path</replaceable>" as + follows: + <literallayout class='monospaced'> + ./runexported.py --deploy-dir /new/path/on/this/machine testdata.json + </literallayout> + <filename>runexported.py</filename> accepts other arguments + as well as described using <filename>--help</filename>. + </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><replaceable>layer</replaceable>/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 the following: + <itemizedlist> + <listitem><para>Filenames need to map directly to test + (module) names. + </para></listitem> + <listitem><para>Do not use module names that + collide with existing core tests. + </para></listitem> + <listitem><para>Minimally, an empty + <filename>__init__.py</filename> file must exist + in the runtime directory. + </para></listitem> + </itemizedlist> + </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 test 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 debug (<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. + <note> + By default, source files are part of the + <filename>*-dbg</filename> packages in order to enable GDB + to show source lines in its output. + You can save further space on the target by setting the + <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_DEBUG_SPLIT_STYLE'><filename>PACKAGE_DEBUG_SPLIT_STYLE</filename></ulink> + variable to "debug-without-src" so that these packages do not + include the source files. + </note> + </para> + + <para> + Because the host GDB is responsible for loading the debugging information and + for doing the necessary processing to make actual debugging happen, + you have 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/<replaceable>host-arch</replaceable>/usr/bin/<replaceable>target-platform</replaceable>/<replaceable>target-abi</replaceable>-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 ~/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. + <note> + If you cannot properly fix a <filename>make</filename> race + condition, you can work around it by clearing either the + <ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKE'><filename>PARALLEL_MAKE</filename></ulink> + or + <ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKEINST'><filename>PARALLEL_MAKEINST</filename></ulink> + variables. + </note> + </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 Quilt in Your 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="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 debug (<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-<replaceable>kernelversion</replaceable></filename>, where + <filename><replaceable>kernelversion</replaceable></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/<replaceable>image_name-datestamp</replaceable></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 \ + " + </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 + </literallayout> + In the previous example, the errors are sent to a public + database available at + <ulink url='http://errors.yoctoproject.org'></ulink>, which is + used by the entire community. + If you specify a particular server, you can send the errors + to a different database. + Use the following command for more information on available + options: + <literallayout class='monospaced'> + $ send-error-report --help + </literallayout> + </para> + + <para> + When sending the error file, you are prompted to review the + data being sent as well as to provide a name and optional + email address. + Once you satisfy these prompts, the command returns a link + from the server that corresponds to your entry in the database. + For example, here is a typical link: + <literallayout class='monospaced'> + http://errors.yoctoproject.org/Errors/Details/9522/ + </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 +--> |