diff mbox series

[3/3] contributor-guide: add recipe style guide

Message ID 20230809142520.226581-3-michael.opdenacker@bootlin.com
State New
Headers show
Series [1/3] contributor-guide: add missing links to mailing lists | expand

Commit Message

Michael Opdenacker Aug. 9, 2023, 2:25 p.m. UTC
From: Michael Opdenacker <michael.opdenacker@bootlin.com>

Signed-off-by: Michael Opdenacker <michael.opdenacker@bootlin.com>
---
 documentation/contributor-guide/index.rst     |   1 +
 .../contributor-guide/recipe-style-guide.rst  | 263 ++++++++++++++++++
 documentation/dev-manual/new-recipe.rst       |  54 +---
 3 files changed, 268 insertions(+), 50 deletions(-)
 create mode 100644 documentation/contributor-guide/recipe-style-guide.rst
diff mbox series

Patch

diff --git a/documentation/contributor-guide/index.rst b/documentation/contributor-guide/index.rst
index d723854843..7a39f994e2 100644
--- a/documentation/contributor-guide/index.rst
+++ b/documentation/contributor-guide/index.rst
@@ -20,6 +20,7 @@  this.
 
    identify-component
    submit-defect
+   recipe-style-guide
    submit-change
 
 .. include:: /boilerplate.rst
diff --git a/documentation/contributor-guide/recipe-style-guide.rst b/documentation/contributor-guide/recipe-style-guide.rst
new file mode 100644
index 0000000000..5210062802
--- /dev/null
+++ b/documentation/contributor-guide/recipe-style-guide.rst
@@ -0,0 +1,263 @@ 
+.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
+
+Recipe Style Guide
+******************
+
+Recipe Naming Conventions
+=========================
+
+In general, most recipes should follow the naming convention
+``recipes-category/package/packagename_version.bb``. Recipes for related
+projects may share the same package directory. ``packagename``, ``category``,
+and ``package`` may contain hyphens, but hyphens are not allowed in ``version``.
+
+If the recipe is tracking a Git revision that does not correspond to a released
+version of the software, ``version`` may be ``git`` (e.g. ``packagename_git.bb``)
+
+Version Policy
+==============
+
+Our versions follow the form ``<package epoch>:<package version>-<package revision>``
+or in BitBake variable terms ${:term:`PE`}:${:term:`PV`}-${:term:`PR`}. We
+generally follow the `Debian <https://www.debian.org/doc/debian-policy/ch-controlfields.html#version>`__
+version policy which defines these terms.
+
+In most cases the version :term:`PV` will be set automatically from the recipe
+file name. It is recommended to use released versions of software as these are
+revisions that upstream are expecting people to use.
+
+Package versions should always compare and sort correctly so that upgrades work
+as expected. With conventional versions such as ``1.4`` upgrading ``to 1.5``
+this happens naturally, but some versions don't sort. For example,
+``1.5 Release Candidate 2`` could be written as ``1.5rc2`` but this sorts after
+``1.5``, so upgrades from feeds won't happen correctly.
+
+Instead the tilde (``~``) operator can be used, which sorts before the empty
+string so ``1.5~rc2`` comes before ``1.5``. There is a historical syntax which
+may be found where :term:`PV` is set as a combination of the prior version
+``+`` the pre-release version, for example ``PV=1.4+1.5rc2``. This is a valid
+syntax but the tilde form is preferred.
+
+For version comparisons, the ``opkg-compare-versions`` program from
+``opkg-utils`` can be useful when attempting to determine how two version
+numbers compare to each other. Our definitive version comparison algorithm is
+the one within bitbake which aims to match those of the package managers and
+Debian policy closely.
+
+When a recipe references a git revision that does not correspond to a released
+version of software (e.g. is not a tagged version), the :term:`PV` variable
+should include the Git revision using the following to make the
+version clear::
+
+    PV = "<version>+git${SRCPV}"
+
+In this case, ``<version>`` should be the most recently released version of the
+software from the current source revision (``git describe`` can be useful for
+determining this). Whilst not recommended for published layers, this format is
+also useful when using :term:`AUTOREV` to set the recipe to increment source
+control revisions automatically, which can be useful during local development.
+
+Version Number Changes
+======================
+
+The :term:`PR` variable is used to indicate different revisions of a recipe
+that reference the same upstream source version. It can be used to force a
+new version of a package to be installed onto a device from a package feed.
+These once had to be set manually but in most cases these can now be set and
+incremented automatically by a PR Server connected with a package feed.
+
+When :term:`PV` increases, any existing :term:`PR` value can and should be
+removed.
+
+If :term:`PV` changes in such a way that it does not increase with respect to
+the previous value, you need to increase :term:`PE` to ensure package managers
+will upgrade it correctly. If unset you should set :term:`PE` to "1" since
+the default of empty is easily confused with "0" depending on the package
+manager. :term:`PE` can only have an integer value.
+
+Recipe formatting
+=================
+
+Variable Formatting
+-------------------
+
+-  Variable assignment should a space around each side of the operator, e.g.
+   ``FOO = "bar"``, not ``FOO="bar"``.
+
+-  Double quotes should be used on the right-hand side of the assignment,
+   e.g. ``FOO = "bar"`` not ``FOO = 'bar'``
+
+-  Spaces should be used for indenting variables, with 4 spaces per tab
+
+-  Long variables should be split over multiple lines when possible by using
+   the continuation character (``\``)
+
+-  When splitting a long variable over multiple lines, all continuation lines
+   should be indented (with spaces) to align with the start of the quote on the
+   first line::
+
+       FOO = "this line is \
+              long \
+              "
+
+   Instead of::
+
+       FOO = "this line is \
+       long \
+       "
+
+Python Function formatting
+--------------------------
+
+-  Spaces must be used for indenting Python code, with 4 spaces per tab
+
+Shell Function formatting
+-------------------------
+
+-  The formatting of shell functions should be consistent within layers.
+   Some use tabs, some use spaces.
+
+Recipe metadata
+===============
+
+Required Variables
+------------------
+
+The following variables should be included in all recipes:
+
+-  :term:`SUMMARY`: a one line description of the upstream project
+
+-  :term:`DESCRIPTION`: an extended description of the upstream project,
+   possibly with multiple lines. If no reasonable description can be written,
+   this may be omitted as it defaults to :term:`SUMMARY`.
+
+-  :term:`HOMEPAGE`: the URL to the upstream projects homepage.
+
+-  :term:`BUGTRACKER`: the URL upstream projects bug tracking website,
+   if applicable.
+
+Recipe Ordering
+---------------
+
+When a variable is defined in recipes and classes, variables should follow the
+general order when possible:
+
+-  :term:`SUMMARY`
+-  :term:`DESCRIPTION`
+-  :term:`AUTHOR`
+-  :term:`HOMEPAGE`
+-  :term:`BUGTRACKER`
+-  :term:`SECTION`
+-  :term:`LICENSE`
+-  :term:`LIC_FILES_CHKSUM`
+-  :term:`DEPENDS`
+-  :term:`PROVIDES`
+-  :term:`PV`
+-  :term:`SRC_URI`
+-  :term:`SRCREV`
+-  :term:`S`
+-  ``inherit ...``
+-  :term:`PACKAGECONFIG`
+-  Build class specific variables such as ``EXTRA_QMAKEVARS_POST`` and :term:`EXTRA_OECONF`
+-  Tasks such as :ref:`ref-tasks-configure`
+-  :term:`PACKAGE_ARCH`
+-  :term:`PACKAGES`
+-  :term:`FILES`
+-  :term:`RDEPENDS`
+-  :term:`RRECOMMENDS`
+-  :term:`RSUGGESTS`
+-  :term:`RPROVIDES`
+-  :term:`RCONFLICTS`
+-  :term:`BBCLASSEXTEND`
+
+There are some cases where ordering is important and these cases would override
+this default order. Examples include:
+
+-  :term:`PACKAGE_ARCH` needing to be set before ``inherit packagegroup``
+
+Tasks should be ordered based on the order they generally execute. For commonly
+used tasks this would be:
+
+-  :ref:`ref-tasks-fetch`
+-  :ref:`ref-tasks-unpack`
+-  :ref:`ref-tasks-patch`
+-  :ref:`ref-tasks-prepare_recipe_sysroot`
+-  :ref:`ref-tasks-configure`
+-  :ref:`ref-tasks-compile`
+-  :ref:`ref-tasks-install`
+-  :ref:`ref-tasks-populate_sysroot`
+-  :ref:`ref-tasks-package`
+
+Custom tasks should be sorted similarly.
+
+Package specific variables are typically grouped together, e.g.::
+
+    RDEPENDS:${PN} = “foo”
+    RDEPENDS:${PN}-libs = “bar”
+
+    RRECOMMENDS:${PN} = “one”
+    RRECOMMENDS:${PN}-libs = “two”
+
+Recipe License Fields
+---------------------
+
+Recipes need to define 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 = "GPL-2.0-only"
+
+   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/licenses: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/new-recipe: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.
+
+Tips and Guidelines for Writing Recipes
+---------------------------------------
+
+-  Use :term:`BBCLASSEXTEND` instead of creating separate recipes such as ``-native``
+   and ``-nativesdk`` ones, whenever possible. This avoids having to maintain multiple
+   recipe files at the same time.
+
+-  Avoid manually mangling ``pkg-config`` ``.pc`` files.
+   Recipes using ``pkg-config`` should use variables to ensure they are correctly
+   relocatable and not need manual path correction in the recipe.
+
diff --git a/documentation/dev-manual/new-recipe.rst b/documentation/dev-manual/new-recipe.rst
index af390773a9..cb9533ff5d 100644
--- a/documentation/dev-manual/new-recipe.rst
+++ b/documentation/dev-manual/new-recipe.rst
@@ -432,56 +432,10 @@  named the same as the base name of the recipe
 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 = "GPL-2.0-only"
-
-   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/licenses: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/new-recipe: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.
+Your recipe needs to define variables related to the license
+under whith the software is distributed. See the
+:ref:`contributor-guide/recipe-style-guide:recipe license fields`
+section in the Contributor Guide for details.
 
 Dependencies
 ============