1.. _modules: 2 3Modules (External projects) 4############################ 5 6Zephyr relies on the source code of several externally maintained projects in 7order to avoid reinventing the wheel and to reuse as much well-established, 8mature code as possible when it makes sense. In the context of Zephyr's build 9system those are called *modules*. These modules must be integrated with the 10Zephyr build system, as described in more detail in other sections on 11this page. 12 13To be classified as a candidate for being included in the default list of 14modules, an external project is required to have its own life-cycle outside 15the Zephyr Project, that is, reside in its own repository, and have its own 16contribution and maintenance workflow and release process. Zephyr modules 17should not contain code that is written exclusively for Zephyr. Instead, 18such code should be contributed to the main zephyr tree. 19 20Modules to be included in the default manifest of the Zephyr project need to 21provide functionality or features endorsed and approved by the project Technical 22Steering Committee and should comply with the 23:ref:`module licensing requirements<modules_licensing>` and 24:ref:`contribution guidelines<modules_contributing>`. They should also have a 25Zephyr developer that is committed to maintain the module codebase. 26 27Zephyr depends on several categories of modules, including but not limited to: 28 29- Debugger integration 30- Silicon vendor Hardware Abstraction Layers (HALs) 31- Cryptography libraries 32- File Systems 33- Inter-Process Communication (IPC) libraries 34 35Additionally, in some cases modules (particularly vendor HALs) can contain 36references to optional :ref:`binary blobs <bin-blobs>`. 37 38This page summarizes a list of policies and best practices which aim at 39better organizing the workflow in Zephyr modules. 40 41.. _modules-vs-projects: 42 43Modules vs west projects 44************************ 45 46Zephyr modules, described in this page, are not the same as :ref:`west projects 47<west-workspace>`. In fact, modules :ref:`do not require west 48<modules_without_west>` at all. However, when using modules :ref:`with west 49<modules_using_west>`, then the build system uses west in order to find modules. 50 51In summary: 52 53Modules are repositories that contain a :file:`zephyr/module.yml` file, so that 54the Zephyr build system can pull in the source code from the repository. 55:ref:`West projects <west-manifests-projects>` are entries in the ``projects:`` 56section in the :file:`west.yml` manifest file. 57West projects are often also modules, but not always. There are west projects 58that are not included in the final firmware image (eg. tools) and thus do not 59need to be modules. 60Modules are found by the Zephyr build system either via :ref:`west itself 61<modules_using_west>`, or via the :ref:`ZEPHYR_MODULES CMake variable 62<modules_without_west>`. 63 64The contents of this page only apply to modules, and not to west projects in 65general (unless they are a module themselves). 66 67Module Repositories 68******************* 69 70* All modules included in the default manifest shall be hosted in repositories 71 under the zephyrproject-rtos GitHub organization. 72 73* The module repository codebase shall include a *module.yml* file in a 74 :file:`zephyr/` folder at the root of the repository. 75 76* Module repository names should follow the convention of using lowercase 77 letters and dashes instead of underscores. This rule will apply to all 78 new module repositories, except for repositories that are directly 79 tracking external projects (hosted in Git repositories); such modules 80 may be named as their external project counterparts. 81 82 .. note:: 83 84 Existing module repositories that do not conform to the above convention 85 do not need to be renamed to comply with the above convention. 86 87* Module repositories names should be explicitly set in the :file:`zephyr/module.yml` file. 88 89* Modules should use "zephyr" as the default name for the repository main 90 branch. Branches for specific purposes, for example, a module branch for 91 an LTS Zephyr version, shall have names starting with the 'zephyr\_' prefix. 92 93* If the module has an external (upstream) project repository, the module 94 repository should preserve the upstream repository folder structure. 95 96 .. note:: 97 98 It is not required in module repositories to maintain a 'master' 99 branch mirroring the master branch of the external repository. It 100 is not recommended as this may generate confusion around the module's 101 main branch, which should be 'zephyr'. 102 103* Modules should expose all provided header files with an include pathname 104 beginning with the module-name. (E.g., mcuboot should expose its 105 ``bootutil/bootutil.h`` as "mcuboot/bootutil/bootutil.h".) 106 107.. _modules_synchronization: 108 109Synchronizing with upstream 110=========================== 111 112It is preferred to synchronize a module repository with the latest stable 113release of the corresponding external project. It is permitted, however, to 114update a Zephyr module repository with the latest development branch tip, 115if this is required to get important updates in the module codebase. When 116synchronizing a module with upstream it is mandatory to document the 117rationale for performing the particular update. 118 119Requirements for allowed practices 120---------------------------------- 121 122Changes to the main branch of a module repository, including synchronization 123with upstream code base, may only be applied via pull requests. These pull 124requests shall be *verifiable* by Zephyr CI and *mergeable* (e.g. with the 125*Rebase and merge*, or *Create a merge commit* option using Github UI). This 126ensures that the incoming changes are always **reviewable**, and the 127*downstream* module repository history is incremental (that is, existing 128commits, tags, etc. are always preserved). This policy also allows to run 129Zephyr CI, git lint, identity, and license checks directly on the set of 130changes that are to be brought into the module repository. 131 132.. note:: 133 134 Force-pushing to a module's main branch is not allowed. 135 136Allowed practices 137----------------- 138 139The following practices conform to the above requirements and should be 140followed in all modules repositories. It is up to the module code owner 141to select the preferred synchronization practice, however, it is required 142that the selected practice is consistently followed in the respective 143module repository. 144 145**Updating modules with a diff from upstream:** 146Upstream changes brought as a single *snapshot* commit (manual diff) in a 147pull request against the module's main branch, which may be merged using 148the *Rebase & merge* operation. This approach is simple and 149should be applicable to all modules with the downside of suppressing the 150upstream history in the module repository. 151 152 .. note:: 153 154 The above practice is the only allowed practice in modules where 155 the external project is not hosted in an upstream Git repository. 156 157The commit message is expected to identify the upstream project URL, the 158version to which the module is updated (upstream version, tag, commit SHA, 159if applicable, etc.), and the reason for the doing the update. 160 161**Updating modules by merging the upstream branch:** 162Upstream changes brought in by performing a Git merge of the intended upstream 163branch (e.g. main branch, latest release branch, etc.) submitting the result in 164pull request against the module main branch, and merging the pull request using 165the *Create a merge commit* operation. 166This approach is applicable to modules with an upstream project Git repository. 167The main advantages of this approach is that the upstream repository history 168(that is, the original commit SHAs) is preserved in the module repository. The 169downside of this approach is that two additional merge commits are generated in 170the downstream main branch. 171 172 173Contributing to Zephyr modules 174****************************** 175 176.. _modules_contributing: 177 178 179Individual Roles & Responsibilities 180=================================== 181 182To facilitate management of Zephyr module repositories, the following 183individual roles are defined. 184 185**Administrator:** Each Zephyr module shall have an administrator 186who is responsible for managing access to the module repository, 187for example, for adding individuals as Collaborators in the repository 188at the request of the module owner. Module administrators are 189members of the Administrators team, that is a group of project 190members with admin rights to module GitHub repositories. 191 192**Module owner:** Each module shall have a module code owner. Module 193owners will have the overall responsibility of the contents of a 194Zephyr module repository. In particular, a module owner will: 195 196* coordinate code reviewing in the module repository 197* be the default assignee in pull-requests against the repository's 198 main branch 199* request additional collaborators to be added to the repository, as 200 they see fit 201* regularly synchronize the module repository with its upstream 202 counterpart following the policies described in 203 :ref:`modules_synchronization` 204* be aware of security vulnerability issues in the external project 205 and update the module repository to include security fixes, as 206 soon as the fixes are available in the upstream code base 207* list any known security vulnerability issues, present in the 208 module codebase, in Zephyr release notes. 209 210 211 .. note:: 212 213 Module owners are not required to be Zephyr 214 :ref:`Maintainers <project_roles>`. 215 216**Merger:** The Zephyr Release Engineering team has the right and the 217responsibility to merge approved pull requests in the main branch of a 218module repository. 219 220 221Maintaining the module codebase 222=============================== 223 224Updates in the zephyr main tree, for example, in public Zephyr APIs, 225may require patching a module's codebase. The responsibility for keeping 226the module codebase up to date is shared between the **contributor** of 227such updates in Zephyr and the module **owner**. In particular: 228 229* the contributor of the original changes in Zephyr is required to submit 230 the corresponding changes that are required in module repositories, to 231 ensure that Zephyr CI on the pull request with the original changes, as 232 well as the module integration testing are successful. 233 234* the module owner has the overall responsibility for synchronizing 235 and testing the module codebase with the zephyr main tree. 236 This includes occasional advanced testing of the module's codebase 237 in addition to the testing performed by Zephyr's CI. 238 The module owner is required to fix issues in the module's codebase that 239 have not been caught by Zephyr pull request CI runs. 240 241 242.. _modules_changes: 243 244Contributing changes to modules 245=============================== 246 247Submitting and merging changes directly to a module's codebase, that is, 248before they have been merged in the corresponding external project 249repository, should be limited to: 250 251* changes required due to updates in the zephyr main tree 252* urgent changes that should not wait to be merged in the external project 253 first, such as fixes to security vulnerabilities. 254 255Non-trivial changes to a module's codebase, including changes in the module 256design or functionality should be discouraged, if the module has an upstream 257project repository. In that case, such changes shall be submitted to the 258upstream project, directly. 259 260:ref:`Submitting changes to modules <submitting_new_modules>` describes in 261detail the process of contributing changes to module repositories. 262 263Contribution guidelines 264----------------------- 265 266Contributing to Zephyr modules shall follow the generic project 267:ref:`Contribution guidelines <contribute_guidelines>`. 268 269**Pull Requests:** may be merged with minimum of 2 approvals, including 270an approval by the PR assignee. In addition to this, pull requests in module 271repositories may only be merged if the introduced changes are verified 272with Zephyr CI tools, as described in more detail in other sections on 273this page. 274 275The merging of pull requests in the main branch of a module 276repository must be coupled with the corresponding manifest 277file update in the zephyr main tree. 278 279**Issue Reporting:** `GitHub issues`_ are intentionally disabled in module 280repositories, in 281favor of a centralized policy for issue reporting. Tickets concerning, for 282example, bugs or enhancements in modules shall be opened in the main 283zephyr repository. Issues should be appropriately labeled using GitHub 284labels corresponding to each module, where applicable. 285 286 .. note:: 287 288 It is allowed to file bug reports for zephyr modules to track 289 the corresponding upstream project bugs in Zephyr. These bug reports 290 shall not affect the 291 :ref:`Release Quality Criteria<release_quality_criteria>`. 292 293 294.. _modules_licensing: 295 296Licensing requirements and policies 297*********************************** 298 299All source files in a module's codebase shall include a license header, 300unless the module repository has **main license file** that covers source 301files that do not include license headers. 302 303Main license files shall be added in the module's codebase by Zephyr 304developers, only if they exist as part of the external project, 305and they contain a permissive OSI-compliant license. Main license files 306should preferably contain the full license text instead of including an 307SPDX license identifier. If multiple main license files are present it 308shall be made clear which license applies to each source file in a module's 309codebase. 310 311Individual license headers in module source files supersede the main license. 312 313Any new content to be added in a module repository will require to have 314license coverage. 315 316 .. note:: 317 318 Zephyr recommends conveying module licensing via individual license 319 headers and main license files. This not a hard requirement; should 320 an external project have its own practice of conveying how licensing 321 applies in the module's codebase (for example, by having a single or 322 multiple main license files), this practice may be accepted by and 323 be referred to in the Zephyr module, as long as licensing requirements, 324 for example OSI compliance, are satisfied. 325 326License policies 327================ 328 329When creating a module repository a developer shall: 330 331* import the main license files, if they exist in the external project, and 332* document (for example in the module README or .yml file) the default license 333 that covers the module's codebase. 334 335License checks 336-------------- 337 338License checks (via CI tools) shall be enabled on every pull request that 339adds new content in module repositories. 340 341 342Documentation requirements 343************************** 344 345All Zephyr module repositories shall include an .rst file documenting: 346 347* the scope and the purpose of the module 348* how the module integrates with Zephyr 349* the owner of the module repository 350* synchronization information with the external project (commit, SHA, version etc.) 351* licensing information as described in :ref:`modules_licensing`. 352 353The file shall be required for the inclusion of the module and the contained 354information should be kept up to date. 355 356 357Testing requirements 358******************** 359 360All Zephyr modules should provide some level of **integration** testing, 361ensuring that the integration with Zephyr works correctly. 362Integration tests: 363 364* may be in the form of a minimal set of samples and tests that reside 365 in the zephyr main tree 366* should verify basic usage of the module (configuration, 367 functional APIs, etc.) that is integrated with Zephyr. 368* shall be built and executed (for example in QEMU) as part of 369 twister runs in pull requests that introduce changes in module 370 repositories. 371 372 .. note:: 373 374 New modules, that are candidates for being included in the Zephyr 375 default manifest, shall provide some level of integration testing. 376 377 .. note:: 378 379 Vendor HALs are implicitly tested via Zephyr tests built or executed 380 on target platforms, so they do not need to provide integration tests. 381 382The purpose of integration testing is not to provide functional verification 383of the module; this should be part of the testing framework of the external 384project. 385 386Certain external projects provide test suites that reside in the upstream 387testing infrastructure but are written explicitly for Zephyr. These tests 388may (but are not required to) be part of the Zephyr test framework. 389 390Deprecating and removing modules 391********************************* 392 393Modules may be deprecated for reasons including, but not limited to: 394 395* Lack of maintainership in the module 396* Licensing changes in the external project 397* Codebase becoming obsolete 398 399The module information shall indicate whether a module is 400deprecated and the build system shall issue a warning 401when trying to build Zephyr using a deprecated module. 402 403Deprecated modules may be removed from the Zephyr default manifest 404after 2 Zephyr releases. 405 406 .. note:: 407 408 Repositories of removed modules shall remain accessible via their 409 original URL, as they are required by older Zephyr versions. 410 411 412Integrate modules in Zephyr build system 413**************************************** 414 415The build system variable :makevar:`ZEPHYR_MODULES` is a `CMake list`_ of 416absolute paths to the directories containing Zephyr modules. These modules 417contain :file:`CMakeLists.txt` and :file:`Kconfig` files describing how to 418build and configure them, respectively. Module :file:`CMakeLists.txt` files are 419added to the build using CMake's `add_subdirectory()`_ command, and the 420:file:`Kconfig` files are included in the build's Kconfig menu tree. 421 422If you have :ref:`west <west>` installed, you don't need to worry about how 423this variable is defined unless you are adding a new module. The build system 424knows how to use west to set :makevar:`ZEPHYR_MODULES`. You can add additional 425modules to this list by setting the :makevar:`EXTRA_ZEPHYR_MODULES` CMake 426variable or by adding a :makevar:`EXTRA_ZEPHYR_MODULES` line to ``.zephyrrc`` 427(See the section on :ref:`env_vars` for more details). This can be useful if you 428want to keep the list of modules found with west and also add your own. If 429:makevar:`EXTRA_ZEPHYR_MODULES` is set in multiple places, for example both as 430an environment variable and as a CMake variable, the final list of additional 431modules will be the merged result of all sources. 432 433.. note:: 434 If the module ``FOO`` is provided by :ref:`west <west>` but also given with 435 ``-DEXTRA_ZEPHYR_MODULES=/<path>/foo`` then the module given by the command 436 line variable :makevar:`EXTRA_ZEPHYR_MODULES` will take precedence. 437 This allows you to use a custom version of ``FOO`` when building and still 438 use other Zephyr modules provided by :ref:`west <west>`. 439 This can for example be useful for special test purposes. 440 441If you want to permanently add modules to the zephyr workspace and you are 442using zephyr as your manifest repository, you can also add a west manifest file 443into the :zephyr_file:`submanifests` directory. See 444:zephyr_file:`submanifests/README.txt` for more details. 445 446See :ref:`west-basics` for more on west workspaces. 447 448Finally, you can also specify the list of modules yourself in various ways, or 449not use modules at all if your application doesn't need them. 450 451.. _module-yml: 452 453Module yaml file description 454**************************** 455 456A module can be described using a file named :file:`zephyr/module.yml`. 457The format of :file:`zephyr/module.yml` is described in the following: 458 459Module name 460=========== 461 462Each Zephyr module is given a name by which it can be referred to in the build 463system. 464 465The name should be specified in the :file:`zephyr/module.yml` file. This will 466ensure the module name is not changeable through user-defined directory names 467or ``west`` manifest files: 468 469.. code-block:: yaml 470 471 name: <name> 472 473In CMake the location of the Zephyr module can then be referred to using the 474CMake variable ``ZEPHYR_<MODULE_NAME>_MODULE_DIR`` and the variable 475``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` holds the location of the directory 476containing the module's :file:`CMakeLists.txt` file. 477 478.. note:: 479 When used for CMake and Kconfig variables, all letters in module names are 480 converted to uppercase and all non-alphanumeric characters are converted 481 to underscores (_). 482 As example, the module ``foo-bar`` must be referred to as 483 ``ZEPHYR_FOO_BAR_MODULE_DIR`` in CMake and Kconfig. 484 485Here is an example for the Zephyr module ``foo``: 486 487.. code-block:: yaml 488 489 name: foo 490 491.. note:: 492 If the ``name`` field is not specified then the Zephyr module name will be 493 set to the name of the module folder. 494 As example, the Zephyr module located in :file:`<workspace>/modules/bar` will 495 use ``bar`` as its module name if nothing is specified in 496 :file:`zephyr/module.yml`. 497 498Module integration files (in-module) 499==================================== 500 501Inclusion of build files, :file:`CMakeLists.txt` and :file:`Kconfig`, can be 502described as: 503 504.. code-block:: yaml 505 506 build: 507 cmake: <cmake-directory> 508 kconfig: <directory>/Kconfig 509 510The ``cmake: <cmake-directory>`` part specifies that 511:file:`<cmake-directory>` contains the :file:`CMakeLists.txt` to use. The 512``kconfig: <directory>/Kconfig`` part specifies the Kconfig file to use. 513Neither is required: ``cmake`` defaults to ``zephyr``, and ``kconfig`` 514defaults to ``zephyr/Kconfig``. 515 516Here is an example :file:`module.yml` file referring to 517:file:`CMakeLists.txt` and :file:`Kconfig` files in the root directory of the 518module: 519 520.. code-block:: yaml 521 522 build: 523 cmake: . 524 kconfig: Kconfig 525 526.. _sysbuild_module_integration: 527 528Sysbuild integration 529==================== 530 531:ref:`Sysbuild<sysbuild>` is the Zephyr build system that allows for building 532multiple images as part of a single application, the sysbuild build process 533can be extended externally with modules as needed, for example to add custom 534build steps or add additional targets to a build. Inclusion of 535sysbuild-specific build files, :file:`CMakeLists.txt` and :file:`Kconfig`, can 536be described as: 537 538.. code-block:: yaml 539 540 build: 541 sysbuild-cmake: <cmake-directory> 542 sysbuild-kconfig: <directory>/Kconfig 543 544The ``sysbuild-cmake: <cmake-directory>`` part specifies that 545:file:`<cmake-directory>` contains the :file:`CMakeLists.txt` to use. The 546``sysbuild-kconfig: <directory>/Kconfig`` part specifies the Kconfig file to 547use. 548 549Here is an example :file:`module.yml` file referring to 550:file:`CMakeLists.txt` and :file:`Kconfig` files in the ``sysbuild`` directory of 551the module: 552 553.. code-block:: yaml 554 555 build: 556 sysbuild-cmake: sysbuild 557 sysbuild-kconfig: sysbuild/Kconfig 558 559The module description file :file:`zephyr/module.yml` can also be used to 560specify that the build files, :file:`CMakeLists.txt` and :file:`Kconfig`, are 561located in a :ref:`modules_module_ext_root`. 562 563Build files located in a ``MODULE_EXT_ROOT`` can be described as: 564 565.. code-block:: yaml 566 567 build: 568 sysbuild-cmake-ext: True 569 sysbuild-kconfig-ext: True 570 571This allows control of the build inclusion to be described externally to the 572Zephyr module. 573 574.. _modules-vulnerability-monitoring: 575 576Vulnerability monitoring 577======================== 578 579The module description file :file:`zephyr/module.yml` can be used to improve vulnerability monitoring. 580 581If your module needs to track vulnerabilities using an external reference 582(e.g your module is forked from another repository), you can use the ``security`` section. 583It contains the field ``external-references`` that contains a list of references that needs to 584be monitored for your module. The supported formats are: 585 586- CPE (Common Platform Enumeration) 587- PURL (Package URL) 588 589.. code-block:: yaml 590 591 security: 592 external-references: 593 - <module-related-cpe> 594 - <an-other-module-related-cpe> 595 - <module-related-purl> 596 597A real life example for ``mbedTLS`` module could look like this: 598 599.. code-block:: yaml 600 601 security: 602 external-references: 603 - cpe:2.3:a:arm:mbed_tls:3.5.2:*:*:*:*:*:*:* 604 - pkg:github/Mbed-TLS/mbedtls@V3.5.2 605 606.. note:: 607 CPE field must follow the CPE 2.3 schema provided by `NVD 608 <https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe>`_. 609 PURL field must follow the PURL specification provided by `Github 610 <https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst>`_. 611 612 613Build system integration 614======================== 615 616When a module has a :file:`module.yml` file, it will automatically be included into 617the Zephyr build system. The path to the module is then accessible through Kconfig 618and CMake variables. 619 620Zephyr modules 621-------------- 622 623In both Kconfig and CMake, the variable ``ZEPHYR_<MODULE_NAME>_MODULE_DIR`` 624contains the absolute path to the module. 625 626Additionally, ``ZEPHYR_<MODULE_NAME>_MODULE`` and ``ZEPHYR_<MODULE_NAME>_MODULE_BLOBS`` 627(in case the module declares blobs) symbols are automatically generated for available 628modules. These can be used e.g. to declare dependencies from other Kconfig symbols 629which depend on the module or blobs from the module. To satisfy compliance checking 630when building Zephyr without the module present, it's recommended for the module to 631have default definitions for these symbols in its respective Kconfig file under 632``modules/`` in the Zephyr main tree. 633 634In CMake, ``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` contains the 635absolute path to the directory containing the :file:`CMakeLists.txt` file that 636is included into CMake build system. This variable's value is empty if the 637module.yml file does not specify a CMakeLists.txt. 638 639To read these variables for a Zephyr module named ``foo``: 640 641- In CMake: use ``${ZEPHYR_FOO_MODULE_DIR}`` for the module's top level directory, and ``${ZEPHYR_FOO_CMAKE_DIR}`` for the directory containing its :file:`CMakeLists.txt` 642- In Kconfig: use ``$(ZEPHYR_FOO_MODULE_DIR)`` for the module's top level directory 643 644Notice how a lowercase module name ``foo`` is capitalized to ``FOO`` 645in both CMake and Kconfig. 646 647These variables can also be used to test whether a given module exists. 648For example, to verify that ``foo`` is the name of a Zephyr module: 649 650.. code-block:: cmake 651 652 if(ZEPHYR_FOO_MODULE_DIR) 653 # Do something if FOO exists. 654 endif() 655 656In Kconfig, the variable may be used to find additional files to include. 657For example, to include the file :file:`some/Kconfig` in module ``foo``: 658 659.. code-block:: kconfig 660 661 source "$(ZEPHYR_FOO_MODULE_DIR)/some/Kconfig" 662 663During CMake processing of each Zephyr module, the following variables are 664also available: 665 666- the current module's name: ``${ZEPHYR_CURRENT_MODULE_NAME}`` 667- the current module's top level directory: ``${ZEPHYR_CURRENT_MODULE_DIR}`` 668- the current module's :file:`CMakeLists.txt` directory: ``${ZEPHYR_CURRENT_CMAKE_DIR}`` 669 670This removes the need for a Zephyr module to know its own name during CMake 671processing. The module can source additional CMake files using these ``CURRENT`` 672variables. For example: 673 674.. code-block:: cmake 675 676 include(${ZEPHYR_CURRENT_MODULE_DIR}/cmake/code.cmake) 677 678It is possible to append values to a Zephyr `CMake list`_ variable from the module's first 679CMakeLists.txt file. 680To do so, append the value to the list and then set the list in the PARENT_SCOPE 681of the CMakeLists.txt file. For example, to append ``bar`` to the ``FOO_LIST`` variable in the 682Zephyr CMakeLists.txt scope: 683 684.. code-block:: cmake 685 686 list(APPEND FOO_LIST bar) 687 set(FOO_LIST ${FOO_LIST} PARENT_SCOPE) 688 689An example of a Zephyr list where this is useful is when adding additional 690directories to the ``SYSCALL_INCLUDE_DIRS`` list. 691 692Sysbuild modules 693---------------- 694 695In both Kconfig and CMake, the variable ``SYSBUILD_CURRENT_MODULE_DIR`` 696contains the absolute path to the sysbuild module. In CMake, 697``SYSBUILD_CURRENT_CMAKE_DIR`` contains the absolute path to the directory 698containing the :file:`CMakeLists.txt` file that is included into CMake build 699system. This variable's value is empty if the module.yml file does not specify 700a CMakeLists.txt. 701 702To read these variables for a sysbuild module: 703 704- In CMake: use ``${SYSBUILD_CURRENT_MODULE_DIR}`` for the module's top level 705 directory, and ``${SYSBUILD_CURRENT_CMAKE_DIR}`` for the directory containing 706 its :file:`CMakeLists.txt` 707- In Kconfig: use ``$(SYSBUILD_CURRENT_MODULE_DIR)`` for the module's top level 708 directory 709 710In Kconfig, the variable may be used to find additional files to include. 711For example, to include the file :file:`some/Kconfig`: 712 713.. code-block:: kconfig 714 715 source "$(SYSBUILD_CURRENT_MODULE_DIR)/some/Kconfig" 716 717The module can source additional CMake files using these variables. For 718example: 719 720.. code-block:: cmake 721 722 include(${SYSBUILD_CURRENT_MODULE_DIR}/cmake/code.cmake) 723 724It is possible to append values to a Zephyr `CMake list`_ variable from the 725module's first CMakeLists.txt file. 726To do so, append the value to the list and then set the list in the 727PARENT_SCOPE of the CMakeLists.txt file. For example, to append ``bar`` to the 728``FOO_LIST`` variable in the Zephyr CMakeLists.txt scope: 729 730.. code-block:: cmake 731 732 list(APPEND FOO_LIST bar) 733 set(FOO_LIST ${FOO_LIST} PARENT_SCOPE) 734 735Sysbuild modules hooks 736---------------------- 737 738Sysbuild provides an infrastructure which allows a sysbuild module to define 739a function which will be invoked by sysbuild at a pre-defined point in the 740CMake flow. 741 742Functions invoked by sysbuild: 743 744- ``<module-name>_pre_cmake(IMAGES <images>)``: This function is called for each 745 sysbuild module before CMake configure is invoked for all images. 746- ``<module-name>_post_cmake(IMAGES <images>)``: This function is called for each 747 sysbuild module after CMake configure has completed for all images. 748- ``<module-name>_pre_domains(IMAGES <images>)``: This function is called for each 749 sysbuild module before domains yaml is created by sysbuild. 750- ``<module-name>_post_domains(IMAGES <images>)``: This function is called for each 751 sysbuild module after domains yaml has been created by sysbuild. 752 753arguments passed from sysbuild to the function defined by a module: 754 755- ``<images>`` is the list of Zephyr images that will be created by the build system. 756 757If a module ``foo`` want to provide a post CMake configure function, then the 758module's sysbuild :file:`CMakeLists.txt` file must define function ``foo_post_cmake()``. 759 760To facilitate naming of functions, the module name is provided by sysbuild CMake 761through the ``SYSBUILD_CURRENT_MODULE_NAME`` CMake variable when loading the 762module's sysbuild :file:`CMakeLists.txt` file. 763 764Example of how the ``foo`` sysbuild module can define ``foo_post_cmake()``: 765 766.. code-block:: cmake 767 768 function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake) 769 cmake_parse_arguments(POST_CMAKE "" "" "IMAGES" ${ARGN}) 770 771 message("Invoking ${CMAKE_CURRENT_FUNCTION}. Images: ${POST_CMAKE_IMAGES}") 772 endfunction() 773 774Zephyr module dependencies 775========================== 776 777A Zephyr module may be dependent on other Zephyr modules to be present in order 778to function correctly. Or it might be that a given Zephyr module must be 779processed after another Zephyr module, due to dependencies of certain CMake 780targets. 781 782Such a dependency can be described using the ``depends`` field. 783 784.. code-block:: yaml 785 786 build: 787 depends: 788 - <module> 789 790Here is an example for the Zephyr module ``foo`` that is dependent on the Zephyr 791module ``bar`` to be present in the build system: 792 793.. code-block:: yaml 794 795 name: foo 796 build: 797 depends: 798 - bar 799 800This example will ensure that ``bar`` is present when ``foo`` is included into 801the build system, and it will also ensure that ``bar`` is processed before 802``foo``. 803 804.. _modules_module_ext_root: 805 806Module integration files (external) 807=================================== 808 809Module integration files can be located externally to the Zephyr module itself. 810The ``MODULE_EXT_ROOT`` variable holds a list of roots containing integration 811files located externally to Zephyr modules. 812 813Module integration files in Zephyr 814---------------------------------- 815 816The Zephyr repository contain :file:`CMakeLists.txt` and :file:`Kconfig` build 817files for certain known Zephyr modules. 818 819Those files are located under 820 821.. code-block:: none 822 823 <ZEPHYR_BASE> 824 └── modules 825 └── <module_name> 826 ├── CMakeLists.txt 827 └── Kconfig 828 829Module integration files in a custom location 830--------------------------------------------- 831 832You can create a similar ``MODULE_EXT_ROOT`` for additional modules, and make 833those modules known to Zephyr build system. 834 835Create a ``MODULE_EXT_ROOT`` with the following structure 836 837.. code-block:: none 838 839 <MODULE_EXT_ROOT> 840 └── modules 841 ├── modules.cmake 842 └── <module_name> 843 ├── CMakeLists.txt 844 └── Kconfig 845 846and then build your application by specifying ``-DMODULE_EXT_ROOT`` parameter to 847the CMake build system. The ``MODULE_EXT_ROOT`` accepts a `CMake list`_ of roots as 848argument. 849 850A Zephyr module can automatically be added to the ``MODULE_EXT_ROOT`` 851list using the module description file :file:`zephyr/module.yml`, see 852:ref:`modules_build_settings`. 853 854.. note:: 855 856 ``ZEPHYR_BASE`` is always added as a ``MODULE_EXT_ROOT`` with the lowest 857 priority. 858 This allows you to overrule any integration files under 859 ``<ZEPHYR_BASE>/modules/<module_name>`` with your own implementation your own 860 ``MODULE_EXT_ROOT``. 861 862The :file:`modules.cmake` file must contain the logic that specifies the 863integration files for Zephyr modules via specifically named CMake variables. 864 865To include a module's CMake file, set the variable ``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` 866to the path containing the CMake file. 867 868To include a module's Kconfig file, set the variable ``ZEPHYR_<MODULE_NAME>_KCONFIG`` 869to the path to the Kconfig file. 870 871The following is an example on how to add support the ``FOO`` module. 872 873Create the following structure 874 875.. code-block:: none 876 877 <MODULE_EXT_ROOT> 878 └── modules 879 ├── modules.cmake 880 └── foo 881 ├── CMakeLists.txt 882 └── Kconfig 883 884and inside the :file:`modules.cmake` file, add the following content 885 886.. code-block:: cmake 887 888 set(ZEPHYR_FOO_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR}/foo) 889 set(ZEPHYR_FOO_KCONFIG ${CMAKE_CURRENT_LIST_DIR}/foo/Kconfig) 890 891Module integration files (zephyr/module.yml) 892-------------------------------------------- 893 894The module description file :file:`zephyr/module.yml` can be used to specify 895that the build files, :file:`CMakeLists.txt` and :file:`Kconfig`, are located 896in a :ref:`modules_module_ext_root`. 897 898Build files located in a ``MODULE_EXT_ROOT`` can be described as: 899 900.. code-block:: yaml 901 902 build: 903 cmake-ext: True 904 kconfig-ext: True 905 906This allows control of the build inclusion to be described externally to the 907Zephyr module. 908 909The Zephyr repository itself is always added as a Zephyr module ext root. 910 911.. _modules_build_settings: 912 913Build settings 914============== 915 916It is possible to specify additional build settings that must be used when 917including the module into the build system. 918 919All ``root`` settings are relative to the root of the module. 920 921Build settings supported in the :file:`module.yml` file are: 922 923- ``board_root``: Contains additional boards that are available to the build 924 system. Additional boards must be located in a :file:`<board_root>/boards` 925 folder. 926- ``dts_root``: Contains additional dts files related to the architecture/soc 927 families. Additional dts files must be located in a :file:`<dts_root>/dts` 928 folder. 929- ``snippet_root``: Contains additional snippets that are available for use. 930 These snippets must be defined in :file:`snippet.yml` files underneath the 931 :file:`<snippet_root>/snippets` folder. For example, if you have 932 ``snippet_root: foo``, then you should place your module's 933 :file:`snippet.yml` files in :file:`<your-module>/foo/snippets` or any 934 nested subdirectory. 935- ``soc_root``: Contains additional SoCs that are available to the build 936 system. Additional SoCs must be located in a :file:`<soc_root>/soc` folder. 937- ``arch_root``: Contains additional architectures that are available to the 938 build system. Additional architectures must be located in a 939 :file:`<arch_root>/arch` folder. 940- ``module_ext_root``: Contains :file:`CMakeLists.txt` and :file:`Kconfig` files 941 for Zephyr modules, see also :ref:`modules_module_ext_root`. 942- ``sca_root``: Contains additional :ref:`SCA <sca>` tool implementations 943 available to the build system. Each tool must be located in 944 :file:`<sca_root>/sca/<tool>` folder. The folder must contain a 945 :file:`sca.cmake`. 946 947Example of a :file:`module.yaml` file containing additional roots, and the 948corresponding file system layout. 949 950.. code-block:: yaml 951 952 build: 953 settings: 954 board_root: . 955 dts_root: . 956 soc_root: . 957 arch_root: . 958 module_ext_root: . 959 960 961requires the following folder structure: 962 963.. code-block:: none 964 965 <zephyr-module-root> 966 ├── arch 967 ├── boards 968 ├── dts 969 ├── modules 970 └── soc 971 972Twister (Test Runner) 973===================== 974 975To execute both tests and samples available in modules, the Zephyr test runner 976(twister) should be pointed to the directories containing those samples and 977tests. This can be done by specifying the path to both samples and tests in the 978:file:`zephyr/module.yml` file. Additionally, if a module defines out of tree 979boards, the module file can point twister to the path where those files 980are maintained in the module. For example: 981 982 983.. code-block:: yaml 984 985 build: 986 cmake: . 987 samples: 988 - samples 989 tests: 990 - tests 991 boards: 992 - boards 993 994.. _modules-bin-blobs: 995 996Binary Blobs 997============ 998 999Zephyr supports fetching and using :ref:`binary blobs <bin-blobs>`, and their 1000metadata is contained entirely in :file:`zephyr/module.yml`. This is because 1001a binary blob must always be associated with a Zephyr module, and thus the 1002blob metadata belongs in the module's description itself. 1003 1004Binary blobs are fetched using :ref:`west blobs <west-blobs>`. If ``west`` is 1005:ref:`not used <modules_without_west>`, they must be downloaded and 1006verified manually. 1007 1008The ``blobs`` section in :file:`zephyr/module.yml` consists of a sequence of 1009maps, each of which has the following entries: 1010 1011- ``path``: The path to the binary blob, relative to the :file:`zephyr/blobs/` 1012 folder in the module repository 1013- ``sha256``: `SHA-256 <https://en.wikipedia.org/wiki/SHA-2>`_ checksum of the 1014 binary blob file 1015- ``type``: The :ref:`type of binary blob <bin-blobs-types>`. Currently limited 1016 to ``img`` or ``lib`` 1017- ``version``: A version string 1018- ``license-path``: Path to the license file for this blob, relative to the root 1019 of the module repository 1020- ``url``: URL that identifies the location the blob will be fetched from, as 1021 well as the fetching scheme to use 1022- ``description``: Human-readable description of the binary blob 1023- ``doc-url``: A URL pointing to the location of the official documentation for 1024 this blob 1025 1026Package manager dependencies 1027============================ 1028 1029Zephyr modules can describe dependencies available from package managers, 1030currently only ``pip`` is supported. 1031 1032A west extension command ``west packages <manager>`` is available to list 1033dependencies for Zephyr and present modules that leverage this feature in their 1034``module.yml`` file. 1035Run ``west help packages`` for more details. 1036 1037Python pip 1038---------- 1039 1040Calling ``west packages pip`` lists `requirement files`_ for Zephyr and modules. 1041Passing ``--install`` installs these if there's an active virtual environment. 1042 1043The following example demonstrates a ``zephyr/module.yml`` file with some 1044requirement files in the ``scripts`` directory of the module. 1045 1046 1047.. code-block:: yaml 1048 1049 package-managers: 1050 pip: 1051 requirement-files: 1052 - scripts/requirements-build.txt 1053 - scripts/requirements-doc.txt 1054 1055 1056.. _modules-runners: 1057 1058External Runners 1059================ 1060 1061If a module has out of tree boards that require custom :ref:`runners <west-runner>`, 1062then it can add a list to its ``zephyr/module.yml`` file, for example: 1063 1064 1065.. code-block:: yaml 1066 1067 runners: 1068 - file: scripts/my-runner.py 1069 1070 1071Each file entry is imported when executing ``west flash`` or ``west debug`` and 1072subclasses of the ``ZephyrBinaryRunner`` are registered for use. 1073 1074Module Inclusion 1075================ 1076 1077.. _modules_using_west: 1078 1079Using West 1080---------- 1081 1082If west is installed and :makevar:`ZEPHYR_MODULES` is not already set, the 1083build system finds all the modules in your :term:`west installation` and uses 1084those. It does this by running :ref:`west list <west-built-in-misc>` to get 1085the paths of all the projects in the installation, then filters the results to 1086just those projects which have the necessary module metadata files. 1087 1088Each project in the ``west list`` output is tested like this: 1089 1090- If the project contains a file named :file:`zephyr/module.yml`, then the 1091 content of that file will be used to determine which files should be added 1092 to the build, as described in the previous section. 1093 1094- Otherwise (i.e. if the project has no :file:`zephyr/module.yml`), the 1095 build system looks for :file:`zephyr/CMakeLists.txt` and 1096 :file:`zephyr/Kconfig` files in the project. If both are present, the project 1097 is considered a module, and those files will be added to the build. 1098 1099- If neither of those checks succeed, the project is not considered a module, 1100 and is not added to :makevar:`ZEPHYR_MODULES`. 1101 1102.. _modules_without_west: 1103 1104Without West 1105------------ 1106 1107If you don't have west installed or don't want the build system to use it to 1108find Zephyr modules, you can set :makevar:`ZEPHYR_MODULES` yourself using one 1109of the following options. Each of the directories in the list must contain 1110either a :file:`zephyr/module.yml` file or the files 1111:file:`zephyr/CMakeLists.txt` and :file:`Kconfig`, as described in the previous 1112section. 1113 1114#. At the CMake command line, like this: 1115 1116 .. code-block:: console 1117 1118 cmake -DZEPHYR_MODULES=<path-to-module1>[;<path-to-module2>[...]] ... 1119 1120#. At the top of your application's top level :file:`CMakeLists.txt`, like this: 1121 1122 .. code-block:: cmake 1123 1124 set(ZEPHYR_MODULES <path-to-module1> <path-to-module2> [...]) 1125 find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 1126 1127 If you choose this option, make sure to set the variable **before** calling 1128 ``find_package(Zephyr ...)``, as shown above. 1129 1130#. In a separate CMake script which is pre-loaded to populate the CMake cache, 1131 like this: 1132 1133 .. code-block:: cmake 1134 1135 # Put this in a file with a name like "zephyr-modules.cmake" 1136 set(ZEPHYR_MODULES <path-to-module1> <path-to-module2> 1137 CACHE STRING "pre-cached modules") 1138 1139 You can tell the build system to use this file by adding ``-C 1140 zephyr-modules.cmake`` to your CMake command line. 1141 1142Not using modules 1143----------------- 1144 1145If you don't have west installed and don't specify :makevar:`ZEPHYR_MODULES` 1146yourself, then no additional modules are added to the build. You will still be 1147able to build any applications that don't require code or Kconfig options 1148defined in an external repository. 1149 1150Submitting changes to modules 1151****************************** 1152 1153When submitting new or making changes to existing modules the main repository 1154Zephyr needs a reference to the changes to be able to verify the changes. In the 1155main tree this is done using revisions. For code that is already merged and part 1156of the tree we use the commit hash, a tag, or a branch name. For pull requests 1157however, we require specifying the pull request number in the revision field to 1158allow building the zephyr main tree with the changes submitted to the 1159module. 1160 1161To avoid merging changes to master with pull request information, the pull 1162request should be marked as ``DNM`` (Do Not Merge) or preferably a draft pull 1163request to make sure it is not merged by mistake and to allow for the module to 1164be merged first and be assigned a permanent commit hash. Drafts reduce noise by 1165not automatically notifying anyone until marked as "Ready for review". 1166Once the module is 1167merged, the revision will need to be changed either by the submitter or by the 1168maintainer to the commit hash of the module which reflects the changes. 1169 1170Note that multiple and dependent changes to different modules can be submitted 1171using exactly the same process. In this case you will change multiple entries of 1172all modules that have a pull request against them. 1173 1174.. _submitting_new_modules: 1175 1176Process for submitting a new module 1177=================================== 1178 1179Please follow the process in :ref:`external-src-process` and obtain the TSC 1180approval to integrate the external source code as a module 1181 1182If the request is approved, a new repository will 1183created by the project team and initialized with basic information that would 1184allow submitting code to the module project following the project contribution 1185guidelines. 1186 1187If a module is maintained as a fork of another project on Github, the Zephyr 1188module related files and changes in relation to upstream need to be maintained 1189in a special branch named ``zephyr``. 1190 1191Maintainers from the Zephyr project will create the repository and initialize 1192it. You will be added as a collaborator in the new repository. Submit the 1193module content (code) to the new repository following the guidelines described 1194:ref:`here <modules_using_west>`, and then add a new entry to the 1195:zephyr_file:`west.yml` with the following information: 1196 1197 .. code-block:: console 1198 1199 - name: <name of repository> 1200 path: <path to where the repository should be cloned> 1201 revision: <ref pointer to module pull request> 1202 1203 1204For example, to add *my_module* to the manifest: 1205 1206.. code-block:: console 1207 1208 - name: my_module 1209 path: modules/lib/my_module 1210 revision: pull/23/head 1211 1212 1213Where 23 in the example above indicated the pull request number submitted to the 1214*my_module* repository. Once the module changes are reviewed and merged, the 1215revision needs to be changed to the commit hash from the module repository. 1216 1217.. _changes_to_existing_module: 1218 1219Process for submitting changes to existing modules 1220================================================== 1221 1222#. Submit the changes using a pull request to an existing repository following 1223 the :ref:`contribution guidelines <contribute_guidelines>` and 1224 :ref:`expectations <contributor-expectations>`. 1225#. Submit a pull request changing the entry referencing the module into the 1226 :zephyr_file:`west.yml` of the main Zephyr tree with the following 1227 information: 1228 1229 .. code-block:: console 1230 1231 - name: <name of repository> 1232 path: <path to where the repository should be cloned> 1233 revision: <ref pointer to module pull request> 1234 1235 1236For example, to add *my_module* to the manifest: 1237 1238.. code-block:: console 1239 1240 - name: my_module 1241 path: modules/lib/my_module 1242 revision: pull/23/head 1243 1244Where 23 in the example above indicated the pull request number submitted to the 1245*my_module* repository. Once the module changes are reviewed and merged, the 1246revision needs to be changed to the commit hash from the module repository. 1247 1248 1249 1250.. _CMake list: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#lists 1251.. _add_subdirectory(): https://cmake.org/cmake/help/latest/command/add_subdirectory.html 1252.. _GitHub issues: https://github.com/zephyrproject-rtos/zephyr/issues 1253.. _requirement files: https://pip.pypa.io/en/stable/reference/requirements-file-format/ 1254