Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 1 | .. SPDX-License-Identifier: CC-BY-SA-2.0-UK |
| 2 | |
| 3 | Customizing Images |
| 4 | ****************** |
| 5 | |
| 6 | You can customize images to satisfy particular requirements. This |
| 7 | section describes several methods and provides guidelines for each. |
| 8 | |
| 9 | Customizing Images Using ``local.conf`` |
| 10 | ======================================= |
| 11 | |
| 12 | Probably the easiest way to customize an image is to add a package by |
| 13 | way of the ``local.conf`` configuration file. Because it is limited to |
| 14 | local use, this method generally only allows you to add packages and is |
| 15 | not as flexible as creating your own customized image. When you add |
| 16 | packages using local variables this way, you need to realize that these |
| 17 | variable changes are in effect for every build and consequently affect |
| 18 | all images, which might not be what you require. |
| 19 | |
| 20 | To add a package to your image using the local configuration file, use |
| 21 | the :term:`IMAGE_INSTALL` variable with the ``:append`` operator:: |
| 22 | |
| 23 | IMAGE_INSTALL:append = " strace" |
| 24 | |
| 25 | Use of the syntax is important; specifically, the leading space |
| 26 | after the opening quote and before the package name, which is |
| 27 | ``strace`` in this example. This space is required since the ``:append`` |
| 28 | operator does not add the space. |
| 29 | |
| 30 | Furthermore, you must use ``:append`` instead of the ``+=`` operator if |
| 31 | you want to avoid ordering issues. The reason for this is because doing |
| 32 | so unconditionally appends to the variable and avoids ordering problems |
| 33 | due to the variable being set in image recipes and ``.bbclass`` files |
| 34 | with operators like ``?=``. Using ``:append`` ensures the operation |
| 35 | takes effect. |
| 36 | |
| 37 | As shown in its simplest use, ``IMAGE_INSTALL:append`` affects all |
| 38 | images. It is possible to extend the syntax so that the variable applies |
| 39 | to a specific image only. Here is an example:: |
| 40 | |
| 41 | IMAGE_INSTALL:append:pn-core-image-minimal = " strace" |
| 42 | |
| 43 | This example adds ``strace`` to the ``core-image-minimal`` image only. |
| 44 | |
| 45 | You can add packages using a similar approach through the |
| 46 | :term:`CORE_IMAGE_EXTRA_INSTALL` variable. If you use this variable, only |
| 47 | ``core-image-*`` images are affected. |
| 48 | |
| 49 | Customizing Images Using Custom ``IMAGE_FEATURES`` and ``EXTRA_IMAGE_FEATURES`` |
| 50 | =============================================================================== |
| 51 | |
| 52 | Another method for customizing your image is to enable or disable |
| 53 | high-level image features by using the |
| 54 | :term:`IMAGE_FEATURES` and |
| 55 | :term:`EXTRA_IMAGE_FEATURES` |
| 56 | variables. Although the functions for both variables are nearly |
| 57 | equivalent, best practices dictate using :term:`IMAGE_FEATURES` from within |
| 58 | a recipe and using :term:`EXTRA_IMAGE_FEATURES` from within your |
| 59 | ``local.conf`` file, which is found in the :term:`Build Directory`. |
| 60 | |
| 61 | To understand how these features work, the best reference is |
| 62 | :ref:`meta/classes-recipe/image.bbclass <ref-classes-image>`. |
| 63 | This class lists out the available |
| 64 | :term:`IMAGE_FEATURES` of which most map to package groups while some, such |
| 65 | as ``debug-tweaks`` and ``read-only-rootfs``, resolve as general |
| 66 | configuration settings. |
| 67 | |
| 68 | In summary, the file looks at the contents of the :term:`IMAGE_FEATURES` |
| 69 | variable and then maps or configures the feature accordingly. Based on |
| 70 | this information, the build system automatically adds the appropriate |
| 71 | packages or configurations to the |
| 72 | :term:`IMAGE_INSTALL` variable. |
| 73 | Effectively, you are enabling extra features by extending the class or |
| 74 | creating a custom class for use with specialized image ``.bb`` files. |
| 75 | |
| 76 | Use the :term:`EXTRA_IMAGE_FEATURES` variable from within your local |
| 77 | configuration file. Using a separate area from which to enable features |
| 78 | with this variable helps you avoid overwriting the features in the image |
| 79 | recipe that are enabled with :term:`IMAGE_FEATURES`. The value of |
| 80 | :term:`EXTRA_IMAGE_FEATURES` is added to :term:`IMAGE_FEATURES` within |
| 81 | ``meta/conf/bitbake.conf``. |
| 82 | |
| 83 | To illustrate how you can use these variables to modify your image, |
| 84 | consider an example that selects the SSH server. The Yocto Project ships |
| 85 | with two SSH servers you can use with your images: Dropbear and OpenSSH. |
| 86 | Dropbear is a minimal SSH server appropriate for resource-constrained |
| 87 | environments, while OpenSSH is a well-known standard SSH server |
| 88 | implementation. By default, the ``core-image-sato`` image is configured |
| 89 | to use Dropbear. The ``core-image-full-cmdline`` and ``core-image-lsb`` |
| 90 | images both include OpenSSH. The ``core-image-minimal`` image does not |
| 91 | contain an SSH server. |
| 92 | |
| 93 | You can customize your image and change these defaults. Edit the |
| 94 | :term:`IMAGE_FEATURES` variable in your recipe or use the |
| 95 | :term:`EXTRA_IMAGE_FEATURES` in your ``local.conf`` file so that it |
| 96 | configures the image you are working with to include |
| 97 | ``ssh-server-dropbear`` or ``ssh-server-openssh``. |
| 98 | |
| 99 | .. note:: |
| 100 | |
| 101 | See the ":ref:`ref-manual/features:image features`" section in the Yocto |
| 102 | Project Reference Manual for a complete list of image features that ship |
| 103 | with the Yocto Project. |
| 104 | |
| 105 | Customizing Images Using Custom .bb Files |
| 106 | ========================================= |
| 107 | |
| 108 | You can also customize an image by creating a custom recipe that defines |
| 109 | additional software as part of the image. The following example shows |
| 110 | the form for the two lines you need:: |
| 111 | |
| 112 | IMAGE_INSTALL = "packagegroup-core-x11-base package1 package2" |
| 113 | inherit core-image |
| 114 | |
| 115 | Defining the software using a custom recipe gives you total control over |
| 116 | the contents of the image. It is important to use the correct names of |
| 117 | packages in the :term:`IMAGE_INSTALL` variable. You must use the |
| 118 | OpenEmbedded notation and not the Debian notation for the names (e.g. |
| 119 | ``glibc-dev`` instead of ``libc6-dev``). |
| 120 | |
| 121 | The other method for creating a custom image is to base it on an |
| 122 | existing image. For example, if you want to create an image based on |
| 123 | ``core-image-sato`` but add the additional package ``strace`` to the |
| 124 | image, copy the ``meta/recipes-sato/images/core-image-sato.bb`` to a new |
| 125 | ``.bb`` and add the following line to the end of the copy:: |
| 126 | |
| 127 | IMAGE_INSTALL += "strace" |
| 128 | |
| 129 | Customizing Images Using Custom Package Groups |
| 130 | ============================================== |
| 131 | |
| 132 | For complex custom images, the best approach for customizing an image is |
| 133 | to create a custom package group recipe that is used to build the image |
| 134 | or images. A good example of a package group recipe is |
| 135 | ``meta/recipes-core/packagegroups/packagegroup-base.bb``. |
| 136 | |
| 137 | If you examine that recipe, you see that the :term:`PACKAGES` variable lists |
| 138 | the package group packages to produce. The ``inherit packagegroup`` |
| 139 | statement sets appropriate default values and automatically adds |
| 140 | ``-dev``, ``-dbg``, and ``-ptest`` complementary packages for each |
| 141 | package specified in the :term:`PACKAGES` statement. |
| 142 | |
| 143 | .. note:: |
| 144 | |
| 145 | The ``inherit packagegroup`` line should be located near the top of the |
| 146 | recipe, certainly before the :term:`PACKAGES` statement. |
| 147 | |
| 148 | For each package you specify in :term:`PACKAGES`, you can use :term:`RDEPENDS` |
| 149 | and :term:`RRECOMMENDS` entries to provide a list of packages the parent |
| 150 | task package should contain. You can see examples of these further down |
| 151 | in the ``packagegroup-base.bb`` recipe. |
| 152 | |
| 153 | Here is a short, fabricated example showing the same basic pieces for a |
| 154 | hypothetical packagegroup defined in ``packagegroup-custom.bb``, where |
| 155 | the variable :term:`PN` is the standard way to abbreviate the reference to |
| 156 | the full packagegroup name ``packagegroup-custom``:: |
| 157 | |
| 158 | DESCRIPTION = "My Custom Package Groups" |
| 159 | |
| 160 | inherit packagegroup |
| 161 | |
| 162 | PACKAGES = "\ |
| 163 | ${PN}-apps \ |
| 164 | ${PN}-tools \ |
| 165 | " |
| 166 | |
| 167 | RDEPENDS:${PN}-apps = "\ |
| 168 | dropbear \ |
| 169 | portmap \ |
| 170 | psplash" |
| 171 | |
| 172 | RDEPENDS:${PN}-tools = "\ |
| 173 | oprofile \ |
| 174 | oprofileui-server \ |
| 175 | lttng-tools" |
| 176 | |
| 177 | RRECOMMENDS:${PN}-tools = "\ |
| 178 | kernel-module-oprofile" |
| 179 | |
| 180 | In the previous example, two package group packages are created with |
| 181 | their dependencies and their recommended package dependencies listed: |
| 182 | ``packagegroup-custom-apps``, and ``packagegroup-custom-tools``. To |
| 183 | build an image using these package group packages, you need to add |
| 184 | ``packagegroup-custom-apps`` and/or ``packagegroup-custom-tools`` to |
| 185 | :term:`IMAGE_INSTALL`. For other forms of image dependencies see the other |
| 186 | areas of this section. |
| 187 | |
| 188 | Customizing an Image Hostname |
| 189 | ============================= |
| 190 | |
| 191 | By default, the configured hostname (i.e. ``/etc/hostname``) in an image |
| 192 | is the same as the machine name. For example, if |
| 193 | :term:`MACHINE` equals "qemux86", the |
| 194 | configured hostname written to ``/etc/hostname`` is "qemux86". |
| 195 | |
| 196 | You can customize this name by altering the value of the "hostname" |
| 197 | variable in the ``base-files`` recipe using either an append file or a |
| 198 | configuration file. Use the following in an append file:: |
| 199 | |
| 200 | hostname = "myhostname" |
| 201 | |
| 202 | Use the following in a configuration file:: |
| 203 | |
| 204 | hostname:pn-base-files = "myhostname" |
| 205 | |
| 206 | Changing the default value of the variable "hostname" can be useful in |
| 207 | certain situations. For example, suppose you need to do extensive |
| 208 | testing on an image and you would like to easily identify the image |
| 209 | under test from existing images with typical default hostnames. In this |
| 210 | situation, you could change the default hostname to "testme", which |
| 211 | results in all the images using the name "testme". Once testing is |
| 212 | complete and you do not need to rebuild the image for test any longer, |
| 213 | you can easily reset the default hostname. |
| 214 | |
| 215 | Another point of interest is that if you unset the variable, the image |
| 216 | will have no default hostname in the filesystem. Here is an example that |
| 217 | unsets the variable in a configuration file:: |
| 218 | |
| 219 | hostname:pn-base-files = "" |
| 220 | |
| 221 | Having no default hostname in the filesystem is suitable for |
| 222 | environments that use dynamic hostnames such as virtual machines. |
| 223 | |