doc: add snippets documentation

Document this new build system feature.

Since its purpose is customizing application builds, the logical place
for the main body of documentation is in a new snippets/ directory in
doc/build/. Create that directory and add its initial documentation.

Like boards and samples, however, we expect people to write
documentation for each snippet within the directory that defines the
snippet itself. Therefore, add a new top-level snippets/ directory and
stub out the documentation needed to document individual snippets as
well.

Add documentation and cross-references in other required places as
well.

Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Marti Bolivar 2023-01-09 15:46:59 -08:00 committed by Carles Cufí
parent 1f9ab85354
commit ee4b134dd6
9 changed files with 314 additions and 0 deletions

1
doc/build/index.rst vendored
View file

@ -11,5 +11,6 @@ Build and Configuration Systems
cmake/index.rst cmake/index.rst
dts/index dts/index
kconfig/index.rst kconfig/index.rst
snippets/index.rst
zephyr_cmake_package.rst zephyr_cmake_package.rst
sysbuild/index.rst sysbuild/index.rst

37
doc/build/snippets/design.rst vendored Normal file
View file

@ -0,0 +1,37 @@
Snippets Design
###############
This page documents design goals for the snippets feature.
Further information can be found in `Issue #51834`_.
.. _Issue #51834: https://github.com/zephyrproject-rtos/zephyr/issues/51834
- **extensible**: for example, it is possible to add board support for an
existing built-in snippet without modifying the zephyr repository
- **composable**: it is possible to use multiple snippets at once, for example
using:
.. code-block:: console
west build -S <snippet1> -S <snippet2> ...
- **able to combine multiple types of configuration**: snippets make it possible
to store multiple different types of build system settings in one place, and
apply them all together
- **specializable**: for example, it is possible to customize a snippet's
behavior for a particular board, or board revision
- **future-proof and backwards-compatible**: arbitrary future changes to the
snippets feature will be possible without breaking backwards compatibility
for older snippets
- **applicable to purely "software" changes**: unlike the shields feature,
snippets do not assume the presence of a "daughterboard", "shield", "hat", or
any other type of external assembly which is connected to the main board
- **DRY** (don't repeat yourself): snippets allow you to skip unnecessary
repetition; for example, you can apply the same board-specific configuration
to boards ``foo`` and ``bar`` by specifying ``/(foo|bar)/`` as a regular
expression for the settings, which will then apply to both boards

25
doc/build/snippets/index.rst vendored Normal file
View file

@ -0,0 +1,25 @@
.. _snippets:
Snippets
########
Snippets are a way to save build system settings in one place, and then use
those settings when you build any Zephyr application. This lets you save common
configuration separately when it applies to multiple different applications.
Some example use cases for snippets are:
- changing your board's console backend from a "real" UART to a USB CDC-ACM UART
- enabling frequently-used debugging options
- applying interrelated configuration settings to your "main" CPU and a
co-processor core on an AMP SoC
The following pages document this feature.
.. toctree::
:maxdepth: 1
using.rst
/snippets/index.rst
writing.rst
design.rst

39
doc/build/snippets/using.rst vendored Normal file
View file

@ -0,0 +1,39 @@
.. _using-snippets:
Using Snippets
##############
.. tip::
See :ref:`built-in-snippets` for a list of snippets that are provided by
Zephyr.
Snippets have names. You use snippets by giving their names to the build
system.
With west build
***************
To use a snippet named ``foo`` when building an application ``app``:
.. code-block:: console
west build -S foo app
To use multiple snippets:
.. code-block:: console
west build -S snippet1 -S snippet2 [...] app
With cmake
**********
If you are running CMake directly instead of using ``west build``, use the
``SNIPPET`` variable. This is a whitespace- or semicolon-separated list of
snippet names you want to use. For example:
.. code-block:: console
cmake -Sapp -Bbuild -DSNIPPET="snippet1;snippet2" [...]
cmake --build build

188
doc/build/snippets/writing.rst vendored Normal file
View file

@ -0,0 +1,188 @@
Writing Snippets
################
.. contents::
:local:
Basics
******
Snippets are defined using YAML files named :file:`snippet.yml`.
A :file:`snippet.yml` file contains the name of the snippet, along with
additional build system settings, like this:
.. code-block:: yaml
name: snippet-name
# ... build system settings go here ...
Build system settings go in other keys in the file as described later on in
this page.
You can combine settings whenever they appear under the same keys. For example,
you can combine a snippet-specific devicetree overlay and a ``.conf`` file like
this:
.. code-block:: yaml
name: foo
append:
DTC_OVERLAY_FILE: foo.overlay
OVERLAY_CONFIG: foo.conf
Namespacing
***********
When writing devicetree overlays in a snippet, use ``snippet_<name>`` or
``snippet-<name>`` as a namespace prefix when choosing names for node labels,
node names, etc. This avoids namespace conflicts.
For example, if your snippet is named ``foo-bar``, write your devicetree
overlays like this:
.. code-block:: DTS
chosen {
zephyr,baz = &snippet_foo_bar_dev;
};
snippet_foo_bar_dev: device@12345678 {
/* ... */
};
Where snippets are located
**************************
The build system looks for snippets in these places:
#. In directories configured by the :makevar:`SNIPPET_ROOT` CMake variable.
This always includes the zephyr repository (so
:zephyr_file:`zephyr/snippets` is always a source of snippets) and the
application source directory (so :file:`<app>/snippets` is also).
Additional directories can be added manually at CMake time.
The variable is a whitespace- or semicolon-separated list of directories
which may contain snippet definitions.
For each directory in the list, the build system looks for
:file:`snippet.yml` files underneath a subdirectory named :file:`snippets/`,
if one exists.
For example, if :makevar:`SNIPPET_ROOT` is set to ``/foo;/bar``, the build
system will look for :file:`snippet.yml` files underneath the following
subdirectories:
- :file:`/foo/snippets/`
- :file:`/bar/snippets/`
The :file:`snippet.yml` files can be nested anywhere underneath these
locations.
#. In any :ref:`module <modules>` whose :file:`module.yml` file provides a
``snippet_root`` setting.
For example, in a zephyr module named ``baz``, you can add this to your
:file:`module.yml` file:
.. code-block:: yaml
settings:
snippet_root: .
And then any :file:`snippet.yml` files in ``baz/snippets`` will
automatically be discovered by the build system, just as if
the path to ``baz`` had appeared in :makevar:`SNIPPET_ROOT`.
Processing order
****************
The order that snippets are processed is currently not defined.
Therefore, you should write your :file:`snippet.yml` file so that
it is not dependent on other snippets.
.. _snippets-devicetree-overlays:
Devicetree overlays (``.overlay``)
**********************************
This :file:`snippet.yml` adds :file:`foo.overlay` to the build:
.. code-block:: yaml
name: foo
append:
DTC_OVERLAY_FILE: foo.overlay
The path to :file:`foo.overlay` is relative to the directory containing
:file:`snippet.yml`.
.. _snippets-conf-files:
``.conf`` files
***************
This :file:`snippet.yml` adds :file:`foo.conf` to the build:
.. code-block:: yaml
name: foo
append:
OVERLAY_CONFIG: foo.conf
The path to :file:`foo.conf` is relative to the directory containing
:file:`snippet.yml`.
Board-specific settings
***********************
You can write settings that only apply to some boards.
The settings described here are applied in **addition** to snippet settings
that apply to all boards. (This is similar, for example, to the way that an
application with both :file:`prj.conf` and :file:`boards/foo.conf` files will
use both ``.conf`` files in the build when building for board ``foo``, instead
of just :file:`boards/foo.conf`)
By name
=======
.. code-block:: yaml
name: ...
boards:
bar: # settings for board "bar" go here
append:
DTC_OVERLAY_FILE: bar.overlay
baz: # settings for board "baz" go here
append:
DTC_OVERLAY_FILE: baz.overlay
The above example uses :file:`bar.overlay` when building for board ``bar``, and
:file:`baz.overlay` when building for ``baz``.
By regular expression
=====================
You can enclose the board name in slashes (``/``) to match the name against a
regular expression in the `CMake syntax`_. The regular expression must match
the entire board name.
.. _CMake syntax:
https://cmake.org/cmake/help/latest/command/string.html#regex-specification
For example:
.. code-block:: yaml
name: foo
boards:
/my_vendor_.*/:
append:
DTC_OVERLAY_FILE: my_vendor.overlay
The above example uses devicetree overlay :file:`my_vendor.overlay` when
building for either board ``my_vendor_board1`` or ``my_vendor_board2``. It
would not use the overlay when building for either ``another_vendor_board`` or
``x_my_vendor_board``.

View file

@ -269,6 +269,7 @@ vcs_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr/blob/{vcs_lin
vcs_link_prefixes = { vcs_link_prefixes = {
"samples/.*": "", "samples/.*": "",
"boards/.*": "", "boards/.*": "",
"snippets/.*": "",
".*": "doc", ".*": "doc",
} }
vcs_link_exclude = [ vcs_link_exclude = [
@ -290,6 +291,8 @@ external_content_contents = [
(ZEPHYR_BASE, "boards/**/doc"), (ZEPHYR_BASE, "boards/**/doc"),
(ZEPHYR_BASE, "samples/**/*.rst"), (ZEPHYR_BASE, "samples/**/*.rst"),
(ZEPHYR_BASE, "samples/**/doc"), (ZEPHYR_BASE, "samples/**/doc"),
(ZEPHYR_BASE, "snippets/**/*.rst"),
(ZEPHYR_BASE, "snippets/**/doc"),
] ]
external_content_keep = [ external_content_keep = [
"reference/kconfig/*", "reference/kconfig/*",

View file

@ -850,6 +850,12 @@ Build settings supported in the :file:`module.yml` file are:
- ``dts_root``: Contains additional dts files related to the architecture/soc - ``dts_root``: Contains additional dts files related to the architecture/soc
families. Additional dts files must be located in a :file:`<dts_root>/dts` families. Additional dts files must be located in a :file:`<dts_root>/dts`
folder. folder.
- ``snippet_root``: Contains additional snippets that are available for use.
These snippets must be defined in :file:`snippet.yml` files underneath the
:file:`<snippet_root>/snippets` folder. For example, if you have
``snippet_root: foo``, then you should place your module's
:file:`snippet.yml` files in :file:`<your-module>/foo/snippets` or any
nested subdirectory.
- ``soc_root``: Contains additional SoCs that are available to the build - ``soc_root``: Contains additional SoCs that are available to the build
system. Additional SoCs must be located in a :file:`<soc_root>/soc` folder. system. Additional SoCs must be located in a :file:`<soc_root>/soc` folder.
- ``arch_root``: Contains additional architectures that are available to the - ``arch_root``: Contains additional architectures that are available to the

View file

@ -350,6 +350,11 @@ build the specific target for the target, for example::
west build --sysbuild --domain hello_world --target help west build --sysbuild --domain hello_world --target help
Use a snippet
-------------
See :ref:`using-snippets`.
.. _west-building-config: .. _west-building-config:
Configuration Options Configuration Options

10
snippets/index.rst Normal file
View file

@ -0,0 +1,10 @@
.. _built-in-snippets:
Built-in snippets
#################
.. toctree::
:maxdepth: 1
:glob:
**/*