Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 1 | .. SPDX-License-Identifier: CC-BY-SA-2.0-UK |
| 2 | |
| 3 | Recipe Style Guide |
| 4 | ****************** |
| 5 | |
| 6 | Recipe Naming Conventions |
| 7 | ========================= |
| 8 | |
| 9 | In general, most recipes should follow the naming convention |
Andrew Geissler | 220dafd | 2023-10-04 10:18:08 -0500 | [diff] [blame] | 10 | ``recipes-category/recipename/recipename_version.bb``. Recipes for related |
| 11 | projects may share the same recipe directory. ``recipename`` and ``category`` |
| 12 | may contain hyphens, but hyphens are not allowed in ``version``. |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 13 | |
| 14 | If the recipe is tracking a Git revision that does not correspond to a released |
Andrew Geissler | 220dafd | 2023-10-04 10:18:08 -0500 | [diff] [blame] | 15 | version of the software, ``version`` may be ``git`` (e.g. ``recipename_git.bb``) |
| 16 | and the recipe would set :term:`PV`. |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 17 | |
| 18 | Version Policy |
| 19 | ============== |
| 20 | |
Andrew Geissler | 220dafd | 2023-10-04 10:18:08 -0500 | [diff] [blame] | 21 | Our versions follow the form ``<epoch>:<version>-<revision>`` |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 22 | or in BitBake variable terms ${:term:`PE`}:${:term:`PV`}-${:term:`PR`}. We |
| 23 | generally follow the `Debian <https://www.debian.org/doc/debian-policy/ch-controlfields.html#version>`__ |
| 24 | version policy which defines these terms. |
| 25 | |
| 26 | In most cases the version :term:`PV` will be set automatically from the recipe |
| 27 | file name. It is recommended to use released versions of software as these are |
| 28 | revisions that upstream are expecting people to use. |
| 29 | |
Andrew Geissler | 220dafd | 2023-10-04 10:18:08 -0500 | [diff] [blame] | 30 | Recipe versions should always compare and sort correctly so that upgrades work |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 31 | as expected. With conventional versions such as ``1.4`` upgrading ``to 1.5`` |
| 32 | this happens naturally, but some versions don't sort. For example, |
| 33 | ``1.5 Release Candidate 2`` could be written as ``1.5rc2`` but this sorts after |
| 34 | ``1.5``, so upgrades from feeds won't happen correctly. |
| 35 | |
| 36 | Instead the tilde (``~``) operator can be used, which sorts before the empty |
| 37 | string so ``1.5~rc2`` comes before ``1.5``. There is a historical syntax which |
| 38 | may be found where :term:`PV` is set as a combination of the prior version |
| 39 | ``+`` the pre-release version, for example ``PV=1.4+1.5rc2``. This is a valid |
| 40 | syntax but the tilde form is preferred. |
| 41 | |
| 42 | For version comparisons, the ``opkg-compare-versions`` program from |
| 43 | ``opkg-utils`` can be useful when attempting to determine how two version |
| 44 | numbers compare to each other. Our definitive version comparison algorithm is |
| 45 | the one within bitbake which aims to match those of the package managers and |
| 46 | Debian policy closely. |
| 47 | |
| 48 | When a recipe references a git revision that does not correspond to a released |
| 49 | version of software (e.g. is not a tagged version), the :term:`PV` variable |
| 50 | should include the Git revision using the following to make the |
| 51 | version clear:: |
| 52 | |
| 53 | PV = "<version>+git${SRCPV}" |
| 54 | |
| 55 | In this case, ``<version>`` should be the most recently released version of the |
| 56 | software from the current source revision (``git describe`` can be useful for |
| 57 | determining this). Whilst not recommended for published layers, this format is |
| 58 | also useful when using :term:`AUTOREV` to set the recipe to increment source |
| 59 | control revisions automatically, which can be useful during local development. |
| 60 | |
| 61 | Version Number Changes |
| 62 | ====================== |
| 63 | |
| 64 | The :term:`PR` variable is used to indicate different revisions of a recipe |
| 65 | that reference the same upstream source version. It can be used to force a |
Andrew Geissler | 220dafd | 2023-10-04 10:18:08 -0500 | [diff] [blame] | 66 | new version of a recipe to be installed onto a device from a package feed. |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 67 | These once had to be set manually but in most cases these can now be set and |
| 68 | incremented automatically by a PR Server connected with a package feed. |
| 69 | |
| 70 | When :term:`PV` increases, any existing :term:`PR` value can and should be |
| 71 | removed. |
| 72 | |
| 73 | If :term:`PV` changes in such a way that it does not increase with respect to |
| 74 | the previous value, you need to increase :term:`PE` to ensure package managers |
| 75 | will upgrade it correctly. If unset you should set :term:`PE` to "1" since |
| 76 | the default of empty is easily confused with "0" depending on the package |
| 77 | manager. :term:`PE` can only have an integer value. |
| 78 | |
| 79 | Recipe formatting |
| 80 | ================= |
| 81 | |
| 82 | Variable Formatting |
| 83 | ------------------- |
| 84 | |
| 85 | - Variable assignment should a space around each side of the operator, e.g. |
| 86 | ``FOO = "bar"``, not ``FOO="bar"``. |
| 87 | |
| 88 | - Double quotes should be used on the right-hand side of the assignment, |
| 89 | e.g. ``FOO = "bar"`` not ``FOO = 'bar'`` |
| 90 | |
| 91 | - Spaces should be used for indenting variables, with 4 spaces per tab |
| 92 | |
| 93 | - Long variables should be split over multiple lines when possible by using |
| 94 | the continuation character (``\``) |
| 95 | |
| 96 | - When splitting a long variable over multiple lines, all continuation lines |
| 97 | should be indented (with spaces) to align with the start of the quote on the |
| 98 | first line:: |
| 99 | |
| 100 | FOO = "this line is \ |
| 101 | long \ |
| 102 | " |
| 103 | |
| 104 | Instead of:: |
| 105 | |
| 106 | FOO = "this line is \ |
| 107 | long \ |
| 108 | " |
| 109 | |
| 110 | Python Function formatting |
| 111 | -------------------------- |
| 112 | |
| 113 | - Spaces must be used for indenting Python code, with 4 spaces per tab |
| 114 | |
| 115 | Shell Function formatting |
| 116 | ------------------------- |
| 117 | |
| 118 | - The formatting of shell functions should be consistent within layers. |
| 119 | Some use tabs, some use spaces. |
| 120 | |
| 121 | Recipe metadata |
| 122 | =============== |
| 123 | |
| 124 | Required Variables |
| 125 | ------------------ |
| 126 | |
| 127 | The following variables should be included in all recipes: |
| 128 | |
| 129 | - :term:`SUMMARY`: a one line description of the upstream project |
| 130 | |
| 131 | - :term:`DESCRIPTION`: an extended description of the upstream project, |
| 132 | possibly with multiple lines. If no reasonable description can be written, |
| 133 | this may be omitted as it defaults to :term:`SUMMARY`. |
| 134 | |
| 135 | - :term:`HOMEPAGE`: the URL to the upstream projects homepage. |
| 136 | |
| 137 | - :term:`BUGTRACKER`: the URL upstream projects bug tracking website, |
| 138 | if applicable. |
| 139 | |
| 140 | Recipe Ordering |
| 141 | --------------- |
| 142 | |
| 143 | When a variable is defined in recipes and classes, variables should follow the |
| 144 | general order when possible: |
| 145 | |
| 146 | - :term:`SUMMARY` |
| 147 | - :term:`DESCRIPTION` |
| 148 | - :term:`HOMEPAGE` |
| 149 | - :term:`BUGTRACKER` |
| 150 | - :term:`SECTION` |
| 151 | - :term:`LICENSE` |
| 152 | - :term:`LIC_FILES_CHKSUM` |
| 153 | - :term:`DEPENDS` |
| 154 | - :term:`PROVIDES` |
| 155 | - :term:`PV` |
| 156 | - :term:`SRC_URI` |
| 157 | - :term:`SRCREV` |
| 158 | - :term:`S` |
| 159 | - ``inherit ...`` |
| 160 | - :term:`PACKAGECONFIG` |
| 161 | - Build class specific variables such as ``EXTRA_QMAKEVARS_POST`` and :term:`EXTRA_OECONF` |
| 162 | - Tasks such as :ref:`ref-tasks-configure` |
| 163 | - :term:`PACKAGE_ARCH` |
| 164 | - :term:`PACKAGES` |
| 165 | - :term:`FILES` |
| 166 | - :term:`RDEPENDS` |
| 167 | - :term:`RRECOMMENDS` |
| 168 | - :term:`RSUGGESTS` |
| 169 | - :term:`RPROVIDES` |
| 170 | - :term:`RCONFLICTS` |
| 171 | - :term:`BBCLASSEXTEND` |
| 172 | |
| 173 | There are some cases where ordering is important and these cases would override |
| 174 | this default order. Examples include: |
| 175 | |
| 176 | - :term:`PACKAGE_ARCH` needing to be set before ``inherit packagegroup`` |
| 177 | |
| 178 | Tasks should be ordered based on the order they generally execute. For commonly |
| 179 | used tasks this would be: |
| 180 | |
| 181 | - :ref:`ref-tasks-fetch` |
| 182 | - :ref:`ref-tasks-unpack` |
| 183 | - :ref:`ref-tasks-patch` |
| 184 | - :ref:`ref-tasks-prepare_recipe_sysroot` |
| 185 | - :ref:`ref-tasks-configure` |
| 186 | - :ref:`ref-tasks-compile` |
| 187 | - :ref:`ref-tasks-install` |
| 188 | - :ref:`ref-tasks-populate_sysroot` |
| 189 | - :ref:`ref-tasks-package` |
| 190 | |
| 191 | Custom tasks should be sorted similarly. |
| 192 | |
| 193 | Package specific variables are typically grouped together, e.g.:: |
| 194 | |
| 195 | RDEPENDS:${PN} = “foo” |
| 196 | RDEPENDS:${PN}-libs = “bar” |
| 197 | |
| 198 | RRECOMMENDS:${PN} = “one” |
| 199 | RRECOMMENDS:${PN}-libs = “two” |
| 200 | |
| 201 | Recipe License Fields |
| 202 | --------------------- |
| 203 | |
| 204 | Recipes need to define both the :term:`LICENSE` and |
| 205 | :term:`LIC_FILES_CHKSUM` variables: |
| 206 | |
| 207 | - :term:`LICENSE`: This variable specifies the license for the software. |
| 208 | If you do not know the license under which the software you are |
| 209 | building is distributed, you should go to the source code and look |
| 210 | for that information. Typical files containing this information |
| 211 | include ``COPYING``, :term:`LICENSE`, and ``README`` files. You could |
| 212 | also find the information near the top of a source file. For example, |
| 213 | given a piece of software licensed under the GNU General Public |
| 214 | License version 2, you would set :term:`LICENSE` as follows:: |
| 215 | |
| 216 | LICENSE = "GPL-2.0-only" |
| 217 | |
| 218 | The licenses you specify within :term:`LICENSE` can have any name as long |
| 219 | as you do not use spaces, since spaces are used as separators between |
| 220 | license names. For standard licenses, use the names of the files in |
| 221 | ``meta/files/common-licenses/`` or the :term:`SPDXLICENSEMAP` flag names |
| 222 | defined in ``meta/conf/licenses.conf``. |
| 223 | |
| 224 | - :term:`LIC_FILES_CHKSUM`: The OpenEmbedded build system uses this |
| 225 | variable to make sure the license text has not changed. If it has, |
| 226 | the build produces an error and it affords you the chance to figure |
| 227 | it out and correct the problem. |
| 228 | |
| 229 | You need to specify all applicable licensing files for the software. |
| 230 | At the end of the configuration step, the build process will compare |
| 231 | the checksums of the files to be sure the text has not changed. Any |
| 232 | differences result in an error with the message containing the |
| 233 | current checksum. For more explanation and examples of how to set the |
| 234 | :term:`LIC_FILES_CHKSUM` variable, see the |
| 235 | ":ref:`dev-manual/licenses:tracking license changes`" section. |
| 236 | |
| 237 | To determine the correct checksum string, you can list the |
| 238 | appropriate files in the :term:`LIC_FILES_CHKSUM` variable with incorrect |
| 239 | md5 strings, attempt to build the software, and then note the |
| 240 | resulting error messages that will report the correct md5 strings. |
| 241 | See the ":ref:`dev-manual/new-recipe:fetching code`" section for |
| 242 | additional information. |
| 243 | |
| 244 | Here is an example that assumes the software has a ``COPYING`` file:: |
| 245 | |
| 246 | LIC_FILES_CHKSUM = "file://COPYING;md5=xxx" |
| 247 | |
| 248 | When you try to build the |
| 249 | software, the build system will produce an error and give you the |
| 250 | correct string that you can substitute into the recipe file for a |
| 251 | subsequent build. |
| 252 | |
| 253 | Tips and Guidelines for Writing Recipes |
| 254 | --------------------------------------- |
| 255 | |
| 256 | - Use :term:`BBCLASSEXTEND` instead of creating separate recipes such as ``-native`` |
| 257 | and ``-nativesdk`` ones, whenever possible. This avoids having to maintain multiple |
| 258 | recipe files at the same time. |
Andrew Geissler | 220dafd | 2023-10-04 10:18:08 -0500 | [diff] [blame] | 259 | |
| 260 | - Recipes should have tasks which are idempotent, i.e. that executing a given task |
| 261 | multiple times shouldn't change the end result. The build environment is built upon |
| 262 | this assumption and breaking it can cause obscure build failures. |
| 263 | |
| 264 | - For idempotence when modifying files in tasks, it is usually best to: |
| 265 | |
| 266 | - copy a file ``X`` to ``X.orig`` (only if it doesn't exist already) |
| 267 | - then, copy ``X.orig`` back to ``X``, |
| 268 | - and, finally, modify ``X``. |
| 269 | |
| 270 | This ensures if rerun the task always has the same end result and the |
| 271 | original file can be preserved to reuse. It also guards against an |
| 272 | interrupted build corrupting the file. |
| 273 | |
| 274 | Patch Upstream Status |
| 275 | ===================== |
| 276 | |
| 277 | In order to keep track of patches applied by recipes and ultimately reduce the |
| 278 | number of patches that need maintaining, the OpenEmbedded build system |
| 279 | requires information about the upstream status of each patch. |
| 280 | |
| 281 | In its description, each patch should provide detailed information about the |
| 282 | bug that it addresses, such as the URL in a bug tracking system and links |
| 283 | to relevant mailing list archives. |
| 284 | |
| 285 | Then, you should also add an ``Upstream-Status:`` tag containing one of the |
| 286 | following status strings: |
| 287 | |
| 288 | ``Pending`` |
| 289 | No determination has been made yet, or patch has not yet been submitted to |
| 290 | upstream. |
| 291 | |
| 292 | Keep in mind that every patch submitted upstream reduces the maintainance |
| 293 | burden in OpenEmbedded and Yocto Project in the long run, so this patch |
| 294 | status should only be used in exceptional cases if there are genuine |
| 295 | obstacles to submitting a patch upstream; the reason for that should be |
| 296 | included in the patch. |
| 297 | |
| 298 | ``Submitted [where]`` |
| 299 | Submitted to upstream, waiting for approval. Optionally include where |
| 300 | it was submitted, such as the author, mailing list, etc. |
| 301 | |
| 302 | ``Backport [version]`` |
| 303 | Accepted upstream and included in the next release, or backported from newer |
| 304 | upstream version, because we are at a fixed version. |
| 305 | Include upstream version info (e.g. commit ID or next expected version). |
| 306 | |
| 307 | ``Denied`` |
| 308 | Not accepted by upstream, include reason in patch. |
| 309 | |
| 310 | ``Inactive-Upstream [lastcommit: when (and/or) lastrelease: when]`` |
| 311 | The upstream is no longer available. This typically means a defunct project |
| 312 | where no activity has happened for a long time --- measured in years. To make |
| 313 | that judgement, it is recommended to look at not only when the last release |
| 314 | happened, but also when the last commit happened, and whether newly made bug |
| 315 | reports and merge requests since that time receive no reaction. It is also |
| 316 | recommended to add to the patch description any relevant links where the |
| 317 | inactivity can be clearly seen. |
| 318 | |
| 319 | ``Inappropriate [reason]`` |
| 320 | The patch is not appropriate for upstream, include a brief reason on the |
| 321 | same line enclosed with ``[]``. In the past, there were several different |
| 322 | reasons not to submit patches upstream, but we have to consider that every |
| 323 | non-upstreamed patch means a maintainance burden for recipe maintainers. |
| 324 | Currently, the only reasons to mark patches as inappropriate for upstream |
| 325 | submission are: |
| 326 | |
| 327 | - ``oe specific``: the issue is specific to how OpenEmbedded performs builds |
| 328 | or sets things up at runtime, and can be resolved only with a patch that |
| 329 | is not however relevant or appropriate for general upstream submission. |
| 330 | - ``upstream ticket <link>``: the issue is not specific to Open-Embedded |
| 331 | and should be fixed upstream, but the patch in its current form is not |
| 332 | suitable for merging upstream, and the author lacks sufficient expertise |
| 333 | to develop a proper patch. Instead the issue is handled via a bug report |
| 334 | (include link). |
| 335 | |
| 336 | Of course, if another person later takes care of submitting this patch upstream, |
| 337 | the status should be changed to ``Submitted [where]``, and an additional |
| 338 | ``Signed-off-by:`` line should be added to the patch by the person claiming |
| 339 | responsibility for upstreaming. |
| 340 | |
| 341 | Examples |
| 342 | -------- |
| 343 | |
| 344 | Here's an example of a patch that has been submitted upstream:: |
| 345 | |
| 346 | rpm: Adjusted the foo setting in bar |
| 347 | |
| 348 | [RPM Ticket #65] -- http://rpm5.org/cvs/tktview?tn=65,5 |
| 349 | |
| 350 | The foo setting in bar was decreased from X to X-50% in order to |
| 351 | ensure we don't exhaust all system memory with foobar threads. |
| 352 | |
| 353 | Upstream-Status: Submitted [rpm5-devel@rpm5.org] |
| 354 | |
| 355 | Signed-off-by: Joe Developer <joe.developer@example.com> |
| 356 | |
| 357 | A future update can change the value to ``Backport`` or ``Denied`` as |
| 358 | appropriate. |
| 359 | |
| 360 | Another example of a patch that is specific to OpenEmbedded:: |
| 361 | |
| 362 | Do not treat warnings as errors |
| 363 | |
| 364 | There are additional warnings found with musl which are |
| 365 | treated as errors and fails the build, we have more combinations |
| 366 | than upstream supports to handle. |
| 367 | |
| 368 | Upstream-Status: Inappropriate [oe specific] |
| 369 | |
| 370 | Here's a patch that has been backported from an upstream commit:: |
| 371 | |
| 372 | include missing sys/file.h for LOCK_EX |
| 373 | |
| 374 | Upstream-Status: Backport [https://github.com/systemd/systemd/commit/ac8db36cbc26694ee94beecc8dca208ec4b5fd45] |
| 375 | |
| 376 | CVE patches |
| 377 | =========== |
| 378 | |
| 379 | In order to have a better control of vulnerabilities, patches that fix CVEs must |
| 380 | contain a ``CVE:`` tag. This tag list all CVEs fixed by the patch. If more than |
| 381 | one CVE is fixed, separate them using spaces. |
| 382 | |
| 383 | CVE Examples |
| 384 | ------------ |
| 385 | |
| 386 | This should be the header of patch that fixes :cve:`2015-8370` in GRUB2:: |
| 387 | |
| 388 | grub2: Fix CVE-2015-8370 |
| 389 | |
| 390 | [No upstream tracking] -- https://bugzilla.redhat.com/show_bug.cgi?id=1286966 |
| 391 | |
| 392 | Back to 28; Grub2 Authentication |
| 393 | |
| 394 | Two functions suffer from integer underflow fault; the grub_username_get() and grub_password_get()located in |
| 395 | grub-core/normal/auth.c and lib/crypto.c respectively. This can be exploited to obtain a Grub rescue shell. |
| 396 | |
| 397 | Upstream-Status: Backport [http://git.savannah.gnu.org/cgit/grub.git/commit/?id=451d80e52d851432e109771bb8febafca7a5f1f2] |
| 398 | CVE: CVE-2015-8370 |
| 399 | Signed-off-by: Joe Developer <joe.developer@example.com> |