1.. SPDX-License-Identifier: CC-BY-SA-2.0-UK 2 3Recipe Style Guide 4****************** 5 6Recipe Naming Conventions 7========================= 8 9In general, most recipes should follow the naming convention 10``recipes-category/recipename/recipename_version.bb``. Recipes for related 11projects may share the same recipe directory. ``recipename`` and ``category`` 12may contain hyphens, but hyphens are not allowed in ``version``. 13 14If the recipe is tracking a Git revision that does not correspond to a released 15version of the software, ``version`` may be ``git`` (e.g. ``recipename_git.bb``) 16and the recipe would set :term:`PV`. 17 18Version Policy 19============== 20 21Our versions follow the form ``<epoch>:<version>-<revision>`` 22or in BitBake variable terms ${:term:`PE`}:${:term:`PV`}-${:term:`PR`}. We 23generally follow the `Debian <https://www.debian.org/doc/debian-policy/ch-controlfields.html#version>`__ 24version policy which defines these terms. 25 26In most cases the version :term:`PV` will be set automatically from the recipe 27file name. It is recommended to use released versions of software as these are 28revisions that upstream are expecting people to use. 29 30Recipe versions should always compare and sort correctly so that upgrades work 31as expected. With conventional versions such as ``1.4`` upgrading ``to 1.5`` 32this 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 36Instead the tilde (``~``) operator can be used, which sorts before the empty 37string so ``1.5~rc2`` comes before ``1.5``. There is a historical syntax which 38may 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 40syntax but the tilde form is preferred. 41 42For version comparisons, the ``opkg-compare-versions`` program from 43``opkg-utils`` can be useful when attempting to determine how two version 44numbers compare to each other. Our definitive version comparison algorithm is 45the one within bitbake which aims to match those of the package managers and 46Debian policy closely. 47 48When a recipe references a git revision that does not correspond to a released 49version of software (e.g. is not a tagged version), the :term:`PV` variable 50should include the Git revision using the following to make the 51version clear:: 52 53 PV = "<version>+git${SRCPV}" 54 55In this case, ``<version>`` should be the most recently released version of the 56software from the current source revision (``git describe`` can be useful for 57determining this). Whilst not recommended for published layers, this format is 58also useful when using :term:`AUTOREV` to set the recipe to increment source 59control revisions automatically, which can be useful during local development. 60 61Version Number Changes 62====================== 63 64The :term:`PR` variable is used to indicate different revisions of a recipe 65that reference the same upstream source version. It can be used to force a 66new version of a recipe to be installed onto a device from a package feed. 67These once had to be set manually but in most cases these can now be set and 68incremented automatically by a PR Server connected with a package feed. 69 70When :term:`PV` increases, any existing :term:`PR` value can and should be 71removed. 72 73If :term:`PV` changes in such a way that it does not increase with respect to 74the previous value, you need to increase :term:`PE` to ensure package managers 75will upgrade it correctly. If unset you should set :term:`PE` to "1" since 76the default of empty is easily confused with "0" depending on the package 77manager. :term:`PE` can only have an integer value. 78 79Recipe formatting 80================= 81 82Variable 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 110Python Function formatting 111-------------------------- 112 113- Spaces must be used for indenting Python code, with 4 spaces per tab 114 115Shell Function formatting 116------------------------- 117 118- The formatting of shell functions should be consistent within layers. 119 Some use tabs, some use spaces. 120 121Recipe metadata 122=============== 123 124Required Variables 125------------------ 126 127The 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 140Recipe Ordering 141--------------- 142 143When a variable is defined in recipes and classes, variables should follow the 144general 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 173There are some cases where ordering is important and these cases would override 174this default order. Examples include: 175 176- :term:`PACKAGE_ARCH` needing to be set before ``inherit packagegroup`` 177 178Tasks should be ordered based on the order they generally execute. For commonly 179used 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 191Custom tasks should be sorted similarly. 192 193Package 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 201Recipe License Fields 202--------------------- 203 204Recipes 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 253License Updates 254~~~~~~~~~~~~~~~ 255 256When you change the :term:`LICENSE` or :term:`LIC_FILES_CHKSUM` in the recipe 257you need to briefly explain the reason for the change via a ``License-Update:`` 258tag. Often it's quite trivial, such as:: 259 260 License-Update: copyright years refreshed 261 262Less often, the actual licensing terms themselves will have changed. If so, do 263try to link to upstream making/justifying that decision. 264 265Tips and Guidelines for Writing Recipes 266--------------------------------------- 267 268- Use :term:`BBCLASSEXTEND` instead of creating separate recipes such as ``-native`` 269 and ``-nativesdk`` ones, whenever possible. This avoids having to maintain multiple 270 recipe files at the same time. 271 272- Recipes should have tasks which are idempotent, i.e. that executing a given task 273 multiple times shouldn't change the end result. The build environment is built upon 274 this assumption and breaking it can cause obscure build failures. 275 276- For idempotence when modifying files in tasks, it is usually best to: 277 278 - copy a file ``X`` to ``X.orig`` (only if it doesn't exist already) 279 - then, copy ``X.orig`` back to ``X``, 280 - and, finally, modify ``X``. 281 282 This ensures if rerun the task always has the same end result and the 283 original file can be preserved to reuse. It also guards against an 284 interrupted build corrupting the file. 285 286Patch Upstream Status 287===================== 288 289In order to keep track of patches applied by recipes and ultimately reduce the 290number of patches that need maintaining, the OpenEmbedded build system 291requires information about the upstream status of each patch. 292 293In its description, each patch should provide detailed information about the 294bug that it addresses, such as the URL in a bug tracking system and links 295to relevant mailing list archives. 296 297Then, you should also add an ``Upstream-Status:`` tag containing one of the 298following status strings: 299 300``Pending`` 301 No determination has been made yet, or patch has not yet been submitted to 302 upstream. 303 304 Keep in mind that every patch submitted upstream reduces the maintainance 305 burden in OpenEmbedded and Yocto Project in the long run, so this patch 306 status should only be used in exceptional cases if there are genuine 307 obstacles to submitting a patch upstream; the reason for that should be 308 included in the patch. 309 310``Submitted [where]`` 311 Submitted to upstream, waiting for approval. Optionally include where 312 it was submitted, such as the author, mailing list, etc. 313 314``Backport [version]`` 315 Accepted upstream and included in the next release, or backported from newer 316 upstream version, because we are at a fixed version. 317 Include upstream version info (e.g. commit ID or next expected version). 318 319``Denied`` 320 Not accepted by upstream, include reason in patch. 321 322``Inactive-Upstream [lastcommit: when (and/or) lastrelease: when]`` 323 The upstream is no longer available. This typically means a defunct project 324 where no activity has happened for a long time --- measured in years. To make 325 that judgement, it is recommended to look at not only when the last release 326 happened, but also when the last commit happened, and whether newly made bug 327 reports and merge requests since that time receive no reaction. It is also 328 recommended to add to the patch description any relevant links where the 329 inactivity can be clearly seen. 330 331``Inappropriate [reason]`` 332 The patch is not appropriate for upstream, include a brief reason on the 333 same line enclosed with ``[]``. In the past, there were several different 334 reasons not to submit patches upstream, but we have to consider that every 335 non-upstreamed patch means a maintainance burden for recipe maintainers. 336 Currently, the only reasons to mark patches as inappropriate for upstream 337 submission are: 338 339 - ``oe specific``: the issue is specific to how OpenEmbedded performs builds 340 or sets things up at runtime, and can be resolved only with a patch that 341 is not however relevant or appropriate for general upstream submission. 342 - ``upstream ticket <link>``: the issue is not specific to Open-Embedded 343 and should be fixed upstream, but the patch in its current form is not 344 suitable for merging upstream, and the author lacks sufficient expertise 345 to develop a proper patch. Instead the issue is handled via a bug report 346 (include link). 347 348Of course, if another person later takes care of submitting this patch upstream, 349the status should be changed to ``Submitted [where]``, and an additional 350``Signed-off-by:`` line should be added to the patch by the person claiming 351responsibility for upstreaming. 352 353Examples 354-------- 355 356Here's an example of a patch that has been submitted upstream:: 357 358 rpm: Adjusted the foo setting in bar 359 360 [RPM Ticket #65] -- http://rpm5.org/cvs/tktview?tn=65,5 361 362 The foo setting in bar was decreased from X to X-50% in order to 363 ensure we don't exhaust all system memory with foobar threads. 364 365 Upstream-Status: Submitted [rpm5-devel@rpm5.org] 366 367 Signed-off-by: Joe Developer <joe.developer@example.com> 368 369A future update can change the value to ``Backport`` or ``Denied`` as 370appropriate. 371 372Another example of a patch that is specific to OpenEmbedded:: 373 374 Do not treat warnings as errors 375 376 There are additional warnings found with musl which are 377 treated as errors and fails the build, we have more combinations 378 than upstream supports to handle. 379 380 Upstream-Status: Inappropriate [oe specific] 381 382Here's a patch that has been backported from an upstream commit:: 383 384 include missing sys/file.h for LOCK_EX 385 386 Upstream-Status: Backport [https://github.com/systemd/systemd/commit/ac8db36cbc26694ee94beecc8dca208ec4b5fd45] 387 388CVE patches 389=========== 390 391In order to have a better control of vulnerabilities, patches that fix CVEs must 392contain a ``CVE:`` tag. This tag list all CVEs fixed by the patch. If more than 393one CVE is fixed, separate them using spaces. 394 395CVE Examples 396------------ 397 398This should be the header of patch that fixes :cve:`2015-8370` in GRUB2:: 399 400 grub2: Fix CVE-2015-8370 401 402 [No upstream tracking] -- https://bugzilla.redhat.com/show_bug.cgi?id=1286966 403 404 Back to 28; Grub2 Authentication 405 406 Two functions suffer from integer underflow fault; the grub_username_get() and grub_password_get()located in 407 grub-core/normal/auth.c and lib/crypto.c respectively. This can be exploited to obtain a Grub rescue shell. 408 409 Upstream-Status: Backport [http://git.savannah.gnu.org/cgit/grub.git/commit/?id=451d80e52d851432e109771bb8febafca7a5f1f2] 410 CVE: CVE-2015-8370 411 Signed-off-by: Joe Developer <joe.developer@example.com> 412