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 428useful if you want to keep the list of modules found with west and also add 429your own. 430 431.. note:: 432 If the module ``FOO`` is provided by :ref:`west <west>` but also given with 433 ``-DEXTRA_ZEPHYR_MODULES=/<path>/foo`` then the module given by the command 434 line variable :makevar:`EXTRA_ZEPHYR_MODULES` will take precedence. 435 This allows you to use a custom version of ``FOO`` when building and still 436 use other Zephyr modules provided by :ref:`west <west>`. 437 This can for example be useful for special test purposes. 438 439If you want to permanently add modules to the zephyr workspace and you are 440using zephyr as your manifest repository, you can also add a west manifest file 441into the :zephyr_file:`submanifests` directory. See 442:zephyr_file:`submanifests/README.txt` for more details. 443 444See :ref:`west-basics` for more on west workspaces. 445 446Finally, you can also specify the list of modules yourself in various ways, or 447not use modules at all if your application doesn't need them. 448 449.. _module-yml: 450 451Module yaml file description 452**************************** 453 454A module can be described using a file named :file:`zephyr/module.yml`. 455The format of :file:`zephyr/module.yml` is described in the following: 456 457Module name 458=========== 459 460Each Zephyr module is given a name by which it can be referred to in the build 461system. 462 463The name should be specified in the :file:`zephyr/module.yml` file. This will 464ensure the module name is not changeable through user-defined directory names 465or ``west`` manifest files: 466 467.. code-block:: yaml 468 469 name: <name> 470 471In CMake the location of the Zephyr module can then be referred to using the 472CMake variable ``ZEPHYR_<MODULE_NAME>_MODULE_DIR`` and the variable 473``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` holds the location of the directory 474containing the module's :file:`CMakeLists.txt` file. 475 476.. note:: 477 When used for CMake and Kconfig variables, all letters in module names are 478 converted to uppercase and all non-alphanumeric characters are converted 479 to underscores (_). 480 As example, the module ``foo-bar`` must be referred to as 481 ``ZEPHYR_FOO_BAR_MODULE_DIR`` in CMake and Kconfig. 482 483Here is an example for the Zephyr module ``foo``: 484 485.. code-block:: yaml 486 487 name: foo 488 489.. note:: 490 If the ``name`` field is not specified then the Zephyr module name will be 491 set to the name of the module folder. 492 As example, the Zephyr module located in :file:`<workspace>/modules/bar` will 493 use ``bar`` as its module name if nothing is specified in 494 :file:`zephyr/module.yml`. 495 496Module integration files (in-module) 497==================================== 498 499Inclusion of build files, :file:`CMakeLists.txt` and :file:`Kconfig`, can be 500described as: 501 502.. code-block:: yaml 503 504 build: 505 cmake: <cmake-directory> 506 kconfig: <directory>/Kconfig 507 508The ``cmake: <cmake-directory>`` part specifies that 509:file:`<cmake-directory>` contains the :file:`CMakeLists.txt` to use. The 510``kconfig: <directory>/Kconfig`` part specifies the Kconfig file to use. 511Neither is required: ``cmake`` defaults to ``zephyr``, and ``kconfig`` 512defaults to ``zephyr/Kconfig``. 513 514Here is an example :file:`module.yml` file referring to 515:file:`CMakeLists.txt` and :file:`Kconfig` files in the root directory of the 516module: 517 518.. code-block:: yaml 519 520 build: 521 cmake: . 522 kconfig: Kconfig 523 524.. _sysbuild_module_integration: 525 526Sysbuild integration 527==================== 528 529:ref:`Sysbuild<sysbuild>` is the Zephyr build system that allows for building 530multiple images as part of a single application, the sysbuild build process 531can be extended externally with modules as needed, for example to add custom 532build steps or add additional targets to a build. Inclusion of 533sysbuild-specific build files, :file:`CMakeLists.txt` and :file:`Kconfig`, can 534be described as: 535 536.. code-block:: yaml 537 538 build: 539 sysbuild-cmake: <cmake-directory> 540 sysbuild-kconfig: <directory>/Kconfig 541 542The ``sysbuild-cmake: <cmake-directory>`` part specifies that 543:file:`<cmake-directory>` contains the :file:`CMakeLists.txt` to use. The 544``sysbuild-kconfig: <directory>/Kconfig`` part specifies the Kconfig file to 545use. 546 547Here is an example :file:`module.yml` file referring to 548:file:`CMakeLists.txt` and :file:`Kconfig` files in the ``sysbuild`` directory of 549the module: 550 551.. code-block:: yaml 552 553 build: 554 sysbuild-cmake: sysbuild 555 sysbuild-kconfig: sysbuild/Kconfig 556 557The module description file :file:`zephyr/module.yml` can also be used to 558specify that the build files, :file:`CMakeLists.txt` and :file:`Kconfig`, are 559located in a :ref:`modules_module_ext_root`. 560 561Build files located in a ``MODULE_EXT_ROOT`` can be described as: 562 563.. code-block:: yaml 564 565 build: 566 sysbuild-cmake-ext: True 567 sysbuild-kconfig-ext: True 568 569This allows control of the build inclusion to be described externally to the 570Zephyr module. 571 572.. _modules-vulnerability-monitoring: 573 574Vulnerability monitoring 575======================== 576 577The module description file :file:`zephyr/module.yml` can be used to improve vulnerability monitoring. 578 579If your module needs to track vulnerabilities using an external reference 580(e.g your module is forked from another repository), you can use the ``security`` section. 581It contains the field ``external-references`` that contains a list of references that needs to 582be monitored for your module. The supported formats are: 583 584- CPE (Common Platform Enumeration) 585- PURL (Package URL) 586 587.. code-block:: yaml 588 589 security: 590 external-references: 591 - <module-related-cpe> 592 - <an-other-module-related-cpe> 593 - <module-related-purl> 594 595A real life example for ``mbedTLS`` module could look like this: 596 597.. code-block:: yaml 598 599 security: 600 external-references: 601 - cpe:2.3:a:arm:mbed_tls:3.5.2:*:*:*:*:*:*:* 602 - pkg:github/Mbed-TLS/mbedtls@V3.5.2 603 604.. note:: 605 CPE field must follow the CPE 2.3 schema provided by `NVD 606 <https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe>`_. 607 PURL field must follow the PURL specification provided by `Github 608 <https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst>`_. 609 610 611Build system integration 612======================== 613 614When a module has a :file:`module.yml` file, it will automatically be included into 615the Zephyr build system. The path to the module is then accessible through Kconfig 616and CMake variables. 617 618Zephyr modules 619-------------- 620 621In both Kconfig and CMake, the variable ``ZEPHYR_<MODULE_NAME>_MODULE_DIR`` 622contains the absolute path to the module. 623 624Additionally, ``ZEPHYR_<MODULE_NAME>_MODULE`` and ``ZEPHYR_<MODULE_NAME>_MODULE_BLOBS`` 625(in case the module declares blobs) symbols are automatically generated for available 626modules. These can be used e.g. to declare dependencies from other Kconfig symbols 627which depend on the module or blobs from the module. To satisfy compliance checking 628when building Zephyr without the module present, it's recommended for the module to 629have default definitions for these symbols in its respective Kconfig file under 630``modules/`` in the Zephyr main tree. 631 632In CMake, ``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` contains the 633absolute path to the directory containing the :file:`CMakeLists.txt` file that 634is included into CMake build system. This variable's value is empty if the 635module.yml file does not specify a CMakeLists.txt. 636 637To read these variables for a Zephyr module named ``foo``: 638 639- 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` 640- In Kconfig: use ``$(ZEPHYR_FOO_MODULE_DIR)`` for the module's top level directory 641 642Notice how a lowercase module name ``foo`` is capitalized to ``FOO`` 643in both CMake and Kconfig. 644 645These variables can also be used to test whether a given module exists. 646For example, to verify that ``foo`` is the name of a Zephyr module: 647 648.. code-block:: cmake 649 650 if(ZEPHYR_FOO_MODULE_DIR) 651 # Do something if FOO exists. 652 endif() 653 654In Kconfig, the variable may be used to find additional files to include. 655For example, to include the file :file:`some/Kconfig` in module ``foo``: 656 657.. code-block:: kconfig 658 659 source "$(ZEPHYR_FOO_MODULE_DIR)/some/Kconfig" 660 661During CMake processing of each Zephyr module, the following variables are 662also available: 663 664- the current module's name: ``${ZEPHYR_CURRENT_MODULE_NAME}`` 665- the current module's top level directory: ``${ZEPHYR_CURRENT_MODULE_DIR}`` 666- the current module's :file:`CMakeLists.txt` directory: ``${ZEPHYR_CURRENT_CMAKE_DIR}`` 667 668This removes the need for a Zephyr module to know its own name during CMake 669processing. The module can source additional CMake files using these ``CURRENT`` 670variables. For example: 671 672.. code-block:: cmake 673 674 include(${ZEPHYR_CURRENT_MODULE_DIR}/cmake/code.cmake) 675 676It is possible to append values to a Zephyr `CMake list`_ variable from the module's first 677CMakeLists.txt file. 678To do so, append the value to the list and then set the list in the PARENT_SCOPE 679of the CMakeLists.txt file. For example, to append ``bar`` to the ``FOO_LIST`` variable in the 680Zephyr CMakeLists.txt scope: 681 682.. code-block:: cmake 683 684 list(APPEND FOO_LIST bar) 685 set(FOO_LIST ${FOO_LIST} PARENT_SCOPE) 686 687An example of a Zephyr list where this is useful is when adding additional 688directories to the ``SYSCALL_INCLUDE_DIRS`` list. 689 690Sysbuild modules 691---------------- 692 693In both Kconfig and CMake, the variable ``SYSBUILD_CURRENT_MODULE_DIR`` 694contains the absolute path to the sysbuild module. In CMake, 695``SYSBUILD_CURRENT_CMAKE_DIR`` contains the absolute path to the directory 696containing the :file:`CMakeLists.txt` file that is included into CMake build 697system. This variable's value is empty if the module.yml file does not specify 698a CMakeLists.txt. 699 700To read these variables for a sysbuild module: 701 702- In CMake: use ``${SYSBUILD_CURRENT_MODULE_DIR}`` for the module's top level 703 directory, and ``${SYSBUILD_CURRENT_CMAKE_DIR}`` for the directory containing 704 its :file:`CMakeLists.txt` 705- In Kconfig: use ``$(SYSBUILD_CURRENT_MODULE_DIR)`` for the module's top level 706 directory 707 708In Kconfig, the variable may be used to find additional files to include. 709For example, to include the file :file:`some/Kconfig`: 710 711.. code-block:: kconfig 712 713 source "$(SYSBUILD_CURRENT_MODULE_DIR)/some/Kconfig" 714 715The module can source additional CMake files using these variables. For 716example: 717 718.. code-block:: cmake 719 720 include(${SYSBUILD_CURRENT_MODULE_DIR}/cmake/code.cmake) 721 722It is possible to append values to a Zephyr `CMake list`_ variable from the 723module's first CMakeLists.txt file. 724To do so, append the value to the list and then set the list in the 725PARENT_SCOPE of the CMakeLists.txt file. For example, to append ``bar`` to the 726``FOO_LIST`` variable in the Zephyr CMakeLists.txt scope: 727 728.. code-block:: cmake 729 730 list(APPEND FOO_LIST bar) 731 set(FOO_LIST ${FOO_LIST} PARENT_SCOPE) 732 733Sysbuild modules hooks 734---------------------- 735 736Sysbuild provides an infrastructure which allows a sysbuild module to define 737a function which will be invoked by sysbuild at a pre-defined point in the 738CMake flow. 739 740Functions invoked by sysbuild: 741 742- ``<module-name>_pre_cmake(IMAGES <images>)``: This function is called for each 743 sysbuild module before CMake configure is invoked for all images. 744- ``<module-name>_post_cmake(IMAGES <images>)``: This function is called for each 745 sysbuild module after CMake configure has completed for all images. 746- ``<module-name>_pre_domains(IMAGES <images>)``: This function is called for each 747 sysbuild module before domains yaml is created by sysbuild. 748- ``<module-name>_post_domains(IMAGES <images>)``: This function is called for each 749 sysbuild module after domains yaml has been created by sysbuild. 750 751arguments passed from sysbuild to the function defined by a module: 752 753- ``<images>`` is the list of Zephyr images that will be created by the build system. 754 755If a module ``foo`` want to provide a post CMake configure function, then the 756module's sysbuild :file:`CMakeLists.txt` file must define function ``foo_post_cmake()``. 757 758To facilitate naming of functions, the module name is provided by sysbuild CMake 759through the ``SYSBUILD_CURRENT_MODULE_NAME`` CMake variable when loading the 760module's sysbuild :file:`CMakeLists.txt` file. 761 762Example of how the ``foo`` sysbuild module can define ``foo_post_cmake()``: 763 764.. code-block:: cmake 765 766 function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake) 767 cmake_parse_arguments(POST_CMAKE "" "" "IMAGES" ${ARGN}) 768 769 message("Invoking ${CMAKE_CURRENT_FUNCTION}. Images: ${POST_CMAKE_IMAGES}") 770 endfunction() 771 772Zephyr module dependencies 773========================== 774 775A Zephyr module may be dependent on other Zephyr modules to be present in order 776to function correctly. Or it might be that a given Zephyr module must be 777processed after another Zephyr module, due to dependencies of certain CMake 778targets. 779 780Such a dependency can be described using the ``depends`` field. 781 782.. code-block:: yaml 783 784 build: 785 depends: 786 - <module> 787 788Here is an example for the Zephyr module ``foo`` that is dependent on the Zephyr 789module ``bar`` to be present in the build system: 790 791.. code-block:: yaml 792 793 name: foo 794 build: 795 depends: 796 - bar 797 798This example will ensure that ``bar`` is present when ``foo`` is included into 799the build system, and it will also ensure that ``bar`` is processed before 800``foo``. 801 802.. _modules_module_ext_root: 803 804Module integration files (external) 805=================================== 806 807Module integration files can be located externally to the Zephyr module itself. 808The ``MODULE_EXT_ROOT`` variable holds a list of roots containing integration 809files located externally to Zephyr modules. 810 811Module integration files in Zephyr 812---------------------------------- 813 814The Zephyr repository contain :file:`CMakeLists.txt` and :file:`Kconfig` build 815files for certain known Zephyr modules. 816 817Those files are located under 818 819.. code-block:: none 820 821 <ZEPHYR_BASE> 822 └── modules 823 └── <module_name> 824 ├── CMakeLists.txt 825 └── Kconfig 826 827Module integration files in a custom location 828--------------------------------------------- 829 830You can create a similar ``MODULE_EXT_ROOT`` for additional modules, and make 831those modules known to Zephyr build system. 832 833Create a ``MODULE_EXT_ROOT`` with the following structure 834 835.. code-block:: none 836 837 <MODULE_EXT_ROOT> 838 └── modules 839 ├── modules.cmake 840 └── <module_name> 841 ├── CMakeLists.txt 842 └── Kconfig 843 844and then build your application by specifying ``-DMODULE_EXT_ROOT`` parameter to 845the CMake build system. The ``MODULE_EXT_ROOT`` accepts a `CMake list`_ of roots as 846argument. 847 848A Zephyr module can automatically be added to the ``MODULE_EXT_ROOT`` 849list using the module description file :file:`zephyr/module.yml`, see 850:ref:`modules_build_settings`. 851 852.. note:: 853 854 ``ZEPHYR_BASE`` is always added as a ``MODULE_EXT_ROOT`` with the lowest 855 priority. 856 This allows you to overrule any integration files under 857 ``<ZEPHYR_BASE>/modules/<module_name>`` with your own implementation your own 858 ``MODULE_EXT_ROOT``. 859 860The :file:`modules.cmake` file must contain the logic that specifies the 861integration files for Zephyr modules via specifically named CMake variables. 862 863To include a module's CMake file, set the variable ``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` 864to the path containing the CMake file. 865 866To include a module's Kconfig file, set the variable ``ZEPHYR_<MODULE_NAME>_KCONFIG`` 867to the path to the Kconfig file. 868 869The following is an example on how to add support the ``FOO`` module. 870 871Create the following structure 872 873.. code-block:: none 874 875 <MODULE_EXT_ROOT> 876 └── modules 877 ├── modules.cmake 878 └── foo 879 ├── CMakeLists.txt 880 └── Kconfig 881 882and inside the :file:`modules.cmake` file, add the following content 883 884.. code-block:: cmake 885 886 set(ZEPHYR_FOO_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR}/foo) 887 set(ZEPHYR_FOO_KCONFIG ${CMAKE_CURRENT_LIST_DIR}/foo/Kconfig) 888 889Module integration files (zephyr/module.yml) 890-------------------------------------------- 891 892The module description file :file:`zephyr/module.yml` can be used to specify 893that the build files, :file:`CMakeLists.txt` and :file:`Kconfig`, are located 894in a :ref:`modules_module_ext_root`. 895 896Build files located in a ``MODULE_EXT_ROOT`` can be described as: 897 898.. code-block:: yaml 899 900 build: 901 cmake-ext: True 902 kconfig-ext: True 903 904This allows control of the build inclusion to be described externally to the 905Zephyr module. 906 907The Zephyr repository itself is always added as a Zephyr module ext root. 908 909.. _modules_build_settings: 910 911Build settings 912============== 913 914It is possible to specify additional build settings that must be used when 915including the module into the build system. 916 917All ``root`` settings are relative to the root of the module. 918 919Build settings supported in the :file:`module.yml` file are: 920 921- ``board_root``: Contains additional boards that are available to the build 922 system. Additional boards must be located in a :file:`<board_root>/boards` 923 folder. 924- ``dts_root``: Contains additional dts files related to the architecture/soc 925 families. Additional dts files must be located in a :file:`<dts_root>/dts` 926 folder. 927- ``snippet_root``: Contains additional snippets that are available for use. 928 These snippets must be defined in :file:`snippet.yml` files underneath the 929 :file:`<snippet_root>/snippets` folder. For example, if you have 930 ``snippet_root: foo``, then you should place your module's 931 :file:`snippet.yml` files in :file:`<your-module>/foo/snippets` or any 932 nested subdirectory. 933- ``soc_root``: Contains additional SoCs that are available to the build 934 system. Additional SoCs must be located in a :file:`<soc_root>/soc` folder. 935- ``arch_root``: Contains additional architectures that are available to the 936 build system. Additional architectures must be located in a 937 :file:`<arch_root>/arch` folder. 938- ``module_ext_root``: Contains :file:`CMakeLists.txt` and :file:`Kconfig` files 939 for Zephyr modules, see also :ref:`modules_module_ext_root`. 940- ``sca_root``: Contains additional :ref:`SCA <sca>` tool implementations 941 available to the build system. Each tool must be located in 942 :file:`<sca_root>/sca/<tool>` folder. The folder must contain a 943 :file:`sca.cmake`. 944 945Example of a :file:`module.yaml` file containing additional roots, and the 946corresponding file system layout. 947 948.. code-block:: yaml 949 950 build: 951 settings: 952 board_root: . 953 dts_root: . 954 soc_root: . 955 arch_root: . 956 module_ext_root: . 957 958 959requires the following folder structure: 960 961.. code-block:: none 962 963 <zephyr-module-root> 964 ├── arch 965 ├── boards 966 ├── dts 967 ├── modules 968 └── soc 969 970Twister (Test Runner) 971===================== 972 973To execute both tests and samples available in modules, the Zephyr test runner 974(twister) should be pointed to the directories containing those samples and 975tests. This can be done by specifying the path to both samples and tests in the 976:file:`zephyr/module.yml` file. Additionally, if a module defines out of tree 977boards, the module file can point twister to the path where those files 978are maintained in the module. For example: 979 980 981.. code-block:: yaml 982 983 build: 984 cmake: . 985 samples: 986 - samples 987 tests: 988 - tests 989 boards: 990 - boards 991 992.. _modules-bin-blobs: 993 994Binary Blobs 995============ 996 997Zephyr supports fetching and using :ref:`binary blobs <bin-blobs>`, and their 998metadata is contained entirely in :file:`zephyr/module.yml`. This is because 999a binary blob must always be associated with a Zephyr module, and thus the 1000blob metadata belongs in the module's description itself. 1001 1002Binary blobs are fetched using :ref:`west blobs <west-blobs>`. If ``west`` is 1003:ref:`not used <modules_without_west>`, they must be downloaded and 1004verified manually. 1005 1006The ``blobs`` section in :file:`zephyr/module.yml` consists of a sequence of 1007maps, each of which has the following entries: 1008 1009- ``path``: The path to the binary blob, relative to the :file:`zephyr/blobs/` 1010 folder in the module repository 1011- ``sha256``: `SHA-256 <https://en.wikipedia.org/wiki/SHA-2>`_ checksum of the 1012 binary blob file 1013- ``type``: The :ref:`type of binary blob <bin-blobs-types>`. Currently limited 1014 to ``img`` or ``lib`` 1015- ``version``: A version string 1016- ``license-path``: Path to the license file for this blob, relative to the root 1017 of the module repository 1018- ``url``: URL that identifies the location the blob will be fetched from, as 1019 well as the fetching scheme to use 1020- ``description``: Human-readable description of the binary blob 1021- ``doc-url``: A URL pointing to the location of the official documentation for 1022 this blob 1023 1024Package manager dependencies 1025============================ 1026 1027Zephyr modules can describe dependencies available from package managers, 1028currently only ``pip`` is supported. 1029 1030A west extension command ``west packages <manager>`` is available to list 1031dependencies for Zephyr and present modules that leverage this feature in their 1032``module.yml`` file. 1033Run ``west help packages`` for more details. 1034 1035Python pip 1036---------- 1037 1038Calling ``west packages pip`` lists `requirement files`_ for Zephyr and modules. 1039Passing ``--install`` installs these if there's an active virtual environment. 1040 1041The following example demonstrates a ``zephyr/module.yml`` file with some 1042requirement files in the ``scripts`` directory of the module. 1043 1044 1045.. code-block:: yaml 1046 1047 package-managers: 1048 pip: 1049 requirement-files: 1050 - scripts/requirements-build.txt 1051 - scripts/requirements-doc.txt 1052 1053Module Inclusion 1054================ 1055 1056.. _modules_using_west: 1057 1058Using West 1059---------- 1060 1061If west is installed and :makevar:`ZEPHYR_MODULES` is not already set, the 1062build system finds all the modules in your :term:`west installation` and uses 1063those. It does this by running :ref:`west list <west-built-in-misc>` to get 1064the paths of all the projects in the installation, then filters the results to 1065just those projects which have the necessary module metadata files. 1066 1067Each project in the ``west list`` output is tested like this: 1068 1069- If the project contains a file named :file:`zephyr/module.yml`, then the 1070 content of that file will be used to determine which files should be added 1071 to the build, as described in the previous section. 1072 1073- Otherwise (i.e. if the project has no :file:`zephyr/module.yml`), the 1074 build system looks for :file:`zephyr/CMakeLists.txt` and 1075 :file:`zephyr/Kconfig` files in the project. If both are present, the project 1076 is considered a module, and those files will be added to the build. 1077 1078- If neither of those checks succeed, the project is not considered a module, 1079 and is not added to :makevar:`ZEPHYR_MODULES`. 1080 1081.. _modules_without_west: 1082 1083Without West 1084------------ 1085 1086If you don't have west installed or don't want the build system to use it to 1087find Zephyr modules, you can set :makevar:`ZEPHYR_MODULES` yourself using one 1088of the following options. Each of the directories in the list must contain 1089either a :file:`zephyr/module.yml` file or the files 1090:file:`zephyr/CMakeLists.txt` and :file:`Kconfig`, as described in the previous 1091section. 1092 1093#. At the CMake command line, like this: 1094 1095 .. code-block:: console 1096 1097 cmake -DZEPHYR_MODULES=<path-to-module1>[;<path-to-module2>[...]] ... 1098 1099#. At the top of your application's top level :file:`CMakeLists.txt`, like this: 1100 1101 .. code-block:: cmake 1102 1103 set(ZEPHYR_MODULES <path-to-module1> <path-to-module2> [...]) 1104 find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 1105 1106 If you choose this option, make sure to set the variable **before** calling 1107 ``find_package(Zephyr ...)``, as shown above. 1108 1109#. In a separate CMake script which is pre-loaded to populate the CMake cache, 1110 like this: 1111 1112 .. code-block:: cmake 1113 1114 # Put this in a file with a name like "zephyr-modules.cmake" 1115 set(ZEPHYR_MODULES <path-to-module1> <path-to-module2> 1116 CACHE STRING "pre-cached modules") 1117 1118 You can tell the build system to use this file by adding ``-C 1119 zephyr-modules.cmake`` to your CMake command line. 1120 1121Not using modules 1122----------------- 1123 1124If you don't have west installed and don't specify :makevar:`ZEPHYR_MODULES` 1125yourself, then no additional modules are added to the build. You will still be 1126able to build any applications that don't require code or Kconfig options 1127defined in an external repository. 1128 1129Submitting changes to modules 1130****************************** 1131 1132When submitting new or making changes to existing modules the main repository 1133Zephyr needs a reference to the changes to be able to verify the changes. In the 1134main tree this is done using revisions. For code that is already merged and part 1135of the tree we use the commit hash, a tag, or a branch name. For pull requests 1136however, we require specifying the pull request number in the revision field to 1137allow building the zephyr main tree with the changes submitted to the 1138module. 1139 1140To avoid merging changes to master with pull request information, the pull 1141request should be marked as ``DNM`` (Do Not Merge) or preferably a draft pull 1142request to make sure it is not merged by mistake and to allow for the module to 1143be merged first and be assigned a permanent commit hash. Drafts reduce noise by 1144not automatically notifying anyone until marked as "Ready for review". 1145Once the module is 1146merged, the revision will need to be changed either by the submitter or by the 1147maintainer to the commit hash of the module which reflects the changes. 1148 1149Note that multiple and dependent changes to different modules can be submitted 1150using exactly the same process. In this case you will change multiple entries of 1151all modules that have a pull request against them. 1152 1153.. _submitting_new_modules: 1154 1155Process for submitting a new module 1156=================================== 1157 1158Please follow the process in :ref:`external-src-process` and obtain the TSC 1159approval to integrate the external source code as a module 1160 1161If the request is approved, a new repository will 1162created by the project team and initialized with basic information that would 1163allow submitting code to the module project following the project contribution 1164guidelines. 1165 1166If a module is maintained as a fork of another project on Github, the Zephyr 1167module related files and changes in relation to upstream need to be maintained 1168in a special branch named ``zephyr``. 1169 1170Maintainers from the Zephyr project will create the repository and initialize 1171it. You will be added as a collaborator in the new repository. Submit the 1172module content (code) to the new repository following the guidelines described 1173:ref:`here <modules_using_west>`, and then add a new entry to the 1174:zephyr_file:`west.yml` with the following information: 1175 1176 .. code-block:: console 1177 1178 - name: <name of repository> 1179 path: <path to where the repository should be cloned> 1180 revision: <ref pointer to module pull request> 1181 1182 1183For example, to add *my_module* to the manifest: 1184 1185.. code-block:: console 1186 1187 - name: my_module 1188 path: modules/lib/my_module 1189 revision: pull/23/head 1190 1191 1192Where 23 in the example above indicated the pull request number submitted to the 1193*my_module* repository. Once the module changes are reviewed and merged, the 1194revision needs to be changed to the commit hash from the module repository. 1195 1196.. _changes_to_existing_module: 1197 1198Process for submitting changes to existing modules 1199================================================== 1200 1201#. Submit the changes using a pull request to an existing repository following 1202 the :ref:`contribution guidelines <contribute_guidelines>` and 1203 :ref:`expectations <contributor-expectations>`. 1204#. Submit a pull request changing the entry referencing the module into the 1205 :zephyr_file:`west.yml` of the main Zephyr tree with the following 1206 information: 1207 1208 .. code-block:: console 1209 1210 - name: <name of repository> 1211 path: <path to where the repository should be cloned> 1212 revision: <ref pointer to module pull request> 1213 1214 1215For example, to add *my_module* to the manifest: 1216 1217.. code-block:: console 1218 1219 - name: my_module 1220 path: modules/lib/my_module 1221 revision: pull/23/head 1222 1223Where 23 in the example above indicated the pull request number submitted to the 1224*my_module* repository. Once the module changes are reviewed and merged, the 1225revision needs to be changed to the commit hash from the module repository. 1226 1227 1228 1229.. _CMake list: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#lists 1230.. _add_subdirectory(): https://cmake.org/cmake/help/latest/command/add_subdirectory.html 1231.. _GitHub issues: https://github.com/zephyrproject-rtos/zephyr/issues 1232.. _requirement files: https://pip.pypa.io/en/stable/reference/requirements-file-format/ 1233