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