Boot Linux faster!

Check our new training course

Boot Linux faster!

Check our new training course
and Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
.. _cmake_pkg:

Zephyr CMake Package
####################

The Zephyr `CMake package`_ is a convenient way to create a Zephyr-based application.

The Zephyr CMake package ensures that CMake can automatically select a Zephyr to use for building
the application, whether it is a Zephyr repository application, Zephyr workspace application, or a
Zephyr freestanding application.

When developing a Zephyr-based application, then a developer simply needs to write
``find_package(Zephyr)`` in the beginning of the application :file:`CMakeLists.txt` file.

To use the Zephyr CMake package it must first be exported to the `CMake user package registry`_.
This is means creating a reference to the current Zephyr installation inside the
CMake user package registry.


.. tabs::

   .. group-tab:: Ubuntu

      In Linux, the CMake user package registry is found in:

      ``~/.cmake/package/Zephyr``

   .. group-tab:: macOS

      In macOS, the CMake user package registry is found in:

      ``~/.cmake/package/Zephyr``

   .. group-tab:: Windows

      In Windows, the CMake user package registry is found in:

      ``HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\Zephyr``


The Zephyr CMake package allows CMake to automatically find a Zephyr base.
One or more Zephyr installations must be exported.
Exporting multiple Zephyr installations may be useful when developing or testing
Zephyr freestanding applications, Zephyr workspace application with vendor forks, etc..


Zephyr CMake package export (west)
**********************************

When installing Zephyr using :ref:`west <get_the_code>` then it is recommended
to export Zephyr using ``west zephyr-export``.


Zephyr CMake package export (without west)
******************************************

Zephyr CMake package is exported to the CMake user package registry using the following commands:

.. code-block:: bash

   cmake -S <PATH-TO-ZEPHYR>/share/zephyr-package/cmake -B <PATH-TO-ZEPHYR>/share/zephyr-package/cmake
   cmake --build <PATH-TO-ZEPHYR>/share/zephyr-package/cmake --target pristine

This will export the current Zephyr to the CMake user package registry and remove the temporary
files generated by CMake during export.

.. _zephyr_cmake_package_zephyr_base:


Zephyr application structure
****************************

An application can be placed anywhere on your disk, but to better understand how the Zephyr
package is used, we will name three specific layouts.


Zephyr repository application
=============================

A Zephyr repository has the following structure:

.. code-block:: none

   <projects>/zephyr-workspace
   └── zephyr
        ├── arch
        ├── boards
        ├── cmake
        ├── samples
        │    ├── hello_world
        │    └── ...
        ├── tests
        └── ...

Any application located inside this tree, is simply referred to as a Zephyr repository application.
In this example ``hello_world`` is a Zephyr repository application.


Zephyr workspace application
============================

A Zephyr workspace has the following structure:

.. code-block:: none

   <projects>/zephyr-workspace
   ├── zephyr
   ├── bootloader
   ├── modules
   ├── tools
   ├── <vendor/private-repositories>
   └── my_applications
        └── my_first_app

Any application located in such workspace, but outside the Zephyr repository itself, is referred to
as a Zephyr workspace application.
In this example ``my_first_app`` is a Zephyr workspace application.

.. note:: The root of a Zephyr workspace is identical to ``west topdir`` if the workspace was
          installed using ``west``


Zephyr freestanding application
===============================

A Zephyr freestanding application is a Zephyr application located outside of a Zephyr workspace.


.. code-block:: none

   <projects>/zephyr-workspace
   ├── zephyr
   ├── bootloader
   └── ...

   <home>/app
   ├── CMakeLists.txt
   ├── prj.conf
   └── src
       └── main.c

In this example ``app`` is a Zephyr freestanding application.


Zephyr Base Environment Setting
*******************************

The Zephyr CMake package search functionality allows for explicitly specifying
a Zephyr base using an environment variable.

To do this, use the following ``find_package()`` syntax:

.. code-block:: cmake

   find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

This syntax instructs CMake to first search for Zephyr using the Zephyr base environment setting
:envvar:`ZEPHYR_BASE` and then use the normal search paths.

.. _zephyr_cmake_search_order:

Zephyr CMake Package Search Order
*********************************

When Zephyr base environment setting is not used for searching, the Zephyr installation matching
the following criteria will be used:

* A Zephyr repository application will use the Zephyr in which it is located.
  For example:

  .. code-block:: none

        <projects>/zephyr-workspace/zephyr
        └── samples
            └── hello_world

  in this example, ``hello_world`` will use ``<projects>/zephyr-workspace/zephyr``.


* Zephyr workspace application will use the Zephyr that share the same workspace.
  For example:

  .. code-block:: none

     <projects>/zephyr-workspace
     ├── zephyr
     ├── ...
     └── my_applications
          └── my_first_app

  in this example, ``my_first_app`` will use ``<projects>/zephyr-workspace/zephyr`` as this Zephyr
  is located in the same workspace as the Zephyr workspace application.


* Zephyr freestanding application will use the Zephyr registered in the CMake user package registry.
  For example:

  .. code-block:: none

     <projects>/zephyr-workspace-1
     └── zephyr                       (Not exported to CMake)

     <projects>/zephyr-workspace-2
     └── zephyr                       (Exported to CMake)

     <home>/app
     ├── CMakeLists.txt
     ├── prj.conf
     └── src
         └── main.c

  in this example, only ``<projects>/zephyr-workspace-2/zephyr`` is exported to the CMake package
  registry and therefore this Zephyr will be used by the Zephyr freestanding application
  ``<home>/app``.

  If user wants to test the application with ``<projects>/zephyr-workspace-1/zephyr``, this can be
  done by using the Zephyr Base environment setting, meaning set
  ``ZEPHYR_BASE=<projects>/zephyr-workspace-1/zephyr``, before
  running CMake.

  .. note::

     The Zephyr package selected on the first CMake invocation will be used for all subsequent
     builds. To change the Zephyr package, for example to test the application using Zephyr base
     environment setting, then it is necessary to do a pristine build first
     (See :ref:`application_rebuild`).

Zephyr CMake Package Version
****************************

When writing an application then it is possible to specify a Zephyr version number ``x.y.z`` that
must be used in order to build the application.

Specifying a version is especially useful for a Zephyr freestanding application as it ensures the
application is built with a minimal Zephyr version.

It also helps CMake to select the correct Zephyr to use for building, when there are multiple
Zephyr installations in the system.

For example:

  .. code-block:: cmake

     cmake_minimum_required(VERSION 3.13.1)
     find_package(Zephyr 2.2.0)
     project(app)

will require ``app`` to be built with Zephyr 2.2.0 as minimum.
CMake will search all exported candidates to find a Zephyr installation which matches this version
criteria.

Thus it is possible to have multiple Zephyr installations and have CMake automatically select
between them based on the version number provided, see `CMake package version`_ for details.

For example:

.. code-block:: none

   <projects>/zephyr-workspace-2.a
   └── zephyr                       (Exported to CMake)

   <projects>/zephyr-workspace-2.b
   └── zephyr                       (Exported to CMake)

   <home>/app
   ├── CMakeLists.txt
   ├── prj.conf
   └── src
       └── main.c

in this case, there are two released versions of Zephyr installed at their own workspaces.
Workspace 2.a and 2.b, corresponding to the Zephyr version.

To ensure ``app`` is built with minimum version ``2.a`` the following ``find_package``
syntax may be used:

.. code-block:: cmake

   cmake_minimum_required(VERSION 3.13.1)
   find_package(Zephyr 2.a)
   project(app)


Note that both ``2.a`` and ``2.b`` fulfill this requirement.

CMake also supports the keyword ``EXACT``, to ensure an exact version is used, if that is required.
In this case, the application CMakeLists.txt could be written as:

.. code-block:: cmake

   cmake_minimum_required(VERSION 3.13.1)
   find_package(Zephyr 2.a EXACT)
   project(app)

In case no Zephyr is found which satisfies the version required, as example, the application specifies

.. code-block:: cmake

   cmake_minimum_required(VERSION 3.13.1)
   find_package(Zephyr 2.z)
   project(app)

then an error similar to below will be printed::

  Could not find a configuration file for package "Zephyr" that is compatible
  with requested version "2.z".

  The following configuration files were considered but not accepted:

    <projects>/zephyr-workspace-2.a/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.a.0
    <projects>/zephyr-workspace-2.b/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.b.0


.. note:: It can also be beneficial to specify a version number for Zephyr repository applications
          and Zephyr workspace applications. Specifying a version in those cases ensures the
	  application will only build if the Zephyr repository or workspace is matching.
	  This can be useful to avoid accidental builds when only part of a workspace has been
	  updated.


Multiple Zephyr Installations (Zephyr workspace)
************************************************

Testing out a new Zephyr version, while at the same time keeping the existing Zephyr in the
workspace untouched is sometimes beneficial.

Or having both an upstream Zephyr, Vendor specific, and a custom Zephyr in same workspace.

For example:

.. code-block:: none

   <projects>/zephyr-workspace
   ├── zephyr
   ├── zephyr-vendor
   ├── zephyr-custom
   ├── ...
   └── my_applications
        └── my_first_app


in this setup, ``find_package(Zephyr)`` has the following order of precedence for selecting
which Zephyr to use:

* Project name: ``zephyr``
* First project, when Zephyr projects are ordered lexicographical, in this case.

  * ``zephyr-custom``
  * ``zephyr-vendor``

This means that ``my_first_app`` will use ``<projects>/zephyr-workspace/zephyr``.

It is possible to specify a Zephyr preference list in the application.

A Zephyr preference list can be specified as:

.. code-block:: cmake

   cmake_minimum_required(VERSION 3.13.1)

   set(ZEPHYR_PREFER "zephyr-custom" "zephyr-vendor")
   find_package(Zephyr)

   project(my_first_app)


the ``ZEPHYR_PREFER`` is a list, allowing for multiple Zephyrs.
If a Zephyr is specified in the list, but not found in the system, it is simply ignored and
``find_package(Zephyr)`` will continue to the next candidate.


This allows for temporary creation of a new Zephyr release to be tested, without touching current
Zephyr. When testing is done, the ``zephyr-test`` folder can simply be removed.
Such a CMakeLists.txt could look as:

.. code-block:: cmake

   cmake_minimum_required(VERSION 3.13.1)

   set(ZEPHYR_PREFER "zephyr-test")
   find_package(Zephyr)

   project(my_first_app)

.. _cmake_build_config_package:

Zephyr Build Configuration CMake package
****************************************

The Zephyr Build Configuration CMake package provides a possibility for a Zephyr based project to
control Zephyr build settings in a generic way.

It is similar to the use of ``.zephyrrc`` but with the possibility to automatically allow all users
to share the build configuration through the project repository.
But it also allows more advanced use cases than a ``.zephyrrc``-file, such as loading of additional
CMake boilerplate code.

The Zephyr Build Configuration CMake package will be loaded in the Zephyr boilerplate code after
initial properties and ``ZEPHYR_BASE`` has been defined, but before CMake code execution.
This allows the Zephyr Build Configuration CMake package to setup or extend properties such as:
``DTS_ROOT``, ``BOARD_ROOT``, ``TOOLCHAIN_ROOT`` / other toolchain setup, fixed overlays, and any
other property that can be controlled. It also allows inclusion of additional boilerplate code.

To provide a Zephyr Build Configuration CMake package, create ``ZephyrBuildConfig.cmake`` and place
it in a Zephyr workspace top-level folder as:

.. code-block:: none

   <projects>/zephyr-workspace
   ├── zephyr
   ├── ...
   └── zephyr application (can be named anything)
        └── share/zephyrbuild-package/cmake/ZephyrBuildConfig.cmake

The Zephyr Build Configuration CMake package will not search in any CMake default search paths, and
thus cannot be installed in the CMake package registry. There will be no version checking on the
Zephyr Build Configuration package.

.. note:: ``share/zephyrbuild-package/cmake/ZephyrBuildConfig.cmake`` follows the same folder
          structure as the Zephyr CMake package.

          It is possible to place ``ZephyrBuildConfig.cmake`` directly in a
	  ``<zephyr application>/cmake`` folder or another folder, as long as that folder is
	  honoring the `CMake package search`_ algorithm.

A sample ``ZephyrBuildConfig.cmake`` can be seen below.

.. code-block:: cmake

   # ZephyrBuildConfig.cmake sample code

   # To ensure final path is absolute and does not contain ../.. in variable.
   get_filename_component(APPLICATION_PROJECT_DIR
                          ${CMAKE_CURRENT_LIST_DIR}/../../..
                          ABSOLUTE
   )

   # Add this project to list of board roots
   list(APPEND BOARD_ROOT ${APPLICATION_PROJECT_DIR})

   # Default to GNU Arm Embedded toolchain if no toolchain is set
   if(NOT ENV{ZEPHYR_TOOLCHAIN_VARIANT})
       set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
       find_program(GNU_ARM_GCC arm-none-eabi-gcc)
       if(NOT ${GNU_ARM_GCC} STREQUAL GNU_ARM_GCC-NOTFOUND)
           # The toolchain root is located above the path to the compiler.
           get_filename_component(GNUARMEMB_TOOLCHAIN_PATH ${GNU_ARM_GCC}/../.. ABSOLUTE)
       endif()
   endif()

Zephyr CMake package source code
********************************

The Zephyr CMake package source code in
``<PATH-TO-ZEPHYR>/share/zephyr-package/cmake`` contains the CMake config package
which is used by CMake ``find_package`` function.

It also contains code for exporting Zephyr as a CMake config package.

The following is an overview of those files

:file:`CMakeLists.txt`
    The CMakeLists.txt file for the CMake build system which is responsible for
    exporting Zephyr as a package to the CMake user package registry.

:file:`ZephyrConfigVersion.cmake`
    The Zephyr package version file. This file is called by CMake to determine
    if this installation fulfils the requirements specified by user when calling
    ``find_package(Zephyr ...)``. It is also responsible for detection of Zephyr
    repository or workspace only installations.

:file:`ZephyrUnittestConfigVersion.cmake`
    Same responsibility as ``ZephyrConfigVersion.cmake``, but for unit tests.
    Includes ``ZephyrConfigVersion.cmake``.

:file:`ZephyrConfig.cmake`
    The Zephyr package file. This file is called by CMake to for the package
    meeting which fulfils the requirements specified by user when calling
    ``find_package(Zephyr ...)``. This file is responsible for sourcing of
    boilerplate code.

:file:`ZephyrUnittestConfig.cmake`
    Same responsibility as ``ZephyrConfig.cmake``, but for unit tests.
    Includes ``ZephyrConfig.cmake``.

:file:`zephyr_package_search.cmake`
   Common file used for detection of Zephyr repository and workspace candidates.
   Used by ``ZephyrConfigVersion.cmake`` and ``ZephyrConfig.cmake`` for common code.

:file:`pristine.cmake`
   Pristine file for removing all files created by CMake during configure and generator time when
   exporting Zephyr CMake package. Running pristine keeps all package related files mentioned above.

.. _CMake package: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html
.. _CMake user package registry: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#user-package-registry
.. _CMake package version: https://cmake.org/cmake/help/latest/command/find_package.html#version-selection
.. _CMake package search: https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure