| <!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. |
| <note> |
| As of Yocto Project Release 7.1, some of the core recipes |
| that package binary configuration scripts now disable the |
| scripts due to the scripts previously requiring error-prone |
| path substitution. |
| The OpenEmbedded build system uses |
| <filename>pkg-config</filename> now, which is much more |
| robust. |
| You can find a list of the <filename>*-config</filename> |
| scripts that are disabled list in the |
| "<ulink url='&YOCTO_DOCS_REF_URL;#migration-1.7-binary-configuration-scripts-disabled'>Binary Configuration Scripts Disabled</ulink>" |
| section in the Yocto Project Reference Manual. |
| </note> |
| </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. |
| <note> |
| For cases where improper paths are detected for |
| configuration files or for when libraries/headers cannot |
| be found, be sure you are using the more robust |
| <filename>pkg-config</filename>. |
| See the note in section |
| "<link linkend='new-recipe-configuring-the-recipe'>Configuring the Recipe</link>" |
| for additional information. |
| </note> |
| <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.</para> |
| <para>By default, packages apply to any machine with the |
| same architecture as the target machine. |
| When a recipe produces packages that are |
| machine-specific (e.g. the |
| <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), you should |
| mark them as such by adding the following to the |
| recipe: |
| <literallayout class='monospaced'> |
| PACKAGE_ARCH = "${MACHINE_ARCH}" |
| </literallayout></para> |
| <para>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_append = " lib32-glib-2.0" |
| </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-glib-2.0</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-glib-2.0 |
| </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/wic/plugins/source/</filename> to |
| make the plugin implementation available to the |
| <filename>wic</filename> implementation. |
| For more information, see |
| <filename>scripts/lib/wic/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/wic/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> |
| <para>If you do not use the |
| <filename>--source</filename> option, the |
| <filename>wic</filename> command creates an empty |
| partition. |
| Consequently, you must use the |
| <filename>--size</filename> option to specify the |
| size of the empty partition. |
| </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> |
| <listitem><para><emphasis><filename>--no-table</filename>:</emphasis> |
| This option is a <filename>wic</filename>-specific |
| option. |
| Using the option reserves space for the partition |
| and causes it to become populated. |
| However, the partition is not added to the |
| partition table. |
| </para></listitem> |
| <listitem><para><emphasis><filename>--extra-space</filename>:</emphasis> |
| This option is a <filename>wic</filename>-specific |
| option that adds extra space after the space |
| filled by the content of the partition. |
| The final size can go beyond the size specified |
| by the <filename>--size</filename> option. |
| The default value is 10 Mbytes. |
| </para></listitem> |
| <listitem><para><emphasis><filename>--overhead-factor</filename>:</emphasis> |
| This option is a <filename>wic</filename>-specific |
| option that multiplies the size of the partition by |
| the option's value. |
| You must supply a value greater than or equal to |
| "1". |
| The default value is "1.3". |
| </para></listitem> |
| <listitem><para><emphasis><filename>--part-type</filename>:</emphasis> |
| This option is a <filename>wic</filename>-specific |
| option that specifies the partition type globally |
| unique identifier (GUID) for GPT partitions. |
| You can find the list of partition type GUIDs |
| at |
| <ulink url='http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs'></ulink>. |
| </para></listitem> |
| <listitem><para><emphasis><filename>--use-uuid</filename>:</emphasis> |
| This option is a <filename>wic</filename>-specific |
| option that causes <filename>wic</filename> to |
| generate a random GUID for the partition. |
| The generated identifier is used in the bootloader |
| configuration to specify the root partition. |
| </para></listitem> |
| <listitem><para><emphasis><filename>--uuid</filename>:</emphasis> |
| This option is a <filename>wic</filename>-specific |
| option that specifies the partition UUID. |
| </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> |
| <listitem><para><emphasis>Be sure your host has the |
| correct packages installed:</emphasis> |
| Depending your host's distribution, you need |
| to have the following packages installed: |
| <itemizedlist> |
| <listitem><para>Ubuntu and Debian: |
| <filename>sysstat</filename> and |
| <filename>iproute2</filename> |
| </para></listitem> |
| <listitem><para>OpenSUSE: |
| <filename>sysstat</filename> and |
| <filename>iproute2</filename> |
| </para></listitem> |
| <listitem><para>Fedora: |
| <filename>sysstat</filename> and |
| <filename>iproute</filename> |
| </para></listitem> |
| <listitem><para>CentOS: |
| <filename>sysstat</filename> and |
| <filename>iproute</filename> |
| </para></listitem> |
| </itemizedlist> |
| </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 |
| --> |