<?xml version="1.0" encoding="UTF-8"?>
<chapter id="chapter_recipes" xreflabel="Recipes chapter">
  <title>Recipes</title>

  <section id="recipes_introduction" xreflabel="introduction">
    <title>Introduction</title>

    <para>A bitbake recipe is a set of instructions that describe what needs
    to be done to retrieve the source code for some application, apply any
    necessary patches, provide any additional files (such as init scripts),
    compile it, install it and generated binary packages. The end result is a
    binary package that you can install on your target device, and maybe some
    intermediate files, such as libraries and headers, which can be used when
    building other application.</para>

    <para>In many ways the process is similar to creating .deb or .rpm
    packages for your standard desktop distributions with one major difference
    - in OpenEmbedded everything is being cross-compiled. This often makes the
    task far more difficult (depending on how well suited the application is
    to cross compiling), then it is for other packaging systems and sometime
    impossible.</para>

    <para>This chapter assumes that you are familiar with working with
    bitbake, including the work flow, required directory structures, bitbake
    configuration and the use of monotone. If you are not familiar with these
    then first take a look at the chapter on bitbake usage.</para>
  </section>

  <section id="recipes_syntax" xreflabel="syntax">
    <title>Syntax of recipes</title>

    <para>The basic items that make up a bitbake recipe file are:</para>

    <variablelist>
      <varlistentry>
        <term>functions</term>

        <listitem>
          <para>Functions provide a series of actions to be performed.
          Functions are usually used to override the default implementation of
          a task function, or to compliment (append or prepend to an existing
          function) a default function. Standard functions use sh shell
          syntax, although access to OpenEmbedded variables and internal
          methods is also available.</para>

          <para>The following is an example function from the sed
          recipe:</para>

          <para><screen>do_install () {
    autotools_do_install
    install -d ${D}${base_bindir}
    mv ${D}${bindir}/sed ${D}${base_bindir}/sed.${PN}
}</screen>It is also possible to implement new functions, that are not
          replacing or complimenting the default functions, which are called
          between existing tasks. It is also possible to implement functions
          in python instead of sh. Both of these options are not seen in the
          majority of recipes.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>variable assignments and manipulations</term>

        <listitem>
          <para>Variable assignments allow a value to be assigned to a
          variable. The assignment may be static text or might include the
          contents of other variables. In addition to assignment, appending
          and prepending operations are also supported.</para>

          <para>The follow example shows the some of the ways variables can be
          used in recipes:<screen>S = "${WORKDIR}/postfix-${PV}"
PR = "r4"
CFLAGS += "-DNO_ASM"
SRC_URI_append = "file://fixup.patch;patch=1"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>keywords</term>

        <listitem>
          <para>Only a few keywords are used in bitbake recipes. They are used
          for things such as including common functions
          (<emphasis>inherit</emphasis>), loading parts of a recipe from other
          files (<emphasis>include</emphasis> and
          <emphasis>require</emphasis>) and exporting variables to the
          environment (export).</para>

          <para>The following example shows the use of some of these
          keywords:<screen>export POSTCONF = "${STAGING_BINDIR}/postconf"
inherit autoconf
require otherfile.inc</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>comments</term>

        <listitem>
          <para>Any lines that begin with a # are treated as comment lines and
          are ignored.<screen># This is a comment</screen></para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>The following is a summary of the most important (and most commonly
    used) parts of the recipe syntax:</para>

    <variablelist>
      <varlistentry>
        <term>Line continuation: \</term>

        <listitem>
          <para>To split a line over multiple lines you should place a \ at
          the end of the line that is to be continued on the next line.</para>

          <screen>VAR = "A really long \
       line"</screen>

          <para>Note that there must not be anything (no spaces or tabs) after
          the \.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Comments: #</term>

        <listitem>
          <para>Any lines beginning with a # are comments and will be
          ignored.<screen># This is a comment</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Using variables: ${...}</term>

        <listitem>
          <para>To access the contents of a variable you need to access it via
          <emphasis>${&lt;varname&gt;}</emphasis>:<screen>SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Quote all assignments</term>

        <listitem>
          <para>All variable assignments should be quoted with double quotes.
          (It may work without them at present, but it will not work in the
          future).<screen>VAR1 = "${OTHERVAR}"
VAR2 = "The version is ${PV}"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Conditional assignment</term>

        <listitem>
          <para>Conditional assignement is used to assign a value to a
          variable, but only when the variable is currently unset. This is
          commonly used to provide a default value for use when no specific
          definition is provided by the machine or distro configuration of the
          users local.conf configuration.</para>

          <para>The following example:<screen>VAR1 ?= "New value"</screen>will
          set <emphasis role="bold">VAR1</emphasis> to <emphasis>"New
          value"</emphasis> if its currently empty. However if it was already
          set it would be unchanged. In the following <emphasis
          role="bold">VAR1</emphasis> is left with the value
          <emphasis>"Original value"</emphasis>:<screen>VAR1 = "Original value"
VAR1 ?= "New value"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Appending: +=</term>

        <listitem>
          <para>You can append values to existing variables using the
          <emphasis>+=</emphasis> operator. Note that this operator will add a
          space between the existing content of the variable and the new
          content.<screen>SRC_URI += "file://fix-makefile.patch;patch=1"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Prepending: =+</term>

        <listitem>
          <para>You can prepend values to existing variables using the
          <emphasis>=+</emphasis> operator. Note that this operator will add a
          space between the new content and the existing content of the
          variable.<screen>VAR =+ "Starts"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Appending: _append</term>

        <listitem>
          <para>You can append values to existing variables using the
          <emphasis>_append</emphasis> method. Note that this operator does
          not add any additional space, and it is applied after all the
          <emphasis>+=</emphasis>, and <emphasis>=+</emphasis> operators have
          been applied.</para>

          <para>The following example show the space being explicitly added to
          the start to ensure the appended value is not merged with the
          existing value:<screen>SRC_URI_append = " file://fix-makefile.patch;patch=1"</screen>The
          <emphasis>_append</emphasis> method can also be used with overrides,
          which result in the actions only being performed for the specified
          target or machine: [TODO: Link to section on overrides]<screen>SRC_URI_append_sh4 = " file://fix-makefile.patch;patch=1"</screen>Note
          that the appended information is a variable itself, and therefore
          it's possible to used <emphasis>+=</emphasis> or
          <emphasis>=+</emphasis> to assign variables to the
          <emphasis>_append</emphasis> information:<screen>SRC_URI_append = " file://fix-makefile.patch;patch=1"
SRC_URI_append += "file://fix-install.patch;patch=1"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Prepending: _prepend</term>

        <listitem>
          <para>You can prepend values to existing variables using the
          _prepend method. Note that this operator does not add any additional
          space, and it is applied after all the <emphasis>+=</emphasis>, and
          <emphasis>=+</emphasis> operators have been applied.</para>

          <para>The following example show the space being explicitly added to
          the end to ensure the prepended value is not merged with the
          existing value:<screen>CFLAGS_prepend = "-I${S}/myincludes "</screen>The
          <emphasis>_prepend</emphasis> method can also be used with
          overrides, which result in the actions only being performed for the
          specified target or machine: [TODO: Link to section on
          overrides]<screen>CFLAGS_prepend_sh4 = " file://fix-makefile.patch;patch=1"</screen>Note
          that the appended information is a variable itself, and therefore
          it's possible to used <emphasis>+=</emphasis> or
          <emphasis>=+</emphasis> to assign variables to the
          <emphasis>_prepend</emphasis> information:<screen>CFLAGS_prepend = "-I${S}/myincludes "
CFLAGS_prepend += "-I${S}/myincludes2 "</screen>Note also the lack of a space
          when using += to append to a prepend value - remember that the +=
          operator is adding space itself.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Spaces vs tabs</term>

        <listitem>
          <para>Spaces should be used for indentation, not hard tabs. Both
          currently work, however it is a policy decision of OE that spaces
          always be used.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Style: oe-stylize.py</term>

        <listitem>
          <para>To help with using the correct style in your recipes there is
          a python script in the contrib directory called
          <emphasis>oe-stylize.py</emphasis> which can be used to reformat
          your recipes to the correct style. The output will contain a list of
          warning (to let you know what you did wrong) which should be edited
          out before using the new file.<screen>contrib/oe-stylize.py myrecipe.bb &gt; fixed-recipe.bb
vi fixed-recipe.bb
mv fixed.recipe.bb myrecipe.bb</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Using python for complex operations: ${@...}</term>

        <listitem>
          <para>For more advanced processing it is possible to use python code
          during variable assignments, for doing search and replace on a
          variable for example.</para>

          <para>Python code is indicated by a proceeding @ sign in the
          variable assignment.<screen>CXXFLAGS := "${@'${CXXFLAGS}'.replace('-frename-registers', '')}"</screen>More
          information about using python is available in the <xref
          linkend="recipes_advanced_python" /> section.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Shell syntax</term>

        <listitem>
          <para>When describing a list of actions to take shell syntax is used
          (as if you were writing a shell script). You should ensure that you
          script would work with a generic sh and not require any bash (or
          other shell) specific functionality. The same applies to various
          system utilities (sed, grep, awk etc) that you may wish to use. If
          in doubt you should check with multiple implementations - including
          those from busybox.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>For a detailed description of the syntax for the bitbake recipe
    files you should refer to the bitbake use manual.</para>
  </section>

  <section id="recipes_versioning" xreflabel="versioning">
    <title>Recipe naming: Names, versions and releases</title>

    <para>Recipes in OpenEmbedded use a standard naming convention that
    includes the package name and version number in the filename. In addition
    to the name and version there is also a release number, which is indicates
    changes to the way the package is built and/or packaged. The release
    number is contained within the recipe itself.</para>

    <para>The expected format of recipe name is:<screen>&lt;package-name&gt;_&lt;version&gt;.bb</screen></para>

    <para>where <emphasis>&lt;package-name&gt;</emphasis> is the name of the
    package (application, library, module, or whatever it is that is being
    packaged) and <emphasis>version</emphasis> is the version number.</para>

    <para>So a typical recipe name would be:<screen>strace_4.5.14.bb</screen>which
    would be for version <emphasis>4.5.14</emphasis> of the
    <emphasis>strace</emphasis> application.</para>

    <para>The release version is defined via the package release variable, PR,
    contained in the recipe. The expected format is:<screen>r&lt;n&gt;</screen>where
    <emphasis>&lt;n&gt;</emphasis> is an integer number starting from 0
    initially and then incremented each time the recipe, or something that
    effects the recipe, is modified. So a typical definition of the release
    would be:<screen>PR = "r1"</screen>to specify release number
    <emphasis>1</emphasis> (the second release, the first would have been
    <emphasis>0</emphasis>). If there is no definition of PR in the recipe
    then the default value of "r0" is used.</para>

    <para><note>
        <para>It is good practice to always define PR in your recipes, even
        for the <emphasis>"r0"</emphasis> release, so that when editing the
        recipe it is clear that the PR number needs to be updated.</para>

        <para>You should always increment PR when modifying a recipe.
        Sometimes this can be avoided if the change will have no effect on the
        actual packages generated by the recipe, such as updating the SRC_URI
        to point to a new host. If in any doubt then you should increase the
        PR regardless of what has been changed.</para>

        <para>The PR value should never be decremented. If you accidentally
        submit a large PR value for example then it should be left at the
        value and just increased for new releases, not reset back to a lower
        version.</para>
      </note></para>

    <para>When a recipe is being processed some variables are automatically
    set based on the recipe file name and can be used for other purposes from
    within the recipe itself. These include:</para>

    <variablelist>
      <varlistentry>
        <term>PN</term>

        <listitem>
          <para>The package name. Determined from the recipe filename -
          everything up until the first underscore is considered to be the
          package name. For the <command>strace_4.5.14.bb</command> recipe the
          PN variable would be set to <emphasis>"strace"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PV</term>

        <listitem>
          <para>The package version. Determined from the recipe filename -
          everything between the first underscore and the final .bb is
          considered to be the package version. For the
          <command>strace_4.5.14.bb</command> recipe the PV variable would be
          set to <emphasis>"4.5.14"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PR</term>

        <listitem>
          <para>The package release. This is explicitly set in the recipe, or
          if not set it defaults to "<emphasis>r0"</emphasis> if not
          set.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>P</term>

        <listitem>
          <para>The package name and versions separated by a hyphen.<screen>P = "${PN}-${PV}"</screen></para>

          <para>For the <command>strace_4.5.14.bb</command> recipe the P
          variable would be set to
          <emphasis>"strace-4.5.14"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PF</term>

        <listitem>
          <para>The package name, version and release separated by
          hyphens.<screen>PF = "${PN}-${PV}-${PR}"</screen></para>

          <para>For the s<command>trace_4.5.14.bb recipe</command>, with PR
          set to <emphasis>"r1"</emphasis> in the recipe, the PF variable
          would be set to <emphasis>"strace-4.5.14-r1"</emphasis>.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>While some of these variables are not commonly used in recipes (they
    are used internally though) both PN and PV are used a lot.</para>

    <para>In the following example we are instructing the packaging system to
    include an additional directory in the package. We use PN to refer to the
    name of the package rather than spelling out the package name:<screen>FILES_${PN} += "${sysconfdir}/myconf"</screen></para>

    <para>In the next example we are specifying the URL for the package
    source, by using PV in place of the actual version number it is possible
    to duplicate, or rename, the recipe for a new version without having to
    edit the URL:<screen>SRC_URI = "ftp://ftp.vim.org/pub/vim/unix/vim-${PV}.tar.bz2"</screen></para>
  </section>

  <section id="recipes_variables" xreflabel="variables">
    <title>Variables</title>

    <para>One of the most confusing part of bitbake recipes for new users is
    the large amount of variables that appear to be available to change and/or
    control the behaviour of some aspect of the recipe. Some variables, such
    as those derived from the file name are reasonably obvious, others are not
    at all obvious.</para>

    <para>There are several places where these variables are derived from
    and/or used:</para>

    <orderedlist>
      <listitem>
        <para>A large number of variables are defined in the bitbake
        configuration file conf/bitbake.conf - it's often a good idea to look
        through that file when trying to determine what a particular variable
        means.</para>
      </listitem>

      <listitem>
        <para>Machine and distribution configuration files in conf/machine and
        conf/distro will sometimes define some variables specific to the
        machine and/or distribution. You should look at the appropriate files
        for your targets to see if anything is being defined that effects the
        recipes you are building.</para>
      </listitem>

      <listitem>
        <para>Bitbake itself will define some variables. The FILE variables
        that defines the name of the bitbake recipe being processed is set by
        bitbake itself for example. Refer to the bitbake manual for more
        information on the variables that bitbake sets.</para>
      </listitem>

      <listitem>
        <para>The classes, that are used via the inherit keyword, define
        and/or use the majority of the remaining variables. A class is a like
        a library that contain parts of a bitbake recipe that are used by
        multiple recipes. To make them usable in more situations they often
        include a large number of variables to control how the class
        operates.</para>
      </listitem>
    </orderedlist>

    <para>Another important aspect is that there are three different types of
    things that binaries and libraries are used for and they often have
    different variables for each. These include:</para>

    <variablelist>
      <varlistentry>
        <term>target</term>

        <listitem>
          <para>Refers to things built for the target are expected to be run
          on the target device itself.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>native</term>

        <listitem>
          <para>Refers to things built to run natively on the build host
          itself.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>cross</term>

        <listitem>
          <para>Refers to things built to run natively on the build host
          itself, but produce output which is suitable for the target device.
          Cross versions of packages usually only exist for things like
          compilers and assemblers - i.e. things which are used to produce
          binary applications themselves.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section>

  <section id="recipes_header" xreflabel="header">
    <title>Header</title>

    <para>Practically all recipes start was the header section which describes
    various aspects of the package that is being built. This information is
    typically used directly by the package format (such as ipkg or deb) as
    it's meta data used to describe the package.</para>

    <para>Variables used in the header include:</para>

    <variablelist>
      <varlistentry>
        <term>DESCRIPTION</term>

        <listitem>
          <para>Describes what the software does. Hopefully this gives enough
          information to a use to know if it's the right application for
          them.</para>

          <para>The default description is: <emphasis>"Version ${PV}-${PR} of
          package ${PN}"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>HOMEPAGE</term>

        <listitem>
          <para>The URL of the home page of the application where new releases
          and more information can be found.</para>

          <para>The default homepage is <emphasis>"unknown"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>SECTION</term>

        <listitem>
          <para>The section is used to categorise the application into a
          specific group. Often used by GUI based installers to help users
          when searching for software.</para>

          <para>See <xref linkend="section_variable" /> for a list of the
          available sections.</para>

          <para>The default section is <emphasis>"base"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PRIORITY</term>

        <listitem>
          <para>The default priority is
          <emphasis>"optional"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>LICENSE</term>

        <listitem>
          <para>The license for the application. If it is not one of the
          standard licenses then the license itself must be included
          (where?).</para>

          <para>As well as being used in the package meta-data the license is
          also used by the src_distribute class.</para>

          <para>The default license is <emphasis>"unknown"</emphasis>.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section>

  <section id="recipes_sources" xreflabel="sources">
    <title>Sources: Downloading, patching and additional files</title>

    <para>A recipes purpose is to describe how to take a software package and
    build it for your target device. The location of the source file (or
    files) is specified via the <xref linkend="src_uri_variable" /> in the
    recipe. This can describe several types of URI's, the most common
    are:</para>

    <variablelist>
      <varlistentry>
        <term>http and https</term>

        <listitem>
          <para>Specifies files to be downloaded. A copy is stored locally so
          that future builds will not download the source again.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>cvs, svn and git</term>

        <listitem>
          <para>Specifies that the files are to be retrieved using the
          specified version control system.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>files</term>

        <listitem>
          <para>Plain files which are included locally. These can be used for
          adding documentation, init scripts or any other files that need to
          be added to build the package under openembedded.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>patches</term>

        <listitem>
          <para>Patches are plain files which are treated as patched and
          automatically applied.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>If a http, https or file URI refers to a compressed file, an archive
    file or a compressed archive file, such as .tar.gz or .zip, then the files
    will be uncompressed and extracted from the archive automatically.</para>

    <para>Archive files will be extracted from with the working directory,
    <emphasis role="bold">${WORKDIR}</emphasis> and plain files will be copied
    into the same directory. Patches will be applied from within the unpacked
    source directory, <emphasis role="bold">${S}</emphasis>. (Details on these
    directories is provided in the next section.)</para>

    <para>The following example from the havp recipe shows a typical <emphasis
    role="bold">SRC_URI</emphasis> definition:<screen>SRC_URI = "http://www.server-side.de/download/havp-${PV}.tar.gz \
           file://sysconfdir-is-etc.patch;patch=1 \
           file://havp.init \
           file://doc.configure.txt \
           file://volatiles.05_havp"</screen></para>

    <para>This describes several files</para>

    <variablelist>
      <varlistentry>
        <term>http://www.server-side.de/download/havp-${PV}.tar.gz</term>

        <listitem>
          <para>This is the URI of the havp source code. Note the use of the
          <emphasis role="bold">${PV}</emphasis> variable to specify the
          version. This is done to enable the recipe to be renamed for a new
          version without the need the edit the recipe itself. Because this is
          a .tar.gz compressed archive the file will be decompressed and
          extracted in the working dir <emphasis
          role="bold">${WORKDIR}</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>file://sysconfdir-is-etc.patch;patch=1</term>

        <listitem>
          <para>This is a local file that is used to patch the extracted
          source code. The patch=1 is what specifies that this is a patch. The
          patch will be applied from the unpacked source directory, <emphasis
          role="bold">${S}</emphasis>. In this case <emphasis
          role="bold">${S}</emphasis> will be <emphasis
          role="bold">${WORKDIR}/havp-0.82</emphasis>, and luckily the
          <emphasis role="bold">havp-0.82.tar.gz</emphasis> file extracts
          itself into that directory (so no need to explicitly change
          <emphasis role="bold">${S}</emphasis>).</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>file://havp.init file://doc.configure.txt
        file://volatiles.05_havp"</term>

        <listitem>
          <para>These are plain files which are just copied into the working
          directory <emphasis role="bold">${WORKDIR}</emphasis>. These are
          then used during the install task in the recipe to provide init
          scripts, documentation and volatiles configuration information for
          the package.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Full details on the <emphasis role="bold">SRC_URI</emphasis>
    variable and all the support URI's is available in the <xref
    linkend="src_uri_variable" /> section of the reference chapter.</para>
  </section>

  <section id="recipes_directories" xreflabel="directories">
    <title>Directories: What goes where</title>

    <para>A large part of the work or a recipe is involved with specifying
    where files and found and where they have to go. It's important for
    example that programs do not try and use files from <emphasis
    role="bold">/usr/include</emphasis> or <emphasis
    role="bold">/usr/lib</emphasis> since they are for the host system, not
    the target. Similarly you don't want programs installed into <emphasis
    role="bold">/usr/bin</emphasis> since that may overwrite your host system
    programs with versions that don't work on the host!</para>

    <para>The following are some of the directories commonly referred to in
    recipes and will be described in more detail in the rest of this
    section:</para>

    <variablelist>
      <varlistentry>
        <term>Working directory: WORKDIR</term>

        <listitem>
          <para>This working directory for a recipe is where archive files
          will be extracted, plain files will be placed, subdirectories for
          logs, installed files etc will be created.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Unpacked source code directory: S</term>

        <listitem>
          <para>This is where patches are applied and where the program is
          expected to be compiled in.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Destination directory: D</term>

        <listitem>
          <para>The destination directory. This is where your package should
          be installed into. The packaging system will then take the files
          from directories under here and package them up for installation on
          the target.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Installation directories: bindir, docdir, ...</term>

        <listitem>
          <para>There are a set of variables available to describe all of the
          paths on the target that you may want to use. Recipes should use
          these variables rather than hard coding any specific paths.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Staging directories: STAGING_LIBDIR, STAGING_INCDIR, ...</term>

        <listitem>
          <para>Staging directories are a special area for headers, libraries
          and other files that are generated by one recipe that may be needed
          by another recipe. A library package for example needs to make the
          library and headers available to other recipes so that they can link
          against them.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>File path directories: FILE, FILE_DIRNAME, FILESDIR,
        FILESPATH</term>

        <listitem>
          <para>These directories are used to control where files are found.
          Understanding these can help you separate patches for different
          versions or releases of your recipes and/or use the same patch over
          multiple versions etc.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <section>
      <title>WORKDIR: The working directory</title>

      <para>The working directory is where the source code is extracted, to
      which plain files (not patches) are copied and where the logs and
      installation files are created. A typical reason for needing to
      reference the work directory is for the handling of non patch
      files.</para>

      <para>If we take a look at the recipe for quagga we can see an example
      non patch files for configuration and init scripts:<screen>SRC_URI = "http://www.quagga.net/download/quagga-${PV}.tar.gz \
           file://fix-for-lib-inpath.patch;patch=1 \
           file://quagga.init \
           file://quagga.default \
           file://watchquagga.init \
           file://watchquagga.default"</screen>The recipe has two init files
      and two configuration files, which are not patches, but are actually
      files that it wants to include in the generated packages. Bitbake will
      copy these files into the work directory. So to access them during the
      install task we refer to them via the <emphasis
      role="bold">WORKDIR</emphasis> variable:<screen>do_install () {
    # Install init script and default settings
    install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga
    install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga
    install -m 0644 ${WORKDIR}/watchquagga.default ${D}${sysconfdir}/default/watchquagga
    install -m 0755 ${WORKDIR}/quagga.init ${D}${sysconfdir}/init.d/quagga
    install -m 0755 ${WORKDIR}/watchquagga.init ${D}${sysconfdir}/init.d/watchquagga
    ...</screen></para>
    </section>

    <section>
      <title>S: The unpacked source code directory</title>

      <para>Bitbake expects to find the extracted source for a package in a
      directory called <emphasis
      role="bold">&lt;packagename&gt;-&lt;version&gt;</emphasis> in the
      <emphasis role="bold">WORKDIR</emphasis> directory. This is the
      directory in which it will change into before patching, compiling and
      installating the package.</para>

      <para>For example, we have a package called <emphasis
      role="bold">widgets_1.2.bb</emphasis> which we are extracting from the
      <emphasis role="bold">widgets-1.2.tar.gz</emphasis> file. Bitbake
      expects the source to end up in a directory called <emphasis
      role="bold">widgets-1.2</emphasis> within the work directory. If the
      source does not end up in this directory then bitbake needs to be told
      this by explicitly setting <emphasis role="bold">S</emphasis>.</para>

      <para>If <emphasis role="bold">widgets-1.2.tar.gz</emphasis> actually
      extracts into a directory called <emphasis
      role="bold">widgets</emphasis>, without the version number, instead of
      <emphasis role="bold">widgets-1.2</emphasis> then the <emphasis
      role="bold">S</emphasis> variable will be wrong and patching and/or
      compiling will fail. Therefore we need to override the default value of
      <emphasis role="bold">S</emphasis> to specify the directory the source
      was actually extracted into:<screen>SRC_URI = "http://www.example.com/software/widgets-${PN}.tar.gz"
S = "${WORKDIR}/widgets"</screen></para>
    </section>

    <section>
      <title>D: The destination directory</title>

      <para>The destination directory is where the completed application and
      all of it's files are installed into in preparation for packaging.
      Typically an installation would places files in directories such as
      <emphasis role="bold">/etc</emphasis> and <emphasis
      role="bold">/usr/bin</emphasis> by default. Since those directories are
      used by the host system we do not want the packages to install into
      those locations. Instead they need to install into the directories below
      the destination directory.</para>

      <para>So instead of installing into <emphasis
      role="bold">/usr/bin</emphasis> the package needs to install into
      <emphasis role="bold">${D}/usr/bin</emphasis>.</para>

      <para>The following example from arpwatch shows the make install command
      being passed a <emphasis role="bold">${D}</emphasis> as the <emphasis
      role="bold">DESTDIR</emphasis> variable to control where the makefile
      installs everything:<screen>do_install() {
        ...
        oe_runmake install DESTDIR=${D}</screen></para>

      <para>The following example from quagga shows the use of the destination
      directory to install the configuration files and init scripts for the
      package:<screen>do_install () {
        # Install init script and default settings
        install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga
        install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga
        install -m 0755 ${WORKDIR}/quagga.init ${D}${sysconfdir}/init.d/quagga</screen><note>
          <para>You should not use directories such as <emphasis
          role="bold">/etc</emphasis> and <emphasis
          role="bold">/usr/bin</emphasis> directly in your recipes. You should
          use the variables that define these locations. The full list of
          these variables can be found in the <xref
          linkend="directories_installation" /> section of the reference
          chapter.</para>
        </note></para>
    </section>

    <section>
      <title>Staging directories</title>

      <para>Staging is used to make libraries, headers and binaries available
      for the build of one recipe for use by another recipe. Building a
      library for example requires that packages be created containing the
      libraries and headers for development on the target as well as making
      them available on the host for building other packages that need the
      libraries and headers.</para>

      <para>Making the libraries, headers and binaries available for use by
      other recipes on the host is called staging and is performed by the
      <emphasis>stage</emphasis> task in the recipe. Any recipes that contain
      items that are required to build other packages should have a
      <emphasis>stage</emphasis> task to make sure the items are all correctly
      placed into the staging area. The following example from clamav show the
      clamav library and header being placed into the staging area:<screen>do_stage () {
        oe_libinstall -a -so libclamav ${STAGING_LIBDIR}
        install -m 0644 libclamav/clamav.h ${STAGING_INCDIR}
}</screen></para>

      <para>The following from the p3scan recipe show the path to the clamav
      library and header being passed to the configure script. Without this
      the configure script would either fail to find the library, or worse
      still search the host systems directories for the library. Passing in
      the location results in it searching the correct location and finding
      the clamav library and headers:<screen>EXTRA_OECONF = "--with-clamav=${STAGING_LIBDIR}/.. \
                --with-openssl=${STAGING_LIBDIR}/.. \
                --disable-ripmime"</screen>While the staging directories are
      automatically added by OpenEmbedded to the compiler and linking commands
      it is sometimes necessary, as in the p3scan example above, to explicitly
      specify the location of the staging directories. Typically this is
      needed for autoconf scripts that search in multiple places for the
      libraries and headers.</para>

      <note>
        <para>Many of the helper classes, such as pkgconfig and autotools add
        appropriate commands to the stage task for you. Check with the
        individual class descriptions in the reference section to determine
        what each class is staging automatically for you.</para>
      </note>

      <para>A full list of staging directories can be found in the <xref
      linkend="directories_staging" /> section in the reference
      chapter.</para>
    </section>

    <section id="recipes_filespath_dir" xreflabel="FILESPATH/FILESDIR">
      <title>FILESPATH/FILESDIR: Finding local files</title>

      <para>The file related variables are used by bitbake to determine where
      to look for patches and local files.</para>

      <para>Typically you will not need to modify these, but it is useful to
      be aware of the default values. In particular when searching for patches
      and/or files (file:// URI's), the default search path is:</para>

      <variablelist>
        <varlistentry>
          <term>${FILE_DIRNAME}/${PF}</term>

          <listitem>
            <para>This is the package name, version and release, such as
            "<emphasis role="bold">strace-4.5.14-r1</emphasis>". This is very
            rarely used since the patches would only be found for the one
            exact release of the recipe.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/${P}</term>

          <listitem>
            <para>This is the package name and version, such as "<emphasis
            role="bold">strace-4.5.14</emphasis>". This is by far the most
            common place to place version specified patches.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/${PN}</term>

          <listitem>
            <para>This is the package name only, such as "<emphasis
            role="bold">strace</emphasis>". This is not commonly used.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/files</term>

          <listitem>
            <para>This is just the directory called "<emphasis
            role="bold">files</emphasis>". This is commonly used for patches
            and files that apply to all version of the package.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/</term>

          <listitem>
            <para>This is just the base directory of the recipe. This is very
            rarely used since it would just clutter the main directory.</para>
          </listitem>
        </varlistentry>
      </variablelist>

      <para>Each of the paths is relative to <emphasis
      role="bold">${FILE_DIRNAME}</emphasis> which is the directory in which
      the recipe that is being processed is located.</para>

      <para>The full set of variables that control the file locations and
      patch are:</para>

      <variablelist>
        <varlistentry>
          <term>FILE</term>

          <listitem>
            <para>The path to the .bb file which is currently being
            processed.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>FILE_DIRNAME</term>

          <listitem>
            <para>The path to the directory which contains the FILE which is
            currently being processed.<screen>FILE_DIRNAME = "${@os.path.dirname(bb.data.getVar('FILE', d))}"</screen></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>FILESPATH</term>

          <listitem>
            <para>The default set of directories which are available to use
            for the file:// URI's. Each directory is searched, in the
            specified order, in an attempt to find the file specified by each
            file:// URI: <screen>FILESPATH = "${FILE_DIRNAME}/${PF}:${FILE_DIRNAME}/${P}:\
${FILE_DIRNAME}/${PN}:${FILE_DIRNAME}/files:${FILE_DIRNAME}"</screen></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>FILESDIR</term>

          <listitem>
            <para>The default directory to search for file:// URI's. Only used
            if the file is not found in FILESPATH. This can be used to easily
            add one additional directory to the search path without having to
            modify the default FILESPATH setting. By default this is just the
            first directory from FILESPATH. <screen>FILESDIR = "${@bb.which(bb.data.getVar('FILESPATH', d, 1), '.')}" </screen></para>
          </listitem>
        </varlistentry>
      </variablelist>

      <para>Sometimes recipes will modify the <emphasis
      role="bold">FILESPATH</emphasis> or <emphasis
      role="bold">FILESDIR</emphasis> variables to change the default search
      path for patches and files. The most common situation in which this is
      done is when one recipe includes another one in which the default values
      will be based on the name of the package doing the including, not the
      included package. Typically the included package will expect the files
      to be located in a directories based on it's own name.</para>

      <para>As an example the m4-native recipe includes the m4 recipe. This is
      fine, except that the m4 recipes expects its files and patches to be
      located in a directory called <emphasis role="bold">m4</emphasis>
      directory while the native file name results in them being searched for
      in <emphasis role="bold">m4-native</emphasis>. So the m4-native recipe
      sets the <emphasis role="bold">FILESDIR</emphasis> variable to the value
      that of m4 to add the actual m4 directory (where m4 itself has its files
      stored) to the list of directories search for:<screen>        include m4_${PV}.bb
        inherit native
        FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/m4"</screen></para>
    </section>
  </section>

  <section id="recipes_examples" xreflabel="examples">
    <title>Basic examples</title>

    <para>By now you should know enough about the bitbake recipes to be able
    to create a basic recipe. We'll cover a simple single file recipe and then
    a more advanced example that uses the autotools helper class (to be
    described later) to build an autoconf based package.</para>

    <section id="recipes_helloworld_example" xreflabel="hello world example">
      <title>Hello world</title>

      <para>Now it's time for our first recipe. This is going to be one of the
      simplest possible recipes: all code is included and there's only one
      file to compile and one readme file. While this isn't all that common
      it's a useful example because it doesn't depend on any of the helper
      classes which can sometime hide a lot of what is going on.</para>

      <para>First we'll create the myhelloworld.c file and a readme file.
      We'll place this in the files subdirectory, which is one of the places
      that is searched for file:// URI's:<screen>mkdir recipes/myhelloworld
mkdir recipes/myhelloworld/files
cat &gt; recipes/myhelloworld/files/myhelloworld.c
#include &lt;stdio.h&gt;

int main(int argc, char** argv)
{
        printf("Hello world!\n");
        return 0;
}
^D
cat &gt; recipes/myhelloworld/files/README.txt
Readme file for myhelloworld.
^D</screen></para>

      <para>Now we have a directory for our recipe, recipes/myhelloworld, and
      we've created a files subdirectory in there to store our local files.
      We've created two local files, the C source code for our helloworld
      program and a readme file. Now we need to create the bitbake
      recipe.</para>

      <para>First we need the header section, which will contain a description
      of the package and the release number. We'll leave the other header
      variables out for now:<screen>DESCRIPTION = "My hello world program"
PR = "r0"</screen></para>

      <para>Next we need to tell it which files we want to be included in the
      recipe, which we do via file:// URI's and the SRC_URI variable:<screen>SRC_URI = "file://myhelloworld.c \
           file://README.txt"</screen></para>

      <para>Note the use of the \ to continue a file and the file of file://
      local URI's, rather than other types such as http://.</para>

      <para>Now we need provide a compile task which tells bitbake how to
      compile this program. We do this by defining a do_compile function in
      the recipe and providing the appropriate commands:</para>

      <para><screen>do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/myhelloworld.c -o myhelloworld
}</screen></para>

      <para>Note the:</para>

      <itemizedlist>
        <listitem>
          <para>use of the pre-defined compiler variables, <emphasis
          role="bold">${CC}</emphasis>, <emphasis
          role="bold">${CFLAGS}</emphasis> and <emphasis
          role="bold">${LDFLAGS}</emphasis>. These are setup automatically to
          contain the settings required to cross-compile the program for the
          target.</para>
        </listitem>

        <listitem>
          <para>use of <emphasis role="bold">${WORKDIR}</emphasis> to find the
          source file. As mentioned previously all files are copied into the
          working directory and can be referenced via the <emphasis
          role="bold">${WORKDIR}</emphasis> variable.</para>
        </listitem>
      </itemizedlist>

      <para>And finally we want to install the program and readme file into
      the destination directory so that it'll be packaged up correctly. This
      is done via the install task, so we need to define a do_install function
      in the recipe to describe how to install the package:<screen>do_install() {
        install -m 0755 -d ${D}${bindir} ${D}${docdir}/myhelloworld
        install -m 0644 ${S}/myhelloworld ${D}${bindir}
        install -m 0644 ${WORKDIR}/README.txt ${D}${docdir}/myhelloworld
}</screen></para>

      <para>Note the:</para>

      <itemizedlist>
        <listitem>
          <para>use the <emphasis role="bold">install</emphasis> command to
          create directories and install the files, not cp.</para>
        </listitem>

        <listitem>
          <para>way directories are created before we attempt to install any
          files into them. The install command takes care of any
          subdirectories that are missing, so we only need to create the full
          path to the directory - no need to create the subdirectories.</para>
        </listitem>

        <listitem>
          <para>way we install everything into the destination directory via
          the use of the <emphasis role="bold">${D}
          </emphasis>variable.</para>
        </listitem>

        <listitem>
          <para>way we use variables to refer to the target directories, such
          as <emphasis role="bold">${bindir}</emphasis> and <emphasis
          role="bold">${docdir}</emphasis>.</para>
        </listitem>

        <listitem>
          <para>use of <emphasis role="bold">${WORKDIR}</emphasis> to get
          access to the <emphasis role="bold">README.txt</emphasis> file,
          which was provided via file:// URI.</para>
        </listitem>
      </itemizedlist>

      <para>We'll consider this release 0 and version 0.1 of a program called
      helloworld. So we'll name the recipe myhelloworld_0.1.bb:<screen>cat &gt; recipes/myhelloworld/myhelloworld_0.1.bb
DESCRIPTION = "Hello world program"
PR = "r0"

SRC_URI = "file://myhelloworld.c \
           file://README.txt"

do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/myhelloworld.c -o myhelloworld
}

do_install() {
        install -m 0755 -d ${D}${bindir} ${D}${docdir}/myhelloworld
        install -m 0644 ${S}/myhelloworld ${D}${bindir}
        install -m 0644 ${WORKDIR}/README.txt ${D}${docdir}/myhelloworld
}
^D</screen>Now we are ready to build our package, hopefully it'll all work
      since it's such a simple example:<screen>~/oe%&gt; bitbake -b recipes/myhelloworld/myhelloworld_0.1.bb
NOTE: package myhelloworld-0.1: started
NOTE: package myhelloworld-0.1-r0: task do_fetch: started
NOTE: package myhelloworld-0.1-r0: task do_fetch: completed
NOTE: package myhelloworld-0.1-r0: task do_unpack: started
NOTE: Unpacking /home/lenehan/devel/oe/local-recipes/myhelloworld/files/helloworld.c to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/myhelloworld-0.1-r0/
NOTE: Unpacking /home/lenehan/devel/oe/local-recipes/myhelloworld/files/README.txt to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/myhelloworld-0.1-r0/
NOTE: package myhelloworld-0.1-r0: task do_unpack: completed
NOTE: package myhelloworld-0.1-r0: task do_patch: started
NOTE: package myhelloworld-0.1-r0: task do_patch: completed
NOTE: package myhelloworld-0.1-r0: task do_configure: started
NOTE: package myhelloworld-0.1-r0: task do_configure: completed
NOTE: package myhelloworld-0.1-r0: task do_compile: started
NOTE: package myhelloworld-0.1-r0: task do_compile: completed
NOTE: package myhelloworld-0.1-r0: task do_install: started
NOTE: package myhelloworld-0.1-r0: task do_install: completed
NOTE: package myhelloworld-0.1-r0: task do_package: started
NOTE: package myhelloworld-0.1-r0: task do_package: completed
NOTE: package myhelloworld-0.1-r0: task do_package_write: started
NOTE: Not creating empty archive for myhelloworld-dbg-0.1-r0
Packaged contents of myhelloworld into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/myhelloworld_0.1-r0_sh4.ipk
Packaged contents of myhelloworld-doc into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/myhelloworld-doc_0.1-r0_sh4.ipk
NOTE: Not creating empty archive for myhelloworld-dev-0.1-r0
NOTE: Not creating empty archive for myhelloworld-locale-0.1-r0
NOTE: package myhelloworld-0.1-r0: task do_package_write: completed
NOTE: package myhelloworld-0.1-r0: task do_populate_staging: started
NOTE: package myhelloworld-0.1-r0: task do_populate_staging: completed
NOTE: package myhelloworld-0.1-r0: task do_build: started
NOTE: package myhelloworld-0.1-r0: task do_build: completed
NOTE: package myhelloworld-0.1: completed
Build statistics:
  Attempted builds: 1
~/oe%&gt;</screen></para>

      <para>The package was successfully built, the output consists of two
      .ipkg files, which are ready to be installed on the target. One contains
      the binary and the other contains the readme file:<screen>~/oe%&gt; ls -l tmp/deploy/ipk/*/myhelloworld*
-rw-r--r--  1 lenehan lenehan 3040 Jan 12 14:46 tmp/deploy/ipk/sh4/myhelloworld_0.1-r0_sh4.ipk
-rw-r--r--  1 lenehan lenehan  768 Jan 12 14:46 tmp/deploy/ipk/sh4/myhelloworld-doc_0.1-r0_sh4.ipk
~/oe%&gt;</screen></para>

      <para>It's worthwhile looking at the working directory to see where
      various files ended up:<screen>~/oe%&gt; find tmp/work/myhelloworld-0.1-r0
tmp/work/myhelloworld-0.1-r0
tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1
tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1/patches
tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1/myhelloworld
tmp/work/myhelloworld-0.1-r0/temp
tmp/work/myhelloworld-0.1-r0/temp/run.do_configure.21840
tmp/work/myhelloworld-0.1-r0/temp/log.do_stage.21840
tmp/work/myhelloworld-0.1-r0/temp/log.do_install.21840
tmp/work/myhelloworld-0.1-r0/temp/log.do_compile.21840
tmp/work/myhelloworld-0.1-r0/temp/run.do_stage.21840
tmp/work/myhelloworld-0.1-r0/temp/log.do_configure.21840
tmp/work/myhelloworld-0.1-r0/temp/run.do_install.21840
tmp/work/myhelloworld-0.1-r0/temp/run.do_compile.21840
tmp/work/myhelloworld-0.1-r0/install
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-locale
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-dbg
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-dev
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share/doc
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share/doc/myhelloworld
tmp/work/myhelloworld-0.1-r0/install/myhelloworld-doc/usr/share/doc/myhelloworld/README.txt
tmp/work/myhelloworld-0.1-r0/install/myhelloworld
tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr
tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin
tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin/myhelloworld
tmp/work/myhelloworld-0.1-r0/image
tmp/work/myhelloworld-0.1-r0/image/usr
tmp/work/myhelloworld-0.1-r0/image/usr/bin
tmp/work/myhelloworld-0.1-r0/image/usr/share
tmp/work/myhelloworld-0.1-r0/image/usr/share/doc
tmp/work/myhelloworld-0.1-r0/image/usr/share/doc/myhelloworld
tmp/work/myhelloworld-0.1-r0/myhelloworld.c
tmp/work/myhelloworld-0.1-r0/README.txt
~/oe%&gt;</screen>Things to note here are:</para>

      <itemizedlist>
        <listitem>
          <para>The two source files are in <emphasis
          role="bold">tmp/work/myhelloworld-0.1-r0</emphasis>, which is the
          working directory as specified via the <emphasis
          role="bold">${WORKDIR}</emphasis> variable;</para>
        </listitem>

        <listitem>
          <para>There's logs of the various tasks in <emphasis
          role="bold">tmp/work/myhelloworld-0.1-r0/temp</emphasis> which you
          can look at for more details on what was done in each task;</para>
        </listitem>

        <listitem>
          <para>There's an image directory at <emphasis
          role="bold">tmp/work/myhelloworld-0.1-r0/image</emphasis> which
          contains just the directories that were to be packaged up. This is
          actually the destination directory, as specified via the <emphasis
          role="bold">${D}</emphasis> variable. The two files that we
          installed were originally in here, but during packaging they were
          moved into the install area into a subdirectory specific to the
          package that was being created (remember we have a main package and
          a -doc package being created.</para>
        </listitem>

        <listitem>
          <para>The program was actually compiled in the <emphasis
          role="bold">tmp/work/myhelloworld-0.1-r0/myhelloworld-0.1</emphasis>
          directory, this is the source directory as specified via the
          <emphasis role="bold">${S}</emphasis> variable.</para>
        </listitem>

        <listitem>
          <para>There's an install directory at <emphasis
          role="bold">tmp/work/myhelloworld-0.1-r0/install</emphasis> which
          contains the packages that were being generated and the files that
          go in the package. So we can see that the myhelloworld-doc package
          contains the single file <emphasis
          role="bold">/usr/share/doc/myhelloworld/README.txt</emphasis>, the
          myhelloworld package contains the single file <emphasis
          role="bold">/usr/bin/myhelloworld</emphasis> and the -dev, -dbg and
          -local packages are all empty.</para>
        </listitem>
      </itemizedlist>

      <para>At this stage it's good to verify that we really did produce a
      binary for the target and not for our host system. We can check that
      with the file command:<screen>~/oe%&gt; file tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin/myhelloworld
tmp/work/myhelloworld-0.1-r0/install/myhelloworld/usr/bin/myhelloworld: ELF 32-bit LSB executable, Hitachi SH, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, not stripped
~/oe%&gt; file /bin/ls
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, stripped
~/oe%&gt;</screen>This shows us that the helloworld program is for an SH
      processor (obviously this will change depending on what your target
      system is), while checking the <emphasis role="bold">/bin/ls</emphasis>
      program on host shows us that the host system is an AMD X86-64 system.
      That's exactly what we wanted.</para>
    </section>

    <section id="recipes_autoconf_example" xreflabel="autoconf example">
      <title>An autotools package</title>

      <para>Now for an example of a package that uses autotools. These are
      programs that you need to run a configure script for, passing various
      parameters, and then make. To make these work when cross-compiling you
      need to provides a lot of variables to the configure script. But all the
      hard work as already been done for you. There's an <xref
      linkend="autotools_class" /> which takes care of most of the complexity
      of building an autotools based packages.</para>

      <para>Let's take a look at the tuxnes recipe which is an example of a
      very simple autotools based recipe:<screen>%~oe&gt; cat recipes/tuxnes/tuxnes_0.75.bb
DESCRIPTION = "Tuxnes Nintendo (8bit) Emulator"
HOMEPAGE = "http://prdownloads.sourceforge.net/tuxnes/tuxnes-0.75.tar.gz"
LICENSE = "GPLv2"
SECTION = "x/games"
PRIORITY = "optional"
PR = "r1"

SRC_URI = "http://heanet.dl.sourceforge.net/sourceforge/tuxnes/tuxnes-0.75.tar.gz"

inherit autotools</screen></para>

      <para>This is a really simple recipe. There's the standard header that
      describes the package. Then the SRC_URI, which in this case is a http
      URL that causes the source code to be downloaded from the specified URI.
      And finally there's an "<emphasis role="bold">inherit
      autotools</emphasis>" command which loads the autotools class. The
      autotools class will take care of generating the require configure,
      compile and install tasks. So in this case there's nothing else to do -
      that's all there is to it.</para>

      <para>It would be nice if it was always this simple. Unfortunately
      there's usually a lot more involved for various reasons including the
      need to:</para>

      <itemizedlist>
        <listitem>
          <para>Pass parameters to configure to enable and disable
          features;</para>
        </listitem>

        <listitem>
          <para>Pass parameters to configure to specify where to find
          libraries and headers;</para>
        </listitem>

        <listitem>
          <para>Make modifications to prevent searching for headers and
          libraries in the normal locations (since they below to the host
          system, not the target);</para>
        </listitem>

        <listitem>
          <para>Make modifications to prevent the configure script from tying
          to compile and run programs - any programs it compiles will be for
          the target and not the host and so cannot be run.</para>
        </listitem>

        <listitem>
          <para>Manually implement staging scripts;</para>
        </listitem>

        <listitem>
          <para>Deal with lots of other more complex issues;</para>
        </listitem>
      </itemizedlist>

      <para>Some of these items are covered in more detail in the advanced
      autoconf section.</para>
    </section>
  </section>

  <section id="recipes_depenencies" xreflabel="dependencies">
    <title>Dependencies: What's needed to build and/or run the
    package?</title>

    <para>Dependencies should be familiar to anyone who has used an .rpm and
    .deb based desktop distribution. A dependency is something that a package
    requires either to run the package (a run-time dependency) or to build the
    package (a build-time or compile-time, dependency).</para>

    <para>There are two variables provided to allow the specifications of
    dependencies:</para>

    <variablelist>
      <varlistentry>
        <term>DEPENDS</term>

        <listitem>
          <para>Specifies build-time dependencies, via a list of bitbake
          recipes to build prior to build the recipe. These are programs
          (flex-native) or libraries (libpcre) that are required in order to
          build the package.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RDEPENDS</term>

        <listitem>
          <para>Specifies run-time dependencies, via a list of packages to
          install prior to installing the current package. These are programs
          or libraries that are required in order to run the program. Note
          that libraries which are dynamically linked to an application will
          be automatically detected and added to <emphasis
          role="bold">RDEPENDS</emphasis> and therefore do not need to be
          explicitly declared. If a library was dynamically loaded then it
          would need to be explicitly listed.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>If we take openssh for an example, it requires zlib and openssl in
    order to both built and run. In the recipe we have:<screen>DEPENDS = "zlib openssl"</screen>This
    tells bitbake that it will need to build and stage zlib and openssl prior
    to trying to build openssh, since openssh requires both of them. Note that
    there is no <emphasis role="bold">RDEPENDS</emphasis> even though openssh
    requires both of them to run. The run time dependencies on libz1 (the name
    of the package containing the zlib library) and libssl0 (the name of the
    package containing the ssl library) are automatically determined and added
    via the auto shared libs dependency code.</para>
  </section>

  <section id="recipes_methods" xreflabel="methods">
    <title>Methods: Inbuilt methods to make your life easier</title>

    <para>There are several helper functions defined by the base class, which
    is included by default for all recipes. Many of these are used a lot in
    both recipes and other classes.</para>

    <para>The most commonly seen, and most useful functions, include:</para>

    <variablelist>
      <varlistentry>
        <term>oe_runmake</term>

        <listitem>
          <para>This function is used to run make. However unlike calling make
          yourself this will pass the EXTRA_OEMAKE settings to make, will
          display a note about the make command and will check for any errors
          generated via the call to make.</para>

          <para>You should never have any reason to call make directly and
          should also use oe_runmake when you need to run make.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oe_runconf (autotools only)</term>

        <listitem>
          <para>This function is used to run the configure script of a package
          that is using the autotools class. This takes care of passing all of
          the correct parameters for cross-compiling and for installing into
          the appropriate target directory.</para>

          <para>It also passes the value of the <emphasis
          role="bold">EXTRA_OECONF</emphasis> variable to the configure
          script. For many situations setting <emphasis
          role="bold">EXTRA_OECONF</emphasis> is sufficient and you'll have no
          need to define your own configure task in which you call oe_runconf
          manually.</para>

          <para>If you need to write your own <emphasis>configure</emphasis>
          task for an autotools package you can use oe_runconf to manually
          call the configure process when it is required. The following
          example from net-snmp shows oe_runconf being called manually so that
          the parameter for specifying the endianess can be computed and
          passed in to the configure script:<screen>do_configure() {
    # Additional flag based on target endiness (see siteinfo.bbclass)
    ENDIANESS="${@base_conditional('SITEINFO_ENDIANESS', 'le', '--with-endianness=little', '--with-endianness=big', d)}"
    oenote Determined endianess as: $ENDIANESS
    oe_runconf $ENDIANESS
}</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oe_libinstall</term>

        <listitem>
          <para>This function is used to install <emphasis
          role="bold">.so</emphasis>, <emphasis role="bold">.a</emphasis> and
          associated libtool <emphasis role="bold">.la</emphasis> libraries.
          It will determine the appropriate libraries to install and take care
          of any modifications that may be require for <emphasis
          role="bold">.la</emphasis> files.</para>

          <para>This function supports the following options:</para>

          <variablelist>
            <varlistentry>
              <term>-C &lt;dir&gt;</term>

              <listitem>
                <para>Change into the specified directory before attempting to
                install a library. Used when the libraries are in
                subdirectories of the main package.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>-s</term>

              <listitem>
                <para>Require the presence of a <emphasis
                role="bold">.so</emphasis> library as one of the libraries
                that is installed.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>-a</term>

              <listitem>
                <para>Require the presence of a <emphasis
                role="bold">.a</emphasis> library as one of the libraries that
                is installed.</para>
              </listitem>
            </varlistentry>
          </variablelist>

          <para>The following example from gdbm shows the installation of
          <emphasis role="bold">.so</emphasis>, <emphasis
          role="bold">.a</emphasis> (and associated <emphasis
          role="bold">.la</emphasis>) libraries into the staging library
          area:<screen>do_stage () {
    oe_libinstall -so -a libgdbm ${STAGING_LIBDIR}
    install -m 0644 ${S}/gdbm.h ${STAGING_INCDIR}/
}</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oenote</term>

        <listitem>
          <para>Used to display an informational messages to the user.</para>

          <para>The following example from net-snmp uses oenote to tell the
          user which endianess it determined was appropriate for the target
          device:<screen>do_configure() {
    # Additional flag based on target endiness (see siteinfo.bbclass)
    ENDIANESS="${@base_conditional('SITEINFO_ENDIANESS', 'le', '--with-endianness=little', '--with-endianness=big', d)}"
    oenote Determined endianess as: $ENDIANESS
    oe_runconf $ENDIANESS
}</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oewarn</term>

        <listitem>
          <para>Used to display a warning message to the user, warning of
          something that may be problematic or unexpected.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oedebug</term>

        <listitem>
          <para>Used to display debugging related information. These messages
          will only be visible when bitbake is run with the <emphasis
          role="bold">-D</emphasis> flag to enable debug output.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oefatal</term>

        <listitem>
          <para>Used to display a fatal error message to the user, and then
          abort the bitbake run.</para>

          <para>The following example from linux-libc-headers shows the use of
          oefatal to tell the user when it cannot find the kernel source code
          for the specified target architecture:<screen>do_configure () {
    case ${TARGET_ARCH} in
        alpha*)   ARCH=alpha ;;
        arm*)     ARCH=arm ;;
        cris*)    ARCH=cris ;;
        hppa*)    ARCH=parisc ;;
        i*86*)    ARCH=i386 ;;
        ia64*)    ARCH=ia64 ;;
        mips*)    ARCH=mips ;;
        m68k*)    ARCH=m68k ;;
        powerpc*) ARCH=ppc ;;
        s390*)    ARCH=s390 ;;
        sh*)      ARCH=sh ;;
        sparc64*) ARCH=sparc64 ;;
        sparc*)   ARCH=sparc ;;
        x86_64*)  ARCH=x86_64 ;;
    esac
    if test !  -e include/asm-$ARCH; then
        oefatal unable to create asm symlink in kernel headers
    fi
...</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>base_conditional (python)</term>

        <listitem>
          <para>The base conditional python function is used to set a variable
          to one of two values based on the definition of a third variable.
          The general usage is:<screen>${@base_conditional('&lt;variable-name&gt;', '&lt;value&gt;', '&lt;true-result&gt;', &lt;false-result&gt;', d)}"</screen>where:</para>

          <variablelist>
            <varlistentry>
              <term>variable-name</term>

              <listitem>
                <para>This is the name of a variable to check.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>value</term>

              <listitem>
                <para>This is the value to compare the variable
                against.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>true-result</term>

              <listitem>
                <para>If the variable equals the value then this is what is
                returned by the function.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>false-result</term>

              <listitem>
                <para>If the variable does not equal the value then this is
                what is returned by the function.</para>
              </listitem>
            </varlistentry>
          </variablelist>

          <note>
            <para>The ${@...} syntax is used to call python functions from
            within a recipe or class. This is described in more detail in the
            <xref linkend="recipes_advanced_python" /> section.</para>
          </note>

          <para>The following example from the openssl recipe shows the
          addition of either <emphasis role="bold">-DL_ENDING</emphasis> or
          <emphasis role="bold">-DB_ENDIAN</emphasis> depending on the value
          of <emphasis role="bold">SITEINFO_ENDIANESS</emphasis> which is set
          to le for little endian targets and to be for big endian
          targets:<screen>do_compile () {
    ...
    # Additional flag based on target endiness (see siteinfo.bbclass)
    CFLAG="${CFLAG} ${@base_conditional('SITEINFO_ENDIANESS', 'le', '-DL_ENDIAN', '-DB_ENDIAN', d)}"
    ...</screen></para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section>

  <section id="recipes_packages" xreflabel="packages">
    <title>Packaging: Defining packages and their contents</title>

    <para>A bitbake recipe is a set of instructions from creating one, or
    more, packages for installation on the target device. Typically these are
    .ipkg or .deb packages (although bitbake itself isn't associated with any
    particular packaging format).</para>

    <para>By default several packages are produced automatically without any
    special action required on the part of the recipe author. The following
    example of the packaging output from the helloworld example above shows
    this packaging in action:<screen>[NOTE: package helloworld-0.1-r0: task do_package_write: started
NOTE: Not creating empty archive for helloworld-dbg-0.1-r0
Packaged contents of helloworld into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/helloworld_0.1-r0_sh4.ipk
Packaged contents of helloworld-doc into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/sh4/helloworld-doc_0.1-r0_sh4.ipk
NOTE: Not creating empty archive for helloworld-dev-0.1-r0
NOTE: Not creating empty archive for helloworld-locale-0.1-r0
NOTE: package helloworld-0.1-r0: task do_package_write: completed</screen>We
    can see from above that the packaging did the following:</para>

    <itemizedlist>
      <listitem>
        <para>Created a main package, <emphasis
        role="bold">helloworld_0.1-r0_sh4.ipk</emphasis>. This package
        contains the helloworld binary <emphasis
        role="bold">/usr/bin/helloworld</emphasis>.</para>
      </listitem>

      <listitem>
        <para>Created a documentation package, <emphasis
        role="bold">helloworld-doc_0.1-r0_sh4.ipk</emphasis>. This package
        contains the readme file <emphasis
        role="bold">/usr/share/doc/helloworld/README.txt</emphasis>.</para>
      </listitem>

      <listitem>
        <para>Considered creating a debug package, <emphasis
        role="bold">helloworld-dbg-0.1-r0_sh4.ipk</emphasis>, a development
        package <emphasis role="bold">helloworld-dev-0.1-r0_sh4.ipk</emphasis>
        and a locale package <emphasis
        role="bold">helloworld-locale-0.1-r0_sh4.ipk</emphasis>. It didn't
        create the package due to the fact that it couldn't find any files
        that would actually go in the package.</para>
      </listitem>
    </itemizedlist>

    <para>There are several things happening here which are important to
    understand:</para>

    <orderedlist>
      <listitem>
        <para>There is a default set of packages that are considered for
        creation. This set of packages is controlled via the <emphasis
        role="bold">PACKAGES</emphasis> variable.</para>
      </listitem>

      <listitem>
        <para>For each package there is a default set of files and/or
        directories that are considered to belong to those packages. The
        documentation packages for example include anything found <emphasis
        role="bold">/usr/share/doc</emphasis>. The set of files and
        directories is controlled via the <emphasis
        role="bold">FILES_&lt;package-name&gt;</emphasis> variables.</para>
      </listitem>

      <listitem>
        <para>By default packages that contain no files are not created and no
        error is generated. The decision to create empty packages or not is
        controlled via the <emphasis role="bold">ALLOW_EMPTY</emphasis>
        variable.</para>
      </listitem>
    </orderedlist>

    <section>
      <title>Philosophy</title>

      <para>Separate packaging, where possible, is of high importance in
      OpenEmbedded. Many of the target devices have limited storage space and
      RAM and giving distributions and users the option of not installing a
      part of the package they don't need allows them to reduce the amount of
      storage space required.</para>

      <para>As an example almost no distributions will include documentation
      or development libraries since they are not required for the day to day
      operation of the device. In particular if your package provides multiple
      binaries, and it would be common to only use one or the other, then you
      should consider separating them into separate packages.</para>

      <para>By default several groups of files are automatically separate out,
      including:</para>

      <variablelist>
        <varlistentry>
          <term>dev</term>

          <listitem>
            <para>Any files required for development. This includes header
            files, static libraries, the shared library symlinks required only
            for linking etc. These would only ever need to be installed by
            someone attempt to compile applications on the target device.
            While this does happen it is very uncommon and so these files are
            automatically moved into a separate package</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>doc</term>

          <listitem>
            <para>Any documentation related files, including man pages. These
            are files which are of informational purposes only. For many
            embedded devices there is no way for the user to see any of the
            documentation anyway, and documentation can consume a lot of
            space. By separating these out they don't take any space by
            default but distributions and/or users may choose to install them
            if they need some documentation on a specific package.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>locale</term>

          <listitem>
            <para>Locale information provides translation information for
            packages. Many users do not require these translations, and many
            devices will only want to provide them for user visible
            components, such as UI related items, and not for system binaries.
            By separating these out it is left up to the distribution or users
            to decide if they are required or not.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>

    <section>
      <title>Default packages and files</title>

      <para>The defaults package settings are defined in <emphasis
      role="bold">conf/bitbake.conf</emphasis> and are suitable for a lot of
      recipes without any changes. The following list shows the default values
      for the packaging related variables:</para>

      <para><variablelist>
          <varlistentry>
            <term>PACKAGES</term>

            <listitem>
              <para>This variable lists the names of each of the packages that
              are to be generated.<screen>PACKAGES = "${PN}-dbg ${PN} ${PN}-doc ${PN}-dev ${PN}-locale"</screen>Note
              that the order of packages is important: the packages are
              processed in the listed order. So if two packages specify the
              same file then the first package listed in packages will get the
              file. This is important when packages use wildcards to specify
              their contents.</para>

              <para>For example if the main package, <emphasis
              role="bold">${PN}</emphasis>, contains <emphasis
              role="bold">/usr/bin/*</emphasis> (i.e. all files in <emphasis
              role="bold">/usr/bin</emphasis>), but you want <emphasis
              role="bold">/usr/bin/tprogram</emphasis> in a separate package,
              <emphasis role="bold">${PN}-tpackage</emphasis>, you would need
              to either ensure that <emphasis
              role="bold">${PN}-tpackage</emphasis> is listed prior to
              <emphasis role="bold">${PN}</emphasis> in <emphasis
              role="bold">PACKAGES</emphasis> or that <emphasis
              role="bold">FILES_${PN}</emphasis> was modified to not contain
              the wildcard that matches <emphasis
              role="bold">/usr/bin/tprogram</emphasis>.</para>

              <para>Note that the -dbg package contains the debugging
              information that has been extracted from binaries and libraries
              prior to them being stripped. This package should always be the
              first package in the package list to ensure that the debugging
              information is correctly extracted and moved to the package
              prior to any other packaging decisions being made.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>FILES_${PN}</term>

            <listitem>
              <para>The base package, this includes everything needed to
              actually run the application on the target system.<screen>FILES_${PN} = "\
    ${bindir}/* \
    ${sbindir}/* \
    ${libexecdir}/* \
    ${libdir}/lib*.so.* \
    ${sysconfdir} \
    ${sharedstatedir} \
    ${localstatedir} \
    /bin/* \
    /sbin/* \
    /lib/*.so* \
    ${datadir}/${PN} \
    ${libdir}/${PN}/* \
    ${datadir}/pixmaps \
    ${datadir}/applications \
    ${datadir}/idl \
    ${datadir}/omf \
    ${datadir}/sounds \
    ${libdir}/bonobo/servers"</screen></para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>FILES_${PN}-dbg</term>

            <listitem>
              <para>The debugging information extracted from non-stripped
              versions of libraries and executable's. OpenEmbedded
              automatically extracts the debugging information into files in
              .debug directories and then strips the original files.<screen>FILES_${PN}-dbg = "\
    ${bindir}/.debug \
    ${sbindir}/.debug \
    ${libexecdir}/.debug \
    ${libdir}/.debug \
    /bin/.debug \
    /sbin/.debug \
    /lib/.debug \
    ${libdir}/${PN}/.debug"</screen></para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>FILES_${PN}-doc</term>

            <listitem>
              <para>Documentation related files. All documentation is
              separated into it's own package so that it does not need to be
              installed unless explicitly required.<screen>FILES_${PN}-doc = "\
    ${docdir} \
    ${mandir} \
    ${infodir} \
    ${datadir}/gtk-doc \
    ${datadir}/gnome/help"</screen></para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>FILES_${PN}-dev</term>

            <listitem>
              <para>Development related files. Any headers, libraries and
              support files needed for development work on the target.<screen>FILES_${PN}-dev = "\
    ${includedir} \
    ${libdir}/lib*.so \
    ${libdir}/*.la \
    ${libdir}/*.a \
    ${libdir}/*.o \
    ${libdir}/pkgconfig \
    /lib/*.a \
    /lib/*.o \
    ${datadir}/aclocal"</screen></para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>FILES_${PN}-locale</term>

            <listitem>
              <para>Locale related files.<screen>FILES_${PN}-locale = "${datadir}/locale"</screen></para>
            </listitem>
          </varlistentry>
        </variablelist></para>
    </section>

    <section>
      <title>Wildcards</title>

      <para>Wildcards used in the <emphasis role="bold">FILES</emphasis>
      variables are processed via the python function <emphasis
      role="bold">fnmatch</emphasis>. The following items are of note about
      this function:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis role="bold">/&lt;dir&gt;/*</emphasis>: This will
          match all files and directories in the <emphasis
          role="bold">dir</emphasis> - it will not match other
          directories.</para>
        </listitem>

        <listitem>
          <para><emphasis role="bold">/&lt;dir&gt;/a*</emphasis>: This will
          only match files, and not directories.</para>
        </listitem>

        <listitem>
          <para><emphasis role="bold">/dir</emphasis>: will include the
          directory <emphasis role="bold">dir</emphasis> in the package, which
          in turn will include all files in the directory and all
          subdirectories.</para>
        </listitem>
      </itemizedlist>

      <para>Note that the order of packages effects the files that will be
      matched via wildcards. Consider the case where we have three binaries in
      the <command>/usr/bin</command> directory and we want the test program
      in a separate package:<screen>/usr/bin/programa /usr/bin/programb /usr/bin/test</screen>So
      we define a new package and instruct bitbake to include /usr/bin/test in
      it.</para>

      <screen>FILES-${PN}-test = "${bindir}/test"
PACKAGES += "FILES-${PN}-test"</screen>

      <para>When the package is regenerated no <emphasis
      role="bold">${PN}-test</emphasis> package will be created. The reason
      for this is that the <emphasis role="bold">PACKAGES</emphasis> line now
      looks like this:<screen>{PN}-dbg ${PN} ${PN}-doc ${PN}-dev ${PN}-locale ${PN}-test</screen>Note
      how <emphasis role="bold">${PN}</emphasis> is listed prior to <emphasis
      role="bold">${PN}-test</emphasis>, and if we look at the definition of
      <emphasis role="bold">FILES-${PN}</emphasis> it contains the <emphasis
      role="bold">${bindir}/*</emphasis> wildcard. Since <emphasis
      role="bold">${PN}</emphasis> is first it'll match that wildcard are be
      moved into the <emphasis role="bold">${PN}</emphasis> package prior to
      processing of the <emphasis role="bold">${PN}-test</emphasis>
      package.</para>

      <para>To achieve what we are trying to accomplish we have two
      options:</para>

      <orderedlist>
        <listitem>
          <para>Modify the definition of <emphasis
          role="bold">${PN}</emphasis> so that the wildcard does not match the
          test program.</para>

          <para>We could do this for example:<screen>FILES-${PN} = "${bindir}/p*"</screen>So
          now this will only match things in the bindir that start with p, and
          therefore not match our test program. Note that <emphasis
          role="bold">FILES-${PN}</emphasis> contains a lot more entries and
          we'd need to add any of the other that refer to files that are to be
          included in the package. In this case we have no other files, so
          it's safe to do this simple declaration.</para>
        </listitem>

        <listitem>
          <para>Modify the order of packages so that the <emphasis
          role="bold">${PN}-test</emphasis> package is listed first.</para>

          <para>The most obvious way to do this would be to prepend our new
          package name to the packages list instead of appending it:<screen>PACKAGES =+ "FILES-${PN}-test"</screen>In
          some cases this would work fine, however there is a problem with
          this for packages that include binaries. The package will now be
          listed before the -dbg package and often this will result in the
          .debug directories being included in the package. In this case we
          are explicitly listing only a single file (and not using wildcards)
          and therefore it would be ok.</para>

          <para>In general it's more common to have to redefine the entire
          package list to include your new package plus any of the default
          packages that you require:<screen>PACKAGES = "${PN}-dbg ${PN}-test ${PN} ${PN}-doc ${PN}-dev ${PN}-locale"</screen></para>
        </listitem>
      </orderedlist>
    </section>

    <section>
      <title>Checking the packages</title>

      <para>During recipe development it's useful to be able to check on
      exactly what files went into each package, which files were not packaged
      and which packages contain no files.</para>

      <para>One of easiest method is to run find on the install directory. In
      the install directory there is one subdirectory created per package, and
      the files are moved into the install directory as they are matched to a
      specific package. The following shows the packages and files for the
      helloworld example:<screen>~/oe%&gt; find tmp/work/helloworld-0.1-r0/install
tmp/work/helloworld-0.1-r0/install
tmp/work/helloworld-0.1-r0/install/helloworld-locale
tmp/work/helloworld-0.1-r0/install/helloworld-dbg
tmp/work/helloworld-0.1-r0/install/helloworld-dev
tmp/work/helloworld-0.1-r0/install/helloworld-doc
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc/helloworld
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc/helloworld/README.txt
tmp/work/helloworld-0.1-r0/install/helloworld
tmp/work/helloworld-0.1-r0/install/helloworld/usr
tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin
tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin/helloworld
~/oe%&gt;</screen>The above shows that the -local, -dbg and -dev packages are
      all empty, and the -doc and base package contain a single file each.
      Uses "<emphasis role="bold">-type f</emphasis>" option to find to show
      just files will make this clearer as well.</para>

      <para>In addition to the install directory the image directory (which
      corresponds to the destination directory, <emphasis
      role="bold">D</emphasis>) will contain any files that were not
      packaged:<screen>~/oe%&gt; find tmp/work/helloworld-0.1-r0/image
tmp/work/helloworld-0.1-r0/image
tmp/work/helloworld-0.1-r0/image/usr
tmp/work/helloworld-0.1-r0/image/usr/bin
tmp/work/helloworld-0.1-r0/image/usr/share
tmp/work/helloworld-0.1-r0/image/usr/share/doc
tmp/work/helloworld-0.1-r0/image/usr/share/doc/helloworld
~/oe%&gt;</screen>In this case all files were packaged and so there are no
      left over files. Using find with "<emphasis role="bold">-type
      f</emphasis>" makes this much clearer:<screen>~/oe%&gt; find tmp/work/helloworld-0.1-r0/image -type f
~/oe%&gt;</screen></para>

      <para>Messages reading missing files are also display by bitbake during
      the package task:<screen>NOTE: package helloworld-0.1-r0: task do_package: started
NOTE: the following files were installed but not shipped in any package:
NOTE:   /usualdir/README.txt
NOTE: package helloworld-0.1-r0: task do_package: completed</screen>Except in
      very unusual circumstances there should be no unpackaged files left
      behind by a recipe.</para>
    </section>

    <section>
      <title>Excluding files</title>

      <para>There's no actual support for explicitly excluding files from
      packaging. You could just leave them out of any package, but then you'll
      get warnings (or errors if requesting full package checking) during
      packaging which is not desirable. It also doesn't let other people know
      that you've deliberately avoided packaging the file or files.</para>

      <para>In order to exclude a file totally you should avoid installing it
      in the first place during the install task.</para>

      <para>In some cases it may be easier to let the package install the file
      and then explicitly remove the file and the end of the install task. The
      following example from the samba recipe shows the removal of several
      files that get installed via the default install task generated by the
      <xref linkend="autotools_class" />. By using
      <emphasis>do_install_append</emphasis> these commands and run after the
      autotools generated install task:</para>

      <screen>do_install_append() {
    ...
    rm -f ${D}${bindir}/*.old
    rm -f ${D}${sbindir}/*.old
    ...
}</screen>
    </section>

    <section>
      <title>Debian naming</title>

      <para>A special <emphasis>debian library name</emphasis> policy can be
      applied for packages that contain a single shared library. When enabled
      packages will be renamed to match the debian policy for such
      packages.</para>

      <para>Debian naming is enabled by including the debian class via either
      <command>local.conf</command> or your distributions configuration
      file:<screen>INHERIT += "debian"</screen></para>

      <para>The policy works by looking at the shared library name and version
      and will automatically rename the package to
      <emphasis>&lt;libname&gt;&lt;lib-major-version&gt;</emphasis>. For
      example if the package name (PN) is <command>foo</command> and the
      package ships a file named <command>libfoo.so.1.2.3</command> then the
      package will be renamed to <command>libfoo1</command> to follow the
      debian policy.</para>

      <para>If we look at the <emphasis>lzo_1.08.bb</emphasis> recipe,
      currently at release 14, it generates a package containing a single
      shared library :<screen>~oe/build/titan-glibc-25%&gt; find tmp/work/lzo-1.08-r14/install/
tmp/work/lzo-1.08-r14/install/lzo
tmp/work/lzo-1.08-r14/install/lzo/usr
tmp/work/lzo-1.08-r14/install/lzo/usr/lib
tmp/work/lzo-1.08-r14/install/lzo/usr/lib/liblzo.so.1
tmp/work/lzo-1.08-r14/install/lzo/usr/lib/liblzo.so.1.0.0</screen>Without
      debian naming this package would have been called
      <command>lzo_1.08-r14_sh4.ipk</command> (and the corresponding dev and
      dbg packages would have been called
      <command>lzo-dbg_1.08-r14_sh4.ipk</command> and
      <command>lzo-dev_1.08-r14_sh4.ipk</command>). However with debian naming
      enabled the package is renamed based on the name of the shared library,
      which is <command>liblzo.so.1.0.0</command> in this case. So the name
      <command>lzo</command> is replaced with
      <command>liblzo1</command>:<screen>~oe/build/titan-glibc-25%&gt; find tmp/deploy/ipk/ -name '*lzo*'  
tmp/deploy/ipk/sh4/liblzo1_1.08-r14_sh4.ipk
tmp/deploy/ipk/sh4/liblzo-dev_1.08-r14_sh4.ipk
tmp/deploy/ipk/sh4/liblzo-dbg_1.08-r14_sh4.ipk</screen></para>

      <para>Some variables are available which effect the operation of the
      debian renaming class:</para>

      <variablelist>
        <varlistentry>
          <term>LEAD_SONAME</term>

          <listitem>
            <para>If the package actually contains multiple shared libraries
            then one will be selected automatically and a warning will be
            generated. This variable is a regular expression which is used to
            select which shared library from those available is to be used for
            debian renaming.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>DEBIAN_NOAUTONAME_&lt;pkgname&gt;</term>

          <listitem>
            <para>If this variable is set to 1 for a package then debian
            renaming will not be applied for the package.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>AUTO_LIBNAME_PKGS</term>

          <listitem>
            <para>If set this variable specifies the prefix of packages which
            will be subject to debian renaming. This can be used to prevent
            all of the packages being renamed via the renaming policy.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>

    <section>
      <title>Empty packages</title>

      <para>By default empty packages are ignored. Occasionally you may wish
      to actually created empty packages, typically done when you want a
      virtual package which will install other packages via dependencies
      without actually installing anything itself. The <emphasis
      role="bold">ALLOW_EMPTY</emphasis> variable is used to control the
      creation of empty packages:</para>

      <variablelist>
        <varlistentry>
          <term>ALLOW_EMPTY</term>

          <listitem>
            <para>Controls if empty packages will be created or not. By
            default this is <emphasis role="bold">"0"</emphasis> and empty
            packages are not created. Setting this to <emphasis
            role="bold">"1"</emphasis> will permit the creation of empty
            packages (packages containing no files).</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>
  </section>

  <section id="recipes_tasks" xreflabel="tasks">
    <title>Tasks: Playing with tasks</title>

    <para>Bitbake steps through a series of tasks when building a recipe.
    Sometimes you need to explicitly define what a class does, such as
    providing a <emphasis role="bold">do_install</emphasis> function to
    implement the <emphasis>install</emphasis> task in a recipe and sometimes
    they are provided for you by common classes, such as the autotools class
    providing the default implementations of <emphasis>configure</emphasis>,
    <emphasis>compile</emphasis> and <emphasis>install</emphasis>
    tasks.</para>

    <para>There are several methods available to modify the tasks that are
    being run:</para>

    <variablelist>
      <varlistentry>
        <term>Overriding the default task implementation</term>

        <listitem>
          <para>By defining your own implementation of task you'll override
          any default or class provided implementations.</para>

          <para>For example, you can define you own implementation of the
          compile task to override any default implementation:<screen>do_compile() {
      oe_runmake DESTDIR=${D}
}</screen></para>

          <para>If you with to totally prevent the task from running you need
          to define your own empty implementation. This is typically done via
          the definition of the task using a single colon:<screen>do_configure() {
    :
}</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Appending or prepending to the task</term>

        <listitem>
          <para>Sometime you want the default implementation, but you require
          addition functionality. This can done by appending or pre-pending
          additional functionality onto the task.</para>

          <para>The following example from units shows an example of
          installing an addition file which for some reason was not installed
          via the autotools normal <emphasis>install</emphasis> task:<screen>do_install_append() {
       install -d ${D}${datadir}
       install -m 0655 units.dat ${D}${datadir}
}</screen></para>

          <para>The following example from the cherokee recipe show an example
          of adding functionality prior to the default
          <emphasis>install</emphasis> task. In this case it compiles a
          program that is used during installation natively so that it will
          work on the host. Without this the autotools default
          <emphasis>install</emphasis> task would fail since it'd try to run
          the program on the host which was compiled for the target:<screen>do_install_prepend () {
        # It only needs this app during the install, so compile it natively
        $BUILD_CC -DHAVE_SYS_STAT_H -o cherokee_replace cherokee_replace.c
}</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Defining a new task</term>

        <listitem>
          <para>Another option is define a totally new task, and then register
          that with bitbake so that it runs in between two of the existing
          tasks.</para>

          <para>The following example shows a situation in which a cvs tree
          needs to be copied over the top of an extracted tar.gz archive, and
          this needs to be done before any local patches are applied. So a new
          task is defined to perform this action, and then that task is
          registered to run between the existing <emphasis>unpack</emphasis>
          and <emphasis>patch</emphasis> tasks:<screen>do_unpack_extra(){
    cp -pPR ${WORKDIR}/linux/* ${S}
}
addtask unpack_extra after do_unpack before do_patch</screen></para>

          <note>
            <para>The task to add does not have the do_ prepended to it,
            however the tasks to insert it after and before do have the _do
            prepended. No errors will be generated if this is wrong, the
            additional task simple won't be executed.</para>
          </note>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Using overrides</term>

        <listitem>
          <para>Overrides (described fully elsewhere) allow for various
          functionality to be performed conditionally based on the target
          machine, distribution, architecture etc.</para>

          <para>While not commonly used it is possible to use overrides when
          defining tasks. The following example from udev shows an additional
          file being installed for the specified machine only by performing an
          append to the <emphasis>install</emphasis> task for the h2200
          machine only:<screen>do_install_append_h2200() {
    install -m 0644 ${WORKDIR}/50-hostap_cs.rules         ${D}${sysconfdir}/udev/rules.d/50-hostap_cs.rules
}</screen></para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section>

  <section id="recipes_classes" xreflabel="classes">
    <title>Classes: The separation of common functionality</title>

    <para>Often a certain pattern is followed in more than one recipe, or
    maybe some complex python based functionality is required to achieve the
    desired end result. This is achieved through the use of classes, which can
    be found in the classes subdirectory at the top-level of on OE
    checkout.</para>

    <para>Being aware of the available classes and understanding their
    functionality is important because classes:</para>

    <itemizedlist>
      <listitem>
        <para>Save developers time being performing actions that they would
        otherwise need to perform themselves;</para>
      </listitem>

      <listitem>
        <para>Perform a lot of actions in the background making a lot of
        recipes difficult to understand unless you are aware of classes and
        how they work;</para>
      </listitem>

      <listitem>
        <para>A lot of detail on how things work can be learnt for looking at
        how classes are implement.</para>
      </listitem>
    </itemizedlist>

    <para>A class is used via the inherit method. The following is an example
    for the <emphasis>curl</emphasis> recipe showing that it uses three
    classes:<screen>inherit autotools pkgconfig binconfig</screen>In this case
    it is utilising the services of three separate classes:</para>

    <variablelist>
      <varlistentry>
        <term>autotools</term>

        <listitem>
          <para>The <xref linkend="autotools_class" /> is used by programs
          that use the GNU configuration tools and takes care of the
          configuration and compilation of the software;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>pkgconfig</term>

        <listitem>
          <para>The <xref linkend="pkgconfig_class" /> is used to stage the
          <emphasis>.pc</emphasis> files which are used by the <emphasis
          role="bold">pkg-config</emphasis> program to provide information
          about the package to other software that wants to link to this
          software;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>binconfig</term>

        <listitem>
          <para>The <xref linkend="binconfig_class" /> is used to stage the
          <emphasis>&lt;name&gt;-config</emphasis> files which are used to
          provide information about the package to other software that wants
          to link to this software;</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Each class is implemented via the file in the <emphasis
    role="bold">classes</emphasis> subdirectory named <emphasis
    role="bold">&lt;classname&gt;.bbclass</emphasis> and these can be examined
    for further details on a particular class, although sometimes it's not
    easy to understand everything that's happening. Many of the classes are
    covered in detail in various sections in this user manual.</para>
  </section>

  <section id="recipes_staging" xreflabel="staging">
    <title>Staging: Making includes and libraries available for
    building</title>

    <para>Staging is the process of making files, such as include files and
    libraries, available for use by other recipes. This is different to
    installing because installing is about making things available for
    packaging and then eventually for use on the target device. Staging on the
    other hand is about making things available on the host system for use by
    building later applications.</para>

    <para>Taking bzip2 as an example you can see that it stages a header file
    and it's library files:<screen>do_stage () {
    install -m 0644 bzlib.h ${STAGING_INCDIR}/
    oe_libinstall -a -so libbz2 ${STAGING_LIBDIR}
}</screen></para>

    <para>The <emphasis>oe_libinstall</emphasis> method used in the bzip2
    recipe is described in the <xref linkend="recipes_methods" /> section, and
    it takes care of installing libraries (into the staging area in this
    case). The staging variables are automatically defined to the correct
    staging location, in this case the main staging variables are used:</para>

    <variablelist>
      <varlistentry>
        <term>STAGING_INCDIR</term>

        <listitem>
          <para>The directory into which staged headers files should be
          installed. This is the equivalent of the standard <emphasis
          role="bold">/usr/include</emphasis> directory.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>STAGING_LIBDIR</term>

        <listitem>
          <para>The directory into which staged library files should be
          installed. This is the equivalent of the standard <emphasis
          role="bold">/usr/lib</emphasis> directory.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Additional staging related variables are covered in the <xref
    linkend="directories_staging" /> section in <xref
    linkend="chapter_reference" />.</para>

    <para>Looking in the staging area under tmp you can see the result of the
    bzip2 recipes staging task:<screen>%&gt; find tmp/staging -name '*bzlib*'
tmp/staging/sh4-linux/include/bzlib.h
%&gt; find tmp/staging -name '*libbz*'
tmp/staging/sh4-linux/lib/libbz2.so
tmp/staging/sh4-linux/lib/libbz2.so.1.0
tmp/staging/sh4-linux/lib/libbz2.so.1
tmp/staging/sh4-linux/lib/libbz2.so.1.0.2
tmp/staging/sh4-linux/lib/libbz2.a</screen></para>

    <para>As well as being used during the stage task the staging related
    variables are used when building other packages. Looking at the gnupg
    recipe we see two bzip2 related items:<screen>DEPENDS = "zlib <emphasis
          role="bold">bzip2</emphasis>"
...
EXTRA_OECONF = "--disable-ldap \
        --with-zlib=${STAGING_LIBDIR}/.. \
        <emphasis role="bold">--with-bzip2=${STAGING_LIBDIR}/..</emphasis> \
        --disable-selinux-support"
</screen></para>

    <para>Bzip2 is referred to in two places in the recipe:</para>

    <variablelist>
      <varlistentry>
        <term>DEPENDS</term>

        <listitem>
          <para>Remember that <emphasis role="bold">DEPENDS</emphasis> defines
          the list of build time dependencies. In this case the staged headers
          and libraries from bzip2 are required to build gnupg, and therefore
          we need to make sure the bzip2 recipe has run and staging the
          headers and libraries. By adding the <emphasis
          role="bold">DEPENDS</emphasis> on bzip2 this ensures that this
          happens.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="bold">EXTRA_OECONF</emphasis></term>

        <listitem>
          <para>This variable is used by the <xref
          linkend="autotools_class" /> to provide options to the configure
          script of the package. In the gnupg case it needs to be told where
          the bzip2 headers and libraries files are, and this is done via the
          <emphasis>--with-bzip2</emphasis> option. In this case it needs to
          the directory which include the lib and include subdirectories.
          Since OE doesn't define a variable for one level above the include
          and lib directories <emphasis role="bold">..</emphasis> is used to
          indicate one directory up. Without this gnupg would search the host
          system headers and libraries instead of those we have provided in
          the staging area for the target.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Remember that staging is used to make things, such as headers and
    libraries, available to used by other recipes later on. While header and
    libraries are the most common item requiring staging other items such as
    the pkgconfig files need to be staged as well, while for native packages
    the binaries also need to be staged.</para>
  </section>

  <section id="recipes_autoconf" xreflabel="about autoconf">
    <title>Autoconf: All about autotools</title>

    <para>This section is to be completed:</para>

    <itemizedlist>
      <listitem>
        <para>About building autoconf packages</para>
      </listitem>

      <listitem>
        <para>EXTRA_OECONF</para>
      </listitem>

      <listitem>
        <para>Problems with /usr/include, /usr/lib</para>
      </listitem>

      <listitem>
        <para>Configuring to search in the staging area</para>
      </listitem>

      <listitem>
        <para>-L${STAGING_LIBDIR} vs ${TARGET_LDFLAGS}</para>
      </listitem>

      <listitem>
        <para>Site files</para>
      </listitem>
    </itemizedlist>
  </section>

  <section id="recipes_installation_scripts" xreflabel="installation scripts">
    <title>Installation scripts: Running scripts during package install and/or
    removal</title>

    <para>Packaging system such as .ipkg and .deb support pre and post
    installation and pre and post removal scripts which are run during package
    install and/or package removal on the target system.</para>

    <para>These scripts can be defined in your recipes to enable actions to be
    performed at the appropriate time. Common uses include starting new
    daemons on installation, stopping daemons during uninstall, creating new
    user and/or group entries during install, registering and unregistering
    alternative implementations of commands and registering the need for
    volatiles.</para>

    <para>The following scripts are supported:</para>

    <variablelist>
      <varlistentry>
        <term>preinst</term>

        <listitem>
          <para>The preinst script is run prior to installing the contents of
          the package. During preinst the contents of the package are not
          available to be used as part of the script. The preinst scripts are
          not commonly used.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>postinst</term>

        <listitem>
          <para>The postinst script is run after the installation of the
          package has completed. During postinst the contents of the package
          are available to be used. This is often used for the creation of
          volatile directories, registration of daemons, starting of daemons
          and fixing up of SUID binaries.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>prerm</term>

        <listitem>
          <para>The prerm is run prior to the removal of the contents of a
          package. During prerm the contents of the package are still
          available for use by the script. The prerm scripts</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>postrm</term>

        <listitem>
          <para>The postrm script is run after the completion of the removal
          of the contents of a package. During postrm the contents of the
          package no longer exist and therefore are not available for use by
          the script. Postrm is most commonly used for update alternatives (to
          tell the alternatives system that this alternative is not available
          and another should be selected).</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Scripts are registered by defining a function for:</para>

    <itemizedlist>
      <listitem>
        <para>pkg_&lt;scriptname&gt;_&lt;packagename&gt;</para>
      </listitem>
    </itemizedlist>

    <para>The following example from ndisc6 shows postinst scripts being
    registered for three of the packages that ndisc6 creates:<screen># Enable SUID bit for applications that need it
pkg_postinst_${PN}-rltraceroute6 () {
    chmod 4555 ${bindir}/rltraceroute6
}
pkg_postinst_${PN}-ndisc6 () {
    chmod 4555 ${bindir}/ndisc6
}
pkg_postinst_${PN}-rdisc6 () {
    chmod 4555 ${bindir}/rdisc6
}</screen></para>

    <note>
      <para>These scripts will be run via <emphasis
      role="bold">/bin/sh</emphasis> on the target device, which is typically
      the busybox sh but could also be bash or some other sh compatible shell.
      As always you should not use any bash extensions in your scripts and
      stick to basic sh syntax.</para>
    </note>

    <para>Note that several classes will also register scripts, and that any
    script you declare will have the script for the classes append to by these
    classes. The following classes all generate additional script
    contents:</para>

    <variablelist>
      <varlistentry>
        <term>update-rc.d</term>

        <listitem>
          <para>This class is used by daemons to register there init scripts
          with the init code.</para>

          <para>Details are provided in the <xref
          linkend="recipes_initscripts" /> section.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>module</term>

        <listitem>
          <para>This class is used by linux kernel modules. It's responsible
          for calling depmod and update-modules during kernel module
          installation and removal.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>kernel</term>

        <listitem>
          <para>This class is used by the linux kernel itself. There is a lot
          of housekeeping required both when installing and removing a kernel
          and this class is responsible for generating the required
          scripts.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>qpf</term>

        <listitem>
          <para>This class is used when installing and/or removing qpf fonts.
          It register scripts to update the font paths and font cache
          information to ensure that the font information is kept up to date
          as fonts and installed and removed.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>update-alternatives</term>

        <listitem>
          <para>This class is used by packages that contain binaries which may
          also be available for other packages. It tells that system that
          another alternative is available for consideration. The alternatives
          system will create a symlink to the correct alternative from one or
          more available on the system.</para>

          <para>Details are provided in the <xref
          linkend="recipes_alternatives" /> section.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>gtk-icon-cache</term>

        <listitem>
          <para>This class is used by packages that add new gtk icons. It's
          responsible for updating the icon cache when packages are installed
          and removed.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>gconf</term>

        <listitem>
          <para></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>package</term>

        <listitem>
          <para>The base class used by packaging classes such as those for
          .ipkg and .deb. The package class may create scripts used to update
          the dynamic linkers ld cache.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>The following example from p3scan shows and postinst script which
    ensure that the required user and group entries exist, and registers the
    need for volatiles (directories and/or files under <emphasis
    role="bold">/var</emphasis>). In addition to explicitly declaring a
    postinst script it uses the update-rc.d class which will result in an
    additional entry being added to the postinst script to register the init
    scripts and start the daemon (via call to update-rc.d as describes in the
    <xref linkend="recipes_alternatives" /> section).<screen>inherit autotools update-rc.d

...

# Add havp's user and groups
pkg_postinst_${PN} () {
        grep -q mail: /etc/group || addgroup --system havp
        grep -q mail: /etc/passwd || \
            adduser --disabled-password --home=${localstatedir}/mail --system \
                    --ingroup mail --no-create-home -g "Mail" mail
        /etc/init.d/populate-volatile.sh update
}</screen></para>

    <para>Several scripts in existing recipes will be of the following
    form:<screen>if [ x"$D" = "x" ]; then
    ...
fi</screen></para>

    <para>This is testing if the installation directory, <emphasis
    role="bold">D</emphasis>, is defined and if it is no actions are
    performed. The installation directory will not be defined under normal
    circumstances. The primary use of this test is to permit the application
    to be installed during root filesystem generation. In that situation the
    scripts cannot be run since the root filesystem is generated on the host
    system and not on the target. Any required script actions would need to be
    performed via an alternative method if the package is to be installed in
    the initial root filesystem (such as including any required users and
    groups in the default <emphasis role="bold">passwd</emphasis> and
    <emphasis role="bold">group</emphasis> files for example.)</para>
  </section>

  <section id="recipes_conffiles" xreflabel="conf files">
    <title>Configuration files</title>

    <para>Configuration files that are installed as part of a package require
    special handling. Without special handling as soon as the user upgrades to
    a new version of the package then changes they have made to the
    configuration files will be lost.</para>

    <para>In order to prevent this from happening you need to tell the
    packaging system which files are configuration files. Such files will
    result in the user being asked how the user wants to handle any
    configuration file changes (if any), as shown in this example:<screen>Downloading http://nynaeve.twibble.org/ipkg-titan-glibc//./p3scan_2.9.05d-r1_sh4.ipk
    Configuration file '/etc/p3scan/p3scan.conf'
    ==&gt; File on system created by you or by a script.
    ==&gt; File also in package provided by package maintainer.
       What would you like to do about it ?  Your options are:
        Y or I  : install the package maintainer's version
        N or O  : keep your currently-installed version
          D     : show the differences between the versions (if diff is installed)
     The default action is to keep your current version.
    *** p3scan.conf (Y/I/N/O/D) [default=N] ?</screen>To declare a file as a
    configuration file you need to define the
    <command>CONFFILES_&lt;pkgname&gt;</command> variable as a whitespace
    separated list of configuration files. The following example from clamav
    shows two files being marked as configuration files:<screen>CONFFILES_${PN}-daemon = "${sysconfdir}/clamd.conf \
                          ${sysconfdir}/default/clamav-daemon"</screen>Note
    the user of <command>${PN}-daemon</command> as the package name. The
    <command>${PN}</command> variable will expand to <command>clamav</command>
    and therefore these conf files are declared as being in the clamav-daemon
    package.</para>
  </section>

  <section id="recipes_package_relationships"
           xreflabel="package relationships files">
    <title>Package relationships</title>

    <para>Explicit relationships between packages are support by packaging
    formats such as ipkg and deb. These relationships include describing
    conflicting packages and recommended packages.</para>

    <para>The following variables control the package relationships in the
    recipes:</para>

    <variablelist>
      <varlistentry>
        <term>RRECOMMENDS</term>

        <listitem>
          <para>Used to specify other packages that are recommended to be
          installed when this package is installed. Generally this means while
          the recommended packages are not required they provide some sort of
          functionality which users would usually want.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RCONFLICTS</term>

        <listitem>
          <para>Used to specify other packages that conflict with this
          package. Two packages that conflict cannot be installed at the same
          time.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RREPLACES</term>

        <listitem>
          <para>Used to specify that the current package replaces an older
          package with a different name. During package installing the package
          that is being replaced will be removed since it is no longer needed
          when this package is installed.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RSUGGESTS</term>

        <listitem>
          <para>Used to provide a list of suggested packages to install. These
          are packages that are related to and useful for the current package
          but which are not actually required to use the package.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RPROVIDES</term>

        <listitem>
          <para>Used to explicitly specify what a package provides at runtime.
          For example hotplug support is provided by several packages, such as
          udev and linux-hotplug. Both declare that they runtime provide
          "hotplug". So any packages that require "hotplug" to work simply
          declare that it RDEPENDS on "hotplug". It's up to the distribution
          to specify which actual implementation of "virtual/xserver" is
          used.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PROVIDES</term>

        <listitem>
          <para>Used to explicitly specify what a package provides at build
          time. This is typically used when two or more packages can provide
          the same functionality. For example there are several different X
          servers in OpenEmbedded, and each as declared as providing
          "virtual/xserver". Therefore a package that depends on an X server
          to build can simply declare that it DEPENDS on "virtual/xserver".
          It's up to the distribution to specify which actual implementation
          of "virtual/xserver" is used.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section>

  <section id="recipes_fakeroot" xreflabel="fakeroot">
    <title>Fakeroot: Dealing with the need for "root"</title>

    <para>Sometimes packages requires root permissions in order to perform
    some action, such as changing user or group owners or creating device
    nodes. Since OpenEmbedded will not keep the user and group information
    it's usually preferably to remove that from the makefiles. For device
    nodes it's usually preferably to create them from the initial device node
    lists or via udev configuration.</para>

    <para>However if you can't get by without root permissions then you can
    use <xref linkend="fakeroot" /> to simulate a root environment, without
    the need to really give root access.</para>

    <para>Using <xref linkend="fakeroot" /> is done by prefixing the
    task:<screen>fakeroot do_install() {</screen>Since this requires fakeroot
    you also need to add a dependency on
    <command>fakeroot-native</command>:<screen>DEPENDS = "fakeroot-native"</screen>See
    the fuse recipe for an example. Further information on <xref
    linkend="fakeroot" />, including a description of it works, is provided in
    the reference section: <xref linkend="fakeroot" />.</para>
  </section>

  <section id="recipes_native" xreflabel="native">
    <title>Native: Packages for the build host</title>

    <para>This section is to be completed.</para>

    <itemizedlist>
      <listitem>
        <para>What native packages are</para>
      </listitem>

      <listitem>
        <para>Using require with the non-native package</para>
      </listitem>
    </itemizedlist>
  </section>

  <section id="recipes_development" xreflabel="development">
    <title>Development: Strategies for developing recipes</title>

    <para>This section is to be completed.</para>

    <itemizedlist>
      <listitem>
        <para>How to go about developing recipes</para>
      </listitem>

      <listitem>
        <para>How do handle incrementally creating patches</para>
      </listitem>

      <listitem>
        <para>How to deal with site file issues</para>
      </listitem>

      <listitem>
        <para>Strategies for autotools issues</para>
      </listitem>
    </itemizedlist>
  </section>

  <section id="recipes_advanced_versioning" xreflabel="advanced versioning">
    <title>Advanced versioning: How to deal with rc and pre versions</title>

    <para>Special care needs to be taken when specify the version number for
    rc and pre versions of packages.</para>

    <para>Consider the case where we have an existing 1.5 version and there's
    a new 1.6-rc1 release that you want to add.</para>

    <itemizedlist>
      <listitem>
        <para>1.5: Existing version;</para>
      </listitem>

      <listitem>
        <para>1.6-rc1: New version.</para>
      </listitem>
    </itemizedlist>

    <para>If the new package is given the version number 1.6-rc1 then
    everything will work fine initially. However when the final release
    happens it will be called 1.6. If you now create a 1.6 version of the
    package you'll find that the packages are sorted into the following
    order:</para>

    <orderedlist>
      <listitem>
        <para>1.5</para>
      </listitem>

      <listitem>
        <para>1.6</para>
      </listitem>

      <listitem>
        <para>1.6-rc1</para>
      </listitem>
    </orderedlist>

    <para>This in turn result in packaging system, such as ipkg, considering
    the released version to be older then the rc version.</para>

    <para>In OpenEmbedded the correct naming of pre and rc versions is to use
    the previous version number followed by a + followed by the new version
    number. So the 1.6-rc1 release would be given the version number:</para>

    <itemizedlist>
      <listitem>
        <para>1.5+1.6-rc1</para>
      </listitem>
    </itemizedlist>

    <para>These would result in the eventually ordering being:</para>

    <orderedlist>
      <listitem>
        <para>1.5</para>
      </listitem>

      <listitem>
        <para>1.5+1.6-rc1</para>
      </listitem>

      <listitem>
        <para>1.6</para>
      </listitem>
    </orderedlist>

    <para>This is the correct order and the packaging system will now work as
    expected.</para>
  </section>

  <section id="recipes_require" xreflabel="require">
    <title>Require/include: Reusing recipe contents</title>

    <para>In many packages where you are maintaining multiple versions you'll
    often end up with several recipes which are either identical, or have only
    minor differences between them.</para>

    <para>The require and/or include directive can be used to include common
    content from one file into other. You should always look for a way to
    factor out common functionality into an include file when adding new
    versions of a recipe.</para>

    <note>
      <para>Both require and include perform the same function - including the
      contents of another file into this recipe. The difference is that
      require will generate an error if the file is not found while include
      will not. For this reason include should not be used in new
      recipes.</para>
    </note>

    <para>For example the clamav recipe looks like this:<screen>require clamav.inc

PR = "r0"</screen>Note that all of the functionality of the recipe is provided
    in the clamav.inc file, only the release number is defined in the recipe.
    Each of the recipes includes the same <emphasis
    role="bold">clamav.inc</emphasis> file to save having to duplicate any
    functionality. This also means that as new versions are released it's a
    simple matter of copying the recipe and resetting the release number back
    to zero.</para>

    <para>The following example from iproute2 shows the recipe adding
    additional patches that are not specified by the common included file.
    These are patches only needed for newer release and by only adding them in
    this recipe it permits the common code to be used for both old and new
    recipes:<screen>PR = "r1"

SRC_URI += "file://iproute2-2.6.15_no_strip.diff;patch=1;pnum=0 \
            file://new-flex-fix.patch;patch=1"

require iproute2.inc

DATE = "060323"</screen></para>

    <para>The following example from cherokee shows a similar method of
    including additional patches for this version only. However it also show
    another technique in which the configure task is defined in the recipe for
    this version, thus replacing the <emphasis>configure</emphasis> task that
    is provided by the common include:<screen>PR = "r7"

SRC_URI_append = "file://configure.patch;patch=1 \
                  file://Makefile.in.patch;patch=1 \
                  file://Makefile.cget.patch;patch=1 \
                  file://util.patch;patch=1"

require cherokee.inc

do_configure() {
        gnu-configize
        oe_runconf
        sed -i 's:-L\$:-L${STAGING_LIBDIR} -L\$:' ${S}/*libtool
}</screen></para>
  </section>

  <section id="recipes_advanced_python" xreflabel="advanced python">
    <title>Python: Advanced functionality with python</title>

    <para>Recipes permit the use of python code in order to perform complex
    operations which are not possible with the normal recipe syntax and
    variables. Python can be used in both variable assignments and in the
    implementation of tasks.</para>

    <para>For variable assignments python code is indicated via the use of
    <emphasis>${@...}</emphasis>, as shown in the following example:<screen>TAG = ${@bb.data.getVar('PV',d,1).replace('.', '_')}</screen></para>

    <para>The above example retrieves the PV variable from the bitbake data
    object, the replaces any dots with underscores. Therefore if the <emphasis
    role="bold">PV</emphasis> was <emphasis role="bold">0.9.0</emphasis> then
    <emphasis role="bold">TAG</emphasis> will be set to <emphasis
    role="bold">0-9-0</emphasis>.</para>

    <para>Some of the more common python code in use in existing recipes is
    shown in the following table:</para>

    <variablelist>
      <varlistentry>
        <term>bb.data.getVar(&lt;var&gt;,d,1)</term>

        <listitem>
          <para>Retrieve the data for the specified variable from the bitbake
          database for the current recipe.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>&lt;variable&gt;.replace(&lt;key&gt;,
        &lt;replacement&gt;)</term>

        <listitem>
          <para>Find each instance of the key and replace it with the
          replacement value. This can also be used to remove part of a string
          by specifying <emphasis role="bold">''</emphasis> (two single
          quotes) as the replacement.</para>

          <para>The following example would remove the <emphasis
          role="bold">'-frename-registers'</emphasis> option from the
          <emphasis role="bold">CFLAGS</emphasis> variable:<screen>CFLAGS := "${@'${CFLAGS}'.replace('-frename-registers', '')}"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>os.path.dirname(&lt;filename&gt;)</term>

        <listitem>
          <para>Return the directory only part of a filename.</para>

          <para>This is most commonly seen in existing recipes when settings
          the <emphasis role="bold">FILESDIR</emphasis> variable (as described
          in the <xref linkend="recipes_filespath_dir" /> section). By
          obtaining name of the recipe file itself, <emphasis
          role="bold">FILE</emphasis>, and then using os.path.dirname to strip
          the filename part:<screen>FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/make-${PV}"</screen>Note
          however that this is no longer required as <emphasis
          role="bold">FILE_DIRNAME</emphasis> is automatically set to the
          dirname of the <emphasis role="bold">FILE</emphasis> variable and
          therefore this would be written in new recipes as:<screen>FILESDIR = "$FILE_DIRNAME/make-${PV}"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>&lt;variable&gt;.split(&lt;key&gt;)[&lt;index&gt;]</term>

        <listitem>
          <para>Splits are variable around the specified key. Use <emphasis
          role="bold">[&lt;index&gt;]</emphasis> to select one of the matching
          items from the array generated by the split command.</para>

          <para>The following example from the recipe g<emphasis
          role="bold">enext2fs_1.3+1.4rc1.bb</emphasis> would take the
          <emphasis role="bold">PV</emphasis> of <emphasis
          role="bold">1.3+1.4rc1</emphasis> and split it around the <emphasis
          role="bold">+</emphasis> sign, resulting in an array containing
          <emphasis role="bold">1.3</emphasis> and <emphasis
          role="bold">1.4rc1</emphasis>. It then uses the index of <emphasis
          role="bold">[1]</emphasis> to select the second item from the list
          (the first item is at index <emphasis role="bold">0</emphasis>).
          Therefore <emphasis role="bold">TRIMMEDV</emphasis> would be set to
          <emphasis role="bold">1.4rc1</emphasis> for this recipe:</para>

          <screen>TRIMMEDV = "${@bb.data.getVar('PV', d, 1).split('+')[1]}"</screen>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>As well as directly calling built-in python functions, those
    functions defined by the existing classes may also be called. A set of
    common functions is provided by the base class in <emphasis
    role="bold">classes/base.bbclass</emphasis>:</para>

    <variablelist>
      <varlistentry>
        <term>base_conditional</term>

        <listitem>
          <para>This functions is used to set a variable to one of two values
          based on the definition of a third variable. The general usage
          is:<screen>${@base_conditional('&lt;variable-name&gt;', '&lt;value&gt;', '&lt;true-result&gt;', &lt;false-result&gt;', d)}"</screen>where:</para>

          <variablelist>
            <varlistentry>
              <term>variable-name</term>

              <listitem>
                <para>This is the name of a variable to check.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>value</term>

              <listitem>
                <para>This is the value to compare the variable
                against.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>true-result</term>

              <listitem>
                <para>If the variable equals the value then this is what is
                returned by the function.</para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>false-result</term>

              <listitem>
                <para>If the variable does not equal the value then this is
                what is returned by the function.</para>
              </listitem>
            </varlistentry>
          </variablelist>

          <para>The following example from the openssl recipe shows the
          addition of either <emphasis role="bold">-DL_ENDING</emphasis> or
          <emphasis role="bold">-DB_ENDIAN</emphasis> depending on the value
          of <emphasis role="bold">SITEINFO_ENDIANESS</emphasis> which is set
          to le for little endian targets and to be for big endian
          targets:<screen>do_compile () {
    ...
    # Additional flag based on target endiness (see siteinfo.bbclass)
    CFLAG="${CFLAG} ${@base_conditional('SITEINFO_ENDIANESS', 'le', '-DL_ENDIAN', '-DB_ENDIAN', d)}"
    ...</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>base_contains</term>

        <listitem>
          <para>Similar to base_conditional expect that it is checking for the
          value being an element of an array. The general usage is:<screen>${@base_contains('&lt;array-name&gt;', '&lt;value&gt;', '&lt;true-result&gt;', &lt;false-result&gt;', d)}"</screen></para>

          <para>where:<variablelist>
              <varlistentry>
                <term>array-name</term>

                <listitem>
                  <para>This is the name of the array to search.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>value</term>

                <listitem>
                  <para>This is the value to check for in the array.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>true-result</term>

                <listitem>
                  <para>If the value is found in the array then this is what
                  is returned by the function.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>false-result</term>

                <listitem>
                  <para>If the value is not found in the array then this is
                  what is returned by the function.</para>
                </listitem>
              </varlistentry>
            </variablelist>The following example from the task-angstrom-x11
          recipe shows base_contains being used to add a recipe to the runtime
          dependency list but only for machines which have a
          touchscreen:</para>

          <screen>RDEPENDS_angstrom-gpe-task-base := "\
    ...
    ${@base_contains("MACHINE_FEATURES", "touchscreen", "libgtkstylus", "",d)} \
    ...</screen>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Tasks may be implemented in python by prefixing the task function
    with "python ". In general this should not be needed and should be avoided
    where possible. The following example from the devshell recipe shows how
    the compile task is implemented python:<screen>python do_compile() {
    import os
    import os.path

    workdir = bb.data.getVar('WORKDIR', d, 1)
    shellfile = os.path.join(workdir, bb.data.expand("${TARGET_PREFIX}${DISTRO}-${MACHINE}-devshell", d))

    f = open(shellfile, "w")

    # emit variables and shell functions
        devshell_emit_env(f, d, False, ["die", "oe", "autotools_do_configure"])

    f.close()
}</screen></para>
  </section>

  <section id="recipes_defaultpreference" xreflabel="default preference">
    <title>Preferences: How to disable packages</title>

    <para>When bitbake is asked to build a package and multiple versions of
    that package are available then bitbake will normally select the version
    that has the highest version number (where the version number is defined
    via the <command>PV</command> variable).</para>

    <para>For example if we were to ask bitbake to build procps and the
    following packages are available:<screen>~/oe%&gt; ls recipes/procps 
procps-3.1.15/    procps-3.2.1/    procps-3.2.5/    procps-3.2.7/    procps.inc
procps_3.1.15.bb  procps_3.2.1.bb  procps_3.2.5.bb  procps_3.2.7.bb
~/oe%&gt;</screen>then we would expect it to select version
    <command>3.2.7</command> (the highest version number) to build.</para>

    <para>Sometimes this is not actually what you want to happen though.
    Perhaps you have added a new version of the package that does not yet work
    or maybe the new version has no support for your target yet. Help is at
    hand since bitbake is not only looking at the version numbers to decided
    which version to build but it is also looking at the preference for each
    of those version. The preference is defined via the
    <command>DEFAULT_PREFERENCE</command> variable contained within the
    recipe.</para>

    <para>The default preference (when no
    <command>DEFAULT_PREFERENCE</command> is specified) is zero. Bitbake will
    find the highest preference that is available and then for all the
    packages at the preference level it will select the package with the
    highest version. In general this means that adding a positive
    <command>DEFAULT_PREFERENCE</command> will cause the package to be
    preferred over other versions and a negative
    <command>DEFAULT_PREFERENCE</command> will cause all other packages to be
    preferred.</para>

    <para>Imagine that you are adding procps version 4.0.0, but that it does
    not yet work. You could delete or rename your new recipe so you can build
    a working image, but what you really to do is just ignore the new 4.0.0
    version until it works. By adding:<screen>DEFAULT_PREFERENCE = "-1"</screen>to
    the recipe this is what will happen. Bitbake will now ignore this version
    (since all of the existing versions have a preference of 0). Note that you
    can still call bitbake directly on the recipe:<screen>bitbake -b recipes/procps/procps_4.0.0.bb</screen>This
    enables you to test, and fix the package manually without having bitbake
    automatically select normally.</para>

    <para>By using this feature in conjunction with overrides you can also
    disable (or select) specific versions based on the override. The following
    example from glibc shows that this version has been disabled for the sh3
    architecture because it doesn't support sh3. This will force bitbake to
    try and select one of the other available versions of glibc
    instead:<screen>recipes/glibc/glibc_2.3.2+cvs20040726.bb:DEFAULT_PREFERENCE_sh3 = "-99"</screen></para>
  </section>

  <section id="recipes_initscripts" xreflabel="initscripts">
    <title>Initscripts: How to handle daemons</title>

    <para>This section is to be completed.</para>

    <itemizedlist>
      <listitem>
        <para>update-rc.d class</para>
      </listitem>

      <listitem>
        <para>sh syntax</para>
      </listitem>

      <listitem>
        <para>stop/stop/restart params</para>
      </listitem>

      <listitem>
        <para>samlpe/standard script?</para>
      </listitem>

      <listitem>
        <para>volatiles</para>
      </listitem>
    </itemizedlist>
  </section>

  <section id="recipes_alternatives" xreflabel="alternatives">
    <title>Alternatives: How to handle the same command in multiple
    packages</title>

    <para>Alternatives are used when the same command is provided by multiple
    packages. A classic example is busybox, which provides a whole set of
    commands such as <emphasis role="bold">/bin/ls</emphasis> and <emphasis
    role="bold">/bin/find</emphasis>, which are also provided by other
    packages such as coreutils (<emphasis role="bold">/bin/ls</emphasis>) and
    findutils (<emphasis role="bold">/bin/find</emphasis>).</para>

    <para>A system for handling alternatives is required to allow the user to
    choose which version of the command they wish to have installed. It should
    be possible to install either one, or both, or remove one when both are
    installed etc, and to have no issues with the packages overwriting files
    from other packages.</para>

    <para>The most common reason for alternatives is to reduce the size of the
    binaries. But cutting down on features, built in help and error messages
    and combining multiple binaries into one large binary it's possible to
    save considerable space. Often users are not expected to use the commands
    interactively in embedded appliances and therefore these changes have no
    visible effect to the user. In some situations users may have interactive
    access, or they may be more advanced users who want shell access on
    appliances that normal don't provide it, and in these cases they should be
    able to install the full functional version if they desire.</para>

    <section>
      <title>Example of alternative commands</title>

      <para>Most distributions include busybox in place of the full featured
      version of the commands. The following example shows a typical install
      in which the find command, which we'll use as an example here, is the
      busybox version:<screen>root@titan:~$ find --version
find --version
BusyBox v1.2.1 (2006.12.17-05:10+0000) multi-call binary

Usage: find [PATH...] [EXPRESSION]

root@titan:~$ which find
which find
/usr/bin/find</screen>If we now install the full version of find:<screen>root@titan:~$ ipkg install findutils
ipkg install findutils
Installing findutils (4.2.29-r0) to root...
Downloading http://nynaeve.twibble.org/ipkg-titan-glibc//./findutils_4.2.29-r0_sh4.ipk
Configuring findutils

update-alternatives: Linking //usr/bin/find to find.findutils
update-alternatives: Linking //usr/bin/xargs to xargs.findutils</screen></para>

      <para>Then we see that the standard version of find changes to the full
      featured implement ion:<screen>root@titan:~$ find --version
find --version
GNU find version 4.2.29
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION
root@titan:~$ which find
which find
/usr/bin/find</screen></para>
    </section>

    <section>
      <title>Using update-alternatives</title>

      <para>Two methods of using the alternatives system are available:</para>

      <orderedlist>
        <listitem>
          <para>Via the <xref linkend="update-alternatives_class" />. This is
          the simplest method, but is not usable in all situations.</para>
        </listitem>

        <listitem>
          <para>Via directly calling the update-alternatives command.</para>
        </listitem>
      </orderedlist>

      <para>The <xref linkend="update-alternatives_class" /> is the provides
      the simplest method of using alternatives but it only works for a single
      alternative. For multiple alternatives they need to be manually
      registered during post install.</para>

      <para>Full details on both methods is provided in the <xref
      linkend="update-alternatives_class" /> section of the reference
      manual.</para>
    </section>
  </section>

  <section id="recipes_volatiles" xreflabel="volatiles">
    <title>Volatiles: How to handle the /var directory</title>

    <para>The <emphasis role="bold">/var</emphasis> directory is for storing
    volatile information, that is information which is constantly changing and
    which in general may be easily recreated. In embedded applications it is
    often desirable that such files are not stored on disk or flash for
    various reasons including:</para>

    <itemizedlist>
      <listitem>
        <para>The possibility of a reduced lifetime of the flash;</para>
      </listitem>

      <listitem>
        <para>The limited amount of storage space available;</para>
      </listitem>

      <listitem>
        <para>To ensure filesystem corruption cannot occur due to a sudden
        power loss.</para>
      </listitem>
    </itemizedlist>

    <para>For these reasons many of the OpenEmbedded distributions use a tmpfs
    based memory filesystem for <emphasis role="bold">/var</emphasis> instead
    of using a disk or flash based filesystem. The consequence of this is that
    all contents of the <emphasis role="bold">/var</emphasis> directory is
    lost when the device is powered off or restarted. Therefore special
    handling of <emphasis role="bold">/var</emphasis> is required in all
    packages. Even if your distrubution does not use a tmpfs based <emphasis
    role="bold">/var</emphasis> you need to assume it does when creating
    packages to ensure the package can be used on those distributions that do
    use a tmpfs based <emphasis role="bold">/var</emphasis>. This special
    handling is provided via the <emphasis
    role="bold">populate-volatiles.sh</emphasis> script.</para>

    <note>
      <para>If your package requires any files, directories or symlinks in
      <emphasis role="bold">/var</emphasis> then it should be using the
      populate-volatiles facilities.</para>
    </note>

    <section>
      <title>Declaring volatiles</title>

      <para>This section is to be completed.</para>

      <itemizedlist>
        <listitem>
          <para>how volatiles work</para>
        </listitem>

        <listitem>
          <para>default volatiles</para>
        </listitem>

        <listitem>
          <para>don't include any /var stuff in packages</para>
        </listitem>

        <listitem>
          <para>even if your distro don't use /var in tmpfs, others do</para>
        </listitem>

        <listitem>
          <para>updating the volatiles cache during install</para>
        </listitem>
      </itemizedlist>
    </section>

    <section>
      <title>Logging and log files</title>

      <para>As a consequence of the non-volatile and/or small capacity of the
      <emphasis role="bold">/var</emphasis> file system some distributions
      choose methods of logging other than writing to a file. The most typical
      is the use of an in-memory circular log buffer which can be read using
      the <emphasis role="bold">logread</emphasis> command.</para>

      <para>To ensure that each distribution is able to implement logging in a
      method that is suitable for its goals all packages should be configured
      by default to log via syslog, and not log directly to a file, if
      possible. If the distribution and/or end-user requires logging to a file
      then they can configured syslog and/or your application to implement
      this.</para>
    </section>

    <section>
      <title>Summary</title>

      <para>In summary the following are required when dealing with
      <command>/var</command>:</para>

      <itemizedlist>
        <listitem>
          <para>Configure all logging to use syslog whenever possible. This
          leaves the decision on where to log upto the individual
          distributions.</para>
        </listitem>

        <listitem>
          <para>Don't include any <command>/var</command> directories, file or
          symlinks in packages. They would be lost on a reboot and so should
          not be included in packages.</para>
        </listitem>

        <listitem>
          <para>The only directories that you can assume exist are those
          listed in the default volatiles file:
          <command>recipes/initscripts/initscripts-1.0/volatiles</command>.</para>
        </listitem>

        <listitem>
          <para>For any other directories, files or links that are required in
          <command>/var</command> you should install your own volatiles list
          as part of the package.</para>
        </listitem>
      </itemizedlist>
    </section>
  </section>

  <section id="recipes_misc">
    <title>Miscellaneous</title>

    <para>This section is to be completed.</para>

    <itemizedlist>
      <listitem>
        <para>about optimisation</para>
      </listitem>

      <listitem>
        <para>about download directories</para>
      </listitem>

      <listitem>
        <para>about parallel builds</para>
      </listitem>

      <listitem>
        <para>about determining endianess (aka net-snmp, openssl, hping etc
        style)</para>
      </listitem>

      <listitem>
        <para>about PACKAGES_DYNAMIC</para>
      </listitem>

      <listitem>
        <para>about LEAD_SONAME</para>
      </listitem>

      <listitem>
        <para>about "python () {" - looks like it is always run when a recipe
        is parsed? see pam/libpam</para>
      </listitem>

      <listitem>
        <para>about SRCDATE with svn/cvs?</para>
      </listitem>

      <listitem>
        <para>about INHIBIT_DEFAULT_DEPS?</para>
      </listitem>

      <listitem>
        <para>about COMPATIBLE_MACHINE and COMPATIBLE_HOST</para>
      </listitem>

      <listitem>
        <para>about SUID binaries, and the need for postinst to fix them
        up</para>
      </listitem>

      <listitem>
        <para>about passwd and group (some comment in install scripts section
        already).</para>
      </listitem>
    </itemizedlist>

    <para></para>
  </section>
</chapter>