1.. _cmake_pkg:
2
3Zephyr CMake Package
4####################
5
6The Zephyr `CMake package`_ is a convenient way to create a Zephyr-based application.
7
8.. note::
9   The :ref:`zephyr-app-types` section introduces the application types
10   used in this page.
11
12The Zephyr CMake package ensures that CMake can automatically select a Zephyr installation to use for building
13the application, whether it is a :ref:`Zephyr repository application <zephyr-repo-app>`,
14a :ref:`Zephyr workspace application <zephyr-workspace-app>`, or a
15:ref:`Zephyr freestanding application <zephyr-freestanding-app>`.
16
17When developing a Zephyr-based application, then a developer simply needs to write
18``find_package(Zephyr)`` in the beginning of the application :file:`CMakeLists.txt` file.
19
20To use the Zephyr CMake package it must first be exported to the `CMake user package registry`_.
21This is means creating a reference to the current Zephyr installation inside the
22CMake user package registry.
23
24
25.. tabs::
26
27   .. group-tab:: Ubuntu
28
29      In Linux, the CMake user package registry is found in:
30
31      ``~/.cmake/packages/Zephyr``
32
33   .. group-tab:: macOS
34
35      In macOS, the CMake user package registry is found in:
36
37      ``~/.cmake/packages/Zephyr``
38
39   .. group-tab:: Windows
40
41      In Windows, the CMake user package registry is found in:
42
43      ``HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\Zephyr``
44
45
46The Zephyr CMake package allows CMake to automatically find a Zephyr base.
47One or more Zephyr installations must be exported.
48Exporting multiple Zephyr installations may be useful when developing or testing
49Zephyr freestanding applications, Zephyr workspace application with vendor forks, etc..
50
51
52Zephyr CMake package export (west)
53**********************************
54
55When installing Zephyr using :ref:`west <get_the_code>` then it is recommended
56to export Zephyr using ``west zephyr-export``.
57
58.. _zephyr_cmake_package_export:
59
60Zephyr CMake package export (without west)
61******************************************
62
63Zephyr CMake package is exported to the CMake user package registry using the following commands:
64
65.. code-block:: bash
66
67   cmake -P <PATH-TO-ZEPHYR>/share/zephyr-package/cmake/zephyr_export.cmake
68
69This will export the current Zephyr to the CMake user package registry.
70
71To also export the Zephyr Unittest CMake package, run the following command in addition:
72
73.. code-block:: bash
74
75   cmake -P <PATH-TO-ZEPHYR>/share/zephyrunittest-package/cmake/zephyr_export.cmake
76
77.. _zephyr_cmake_package_zephyr_base:
78
79Zephyr Base Environment Setting
80*******************************
81
82The Zephyr CMake package search functionality allows for explicitly specifying
83a Zephyr base using an environment variable.
84
85To do this, use the following ``find_package()`` syntax:
86
87.. code-block:: cmake
88
89   find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
90
91This syntax instructs CMake to first search for Zephyr using the Zephyr base environment setting
92:envvar:`ZEPHYR_BASE` and then use the normal search paths.
93
94.. _zephyr_cmake_search_order:
95
96Zephyr CMake Package Search Order
97*********************************
98
99When Zephyr base environment setting is not used for searching, the Zephyr installation matching
100the following criteria will be used:
101
102* A Zephyr repository application will use the Zephyr in which it is located.
103  For example:
104
105  .. code-block:: none
106
107        <projects>/zephyr-workspace/zephyr
108        └── samples
109            └── hello_world
110
111  in this example, ``hello_world`` will use ``<projects>/zephyr-workspace/zephyr``.
112
113
114* Zephyr workspace application will use the Zephyr that share the same workspace.
115  For example:
116
117  .. code-block:: none
118
119     <projects>/zephyr-workspace
120     ├── zephyr
121     ├── ...
122     └── my_applications
123          └── my_first_app
124
125  in this example, ``my_first_app`` will use ``<projects>/zephyr-workspace/zephyr`` as this Zephyr
126  is located in the same workspace as the Zephyr workspace application.
127
128.. note::
129   The root of a Zephyr workspace is identical to ``west topdir`` if the workspace was
130   installed using ``west``
131
132* Zephyr freestanding application will use the Zephyr registered in the CMake user package registry.
133  For example:
134
135  .. code-block:: none
136
137     <projects>/zephyr-workspace-1
138     └── zephyr                       (Not exported to CMake)
139
140     <projects>/zephyr-workspace-2
141     └── zephyr                       (Exported to CMake)
142
143     <home>/app
144     ├── CMakeLists.txt
145     ├── prj.conf
146     └── src
147         └── main.c
148
149  in this example, only ``<projects>/zephyr-workspace-2/zephyr`` is exported to the CMake package
150  registry and therefore this Zephyr will be used by the Zephyr freestanding application
151  ``<home>/app``.
152
153  If user wants to test the application with ``<projects>/zephyr-workspace-1/zephyr``, this can be
154  done by using the Zephyr Base environment setting, meaning set
155  ``ZEPHYR_BASE=<projects>/zephyr-workspace-1/zephyr``, before
156  running CMake.
157
158  .. note::
159
160     The Zephyr package selected on the first CMake invocation will be used for all subsequent
161     builds. To change the Zephyr package, for example to test the application using Zephyr base
162     environment setting, then it is necessary to do a pristine build first
163     (See :ref:`application_rebuild`).
164
165Zephyr CMake Package Version
166****************************
167
168When writing an application then it is possible to specify a Zephyr version number ``x.y.z`` that
169must be used in order to build the application.
170
171Specifying a version is especially useful for a Zephyr freestanding application as it ensures the
172application is built with a minimal Zephyr version.
173
174It also helps CMake to select the correct Zephyr to use for building, when there are multiple
175Zephyr installations in the system.
176
177For example:
178
179  .. code-block:: cmake
180
181     find_package(Zephyr 2.2.0)
182     project(app)
183
184will require ``app`` to be built with Zephyr 2.2.0 as minimum.
185CMake will search all exported candidates to find a Zephyr installation which matches this version
186criteria.
187
188Thus it is possible to have multiple Zephyr installations and have CMake automatically select
189between them based on the version number provided, see `CMake package version`_ for details.
190
191For example:
192
193.. code-block:: none
194
195   <projects>/zephyr-workspace-2.a
196   └── zephyr                       (Exported to CMake)
197
198   <projects>/zephyr-workspace-2.b
199   └── zephyr                       (Exported to CMake)
200
201   <home>/app
202   ├── CMakeLists.txt
203   ├── prj.conf
204   └── src
205       └── main.c
206
207in this case, there are two released versions of Zephyr installed at their own workspaces.
208Workspace 2.a and 2.b, corresponding to the Zephyr version.
209
210To ensure ``app`` is built with minimum version ``2.a`` the following ``find_package``
211syntax may be used:
212
213.. code-block:: cmake
214
215   find_package(Zephyr 2.a)
216   project(app)
217
218
219Note that both ``2.a`` and ``2.b`` fulfill this requirement.
220
221CMake also supports the keyword ``EXACT``, to ensure an exact version is used, if that is required.
222In this case, the application CMakeLists.txt could be written as:
223
224.. code-block:: cmake
225
226   find_package(Zephyr 2.a EXACT)
227   project(app)
228
229In case no Zephyr is found which satisfies the version required, as example, the application specifies
230
231.. code-block:: cmake
232
233   find_package(Zephyr 2.z)
234   project(app)
235
236then an error similar to below will be printed::
237
238  Could not find a configuration file for package "Zephyr" that is compatible
239  with requested version "2.z".
240
241  The following configuration files were considered but not accepted:
242
243    <projects>/zephyr-workspace-2.a/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.a.0
244    <projects>/zephyr-workspace-2.b/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.b.0
245
246
247.. note:: It can also be beneficial to specify a version number for Zephyr repository applications
248          and Zephyr workspace applications. Specifying a version in those cases ensures the
249	  application will only build if the Zephyr repository or workspace is matching.
250	  This can be useful to avoid accidental builds when only part of a workspace has been
251	  updated.
252
253
254Multiple Zephyr Installations (Zephyr workspace)
255************************************************
256
257Testing out a new Zephyr version, while at the same time keeping the existing Zephyr in the
258workspace untouched is sometimes beneficial.
259
260Or having both an upstream Zephyr, Vendor specific, and a custom Zephyr in same workspace.
261
262For example:
263
264.. code-block:: none
265
266   <projects>/zephyr-workspace
267   ├── zephyr
268   ├── zephyr-vendor
269   ├── zephyr-custom
270   ├── ...
271   └── my_applications
272        └── my_first_app
273
274
275in this setup, ``find_package(Zephyr)`` has the following order of precedence for selecting
276which Zephyr to use:
277
278* Project name: ``zephyr``
279* First project, when Zephyr projects are ordered lexicographical, in this case.
280
281  * ``zephyr-custom``
282  * ``zephyr-vendor``
283
284This means that ``my_first_app`` will use ``<projects>/zephyr-workspace/zephyr``.
285
286It is possible to specify a Zephyr preference list in the application.
287
288A Zephyr preference list can be specified as:
289
290.. code-block:: cmake
291
292   set(ZEPHYR_PREFER "zephyr-custom" "zephyr-vendor")
293   find_package(Zephyr)
294
295   project(my_first_app)
296
297
298the ``ZEPHYR_PREFER`` is a list, allowing for multiple Zephyrs.
299If a Zephyr is specified in the list, but not found in the system, it is simply ignored and
300``find_package(Zephyr)`` will continue to the next candidate.
301
302
303This allows for temporary creation of a new Zephyr release to be tested, without touching current
304Zephyr. When testing is done, the ``zephyr-test`` folder can simply be removed.
305Such a CMakeLists.txt could look as:
306
307.. code-block:: cmake
308
309   set(ZEPHYR_PREFER "zephyr-test")
310   find_package(Zephyr)
311
312   project(my_first_app)
313
314.. _cmake_build_config_package:
315
316Zephyr Build Configuration CMake package
317****************************************
318
319The Zephyr Build Configuration CMake package provides a possibility for a Zephyr based project to
320control Zephyr build settings in a generic way.
321
322It is similar to the per-user ``.zephyrrc`` file that can be used to set :ref:`env_vars`, but it
323sets CMake variables instead. It also allows you to automatically share the build configuration
324among all users through the project repository. It also allows more advanced use cases, such as loading
325of additional CMake boilerplate code.
326
327The Zephyr Build Configuration CMake package will be loaded in the Zephyr boilerplate code after
328initial properties and ``ZEPHYR_BASE`` has been defined, but before CMake code execution.
329This allows the Zephyr Build Configuration CMake package to setup or extend properties such as:
330``DTS_ROOT``, ``BOARD_ROOT``, ``TOOLCHAIN_ROOT`` / other toolchain setup, fixed overlays, and any
331other property that can be controlled. It also allows inclusion of additional boilerplate code.
332
333To provide a Zephyr Build Configuration CMake package, create ``ZephyrBuildConfig.cmake`` and place
334it in a Zephyr workspace top-level folder as:
335
336.. code-block:: none
337
338   <projects>/zephyr-workspace
339   ├── zephyr
340   ├── ...
341   └── zephyr application (can be named anything)
342        └── share/zephyrbuild-package/cmake/ZephyrBuildConfig.cmake
343
344The Zephyr Build Configuration CMake package will not search in any CMake default search paths, and
345thus cannot be installed in the CMake package registry. There will be no version checking on the
346Zephyr Build Configuration package.
347
348.. note:: ``share/zephyrbuild-package/cmake/ZephyrBuildConfig.cmake`` follows the same folder
349          structure as the Zephyr CMake package.
350
351          It is possible to place ``ZephyrBuildConfig.cmake`` directly in a
352	  ``<zephyr application>/cmake`` folder or another folder, as long as that folder is
353	  honoring the `CMake package search`_ algorithm.
354
355A sample ``ZephyrBuildConfig.cmake`` can be seen below.
356
357.. code-block:: cmake
358
359   # ZephyrBuildConfig.cmake sample code
360
361   # To ensure final path is absolute and does not contain ../.. in variable.
362   get_filename_component(APPLICATION_PROJECT_DIR
363                          ${CMAKE_CURRENT_LIST_DIR}/../../..
364                          ABSOLUTE
365   )
366
367   # Add this project to list of board roots
368   list(APPEND BOARD_ROOT ${APPLICATION_PROJECT_DIR})
369
370   # Default to GNU Arm Embedded toolchain if no toolchain is set
371   if(NOT ENV{ZEPHYR_TOOLCHAIN_VARIANT})
372       set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
373       find_program(GNU_ARM_GCC arm-none-eabi-gcc)
374       if(NOT ${GNU_ARM_GCC} STREQUAL GNU_ARM_GCC-NOTFOUND)
375           # The toolchain root is located above the path to the compiler.
376           get_filename_component(GNUARMEMB_TOOLCHAIN_PATH ${GNU_ARM_GCC}/../.. ABSOLUTE)
377       endif()
378   endif()
379
380Zephyr Build Configuration CMake package (Freestanding application)
381*******************************************************************
382
383The Zephyr Build Configuration CMake package can be located outside a Zephyr
384workspace, for example located with a :ref:`zephyr-freestanding-app`.
385
386Create the build configuration as described in the previous section, and then
387refer to the location of your Zephyr Build Configuration CMake package using
388the CMake variable ``ZephyrBuildConfiguration_ROOT``.
389
390#. At the CMake command line, like this:
391
392   .. code-block:: console
393
394      cmake -DZephyrBuildConfiguration_ROOT=<path-to-build-config> ...
395
396#. At the top of your application's top level :file:`CMakeLists.txt`, like this:
397
398   .. code-block:: cmake
399
400      set(ZephyrBuildConfiguration_ROOT <path-to-build-config>)
401      find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
402
403   If you choose this option, make sure to set the variable **before**  calling
404   ``find_package(Zephyr ...)``, as shown above.
405
406#. In a separate CMake script which is pre-loaded to populate the CMake cache,
407   like this:
408
409   .. code-block:: cmake
410
411      # Put this in a file with a name like "zephyr-settings.cmake"
412      set(ZephyrBuildConfiguration_ROOT <path-to-build-config>
413          CACHE STRING "pre-cached build config"
414      )
415
416   You can tell the build system to use this file by adding ``-C
417   zephyr-settings.cmake`` to your CMake command line.
418   This principle is useful when not using ``west`` as both this setting and
419   Zephyr modules can be specified using the same file.
420   See Zephyr module :ref:`modules_without_west`.
421
422Zephyr CMake package source code
423********************************
424
425The Zephyr CMake package source code in
426:zephyr_file:`share/zephyr-package/cmake` and
427:zephyr_file:`share/zephyrunittest-package/cmake` contains the CMake config
428package which is used by the CMake ``find_package`` function.
429
430It also contains code for exporting Zephyr as a CMake config package.
431
432The following is an overview of the files in these directories:
433
434:file:`ZephyrConfigVersion.cmake`
435    The Zephyr package version file. This file is called by CMake to determine
436    if this installation fulfils the requirements specified by user when calling
437    ``find_package(Zephyr ...)``. It is also responsible for detection of Zephyr
438    repository or workspace only installations.
439
440:file:`ZephyrUnittestConfigVersion.cmake`
441    Same responsibility as ``ZephyrConfigVersion.cmake``, but for unit tests.
442    Includes ``ZephyrConfigVersion.cmake``.
443
444:file:`ZephyrConfig.cmake`
445    The Zephyr package file. This file is called by CMake to for the package
446    meeting which fulfils the requirements specified by user when calling
447    ``find_package(Zephyr ...)``. This file is responsible for sourcing of
448    boilerplate code.
449
450:file:`ZephyrUnittestConfig.cmake`
451    Same responsibility as ``ZephyrConfig.cmake``, but for unit tests.
452    Includes ``ZephyrConfig.cmake``.
453
454:file:`zephyr_package_search.cmake`
455   Common file used for detection of Zephyr repository and workspace candidates.
456   Used by ``ZephyrConfigVersion.cmake`` and ``ZephyrConfig.cmake`` for common code.
457
458:file:`zephyr_export.cmake`
459   See :ref:`zephyr_cmake_package_export`.
460
461.. _CMake package: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html
462.. _CMake user package registry: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#user-package-registry
463.. _CMake package version: https://cmake.org/cmake/help/latest/command/find_package.html#version-selection
464.. _CMake package search: https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
465