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.. code-block:: none
239
240   Could not find a configuration file for package "Zephyr" that is compatible
241   with requested version "2.z".
242
243   The following configuration files were considered but not accepted:
244
245     <projects>/zephyr-workspace-2.a/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.a.0
246     <projects>/zephyr-workspace-2.b/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake, version: 2.b.0
247
248
249.. note:: It can also be beneficial to specify a version number for Zephyr repository applications
250          and Zephyr workspace applications. Specifying a version in those cases ensures the
251	  application will only build if the Zephyr repository or workspace is matching.
252	  This can be useful to avoid accidental builds when only part of a workspace has been
253	  updated.
254
255
256Multiple Zephyr Installations (Zephyr workspace)
257************************************************
258
259Testing out a new Zephyr version, while at the same time keeping the existing Zephyr in the
260workspace untouched is sometimes beneficial.
261
262Or having both an upstream Zephyr, Vendor specific, and a custom Zephyr in same workspace.
263
264For example:
265
266.. code-block:: none
267
268   <projects>/zephyr-workspace
269   ├── zephyr
270   ├── zephyr-vendor
271   ├── zephyr-custom
272   ├── ...
273   └── my_applications
274        └── my_first_app
275
276
277in this setup, ``find_package(Zephyr)`` has the following order of precedence for selecting
278which Zephyr to use:
279
280* Project name: ``zephyr``
281* First project, when Zephyr projects are ordered lexicographical, in this case.
282
283  * ``zephyr-custom``
284  * ``zephyr-vendor``
285
286This means that ``my_first_app`` will use ``<projects>/zephyr-workspace/zephyr``.
287
288It is possible to specify a Zephyr preference list in the application.
289
290A Zephyr preference list can be specified as:
291
292.. code-block:: cmake
293
294   set(ZEPHYR_PREFER "zephyr-custom" "zephyr-vendor")
295   find_package(Zephyr)
296
297   project(my_first_app)
298
299
300the ``ZEPHYR_PREFER`` is a list, allowing for multiple Zephyrs.
301If a Zephyr is specified in the list, but not found in the system, it is simply ignored and
302``find_package(Zephyr)`` will continue to the next candidate.
303
304
305This allows for temporary creation of a new Zephyr release to be tested, without touching current
306Zephyr. When testing is done, the ``zephyr-test`` folder can simply be removed.
307Such a CMakeLists.txt could look as:
308
309.. code-block:: cmake
310
311   set(ZEPHYR_PREFER "zephyr-test")
312   find_package(Zephyr)
313
314   project(my_first_app)
315
316.. _cmake_build_config_package:
317
318Zephyr Build Configuration CMake packages
319*****************************************
320
321There are two Zephyr Build configuration packages which provide control over the build
322settings in Zephyr in a more generic way. These packages are:
323
324* **ZephyrBuildConfiguration**: Applies to all Zephyr applications in the workspace
325* **ZephyrAppConfiguration**: Applies only to the application you are currently building
326
327They are similar to the per-user :file:`.zephyrrc` file that can be used to set :ref:`env_vars`,
328but they set CMake variables instead. They also allow you to automatically share the build
329configuration among all users through the project repository. They also allow more advanced use
330cases, such as loading of additional CMake boilerplate code.
331
332The Zephyr Build Configuration CMake packages will be loaded in the Zephyr boilerplate code after
333initial properties and ``ZEPHYR_BASE`` has been defined, but before CMake code execution. The
334ZephyrBuildConfiguration is included first and ZephyrAppConfiguration afterwards. That means the
335application-specific package could override the workspace settings, if needed.
336This allows the Zephyr Build Configuration CMake packages to setup or extend properties such as:
337``DTS_ROOT``, ``BOARD_ROOT``, ``TOOLCHAIN_ROOT`` / other toolchain setup, fixed overlays, and any
338other property that can be controlled. It also allows inclusion of additional boilerplate code.
339
340To provide a ZephyrBuildConfiguration or ZephyrAppConfiguration, create
341:file:`ZephyrBuildConfig.cmake` and/or :file:`ZephyrAppConfig.cmake` respectively and place them
342in the appropriate location. The CMake ``find_package`` mechanism will search for these files with
343the steps below. Other default CMake package search paths and hints are disabled and there is no
344version checking implemented for these packages. This also means that these packages cannot be
345installed in the CMake package registry. The search steps are:
346
3471. If ``ZephyrBuildConfiguration_ROOT``, or ``ZephyrAppConfiguration_ROOT`` respectively, is set,
348   search within this prefix path. If a matching file is found, execute this file. If no matching
349   file is found, go to step 2.
3502. Search within ``${ZEPHYR_BASE}/../*``, or ``${APPLICATION_SOURCE_DIR}`` respectively. If a
351   matching file is found, execute this file. If no matching file is found, abort the search.
352
353It is recommended to place the files in the default paths from step 2, but with the
354``<PackageName>_ROOT`` variables you have the flexibility to place them anywhere. This is
355especially necessary for freestanding applications, for which the default path to
356ZephyrBuildConfiguration usually does not work. In this case the ``<PackageName>_ROOT`` variables
357can be set on the CMake command line, **before** ``find_package(Zephyr ...)``, as environment
358variable or from a CMake cache initialization file with the ``-C`` command line option.
359
360.. note:: The ``<PackageName>_ROOT`` variables, as well as the default paths, are just the prefixes
361   to the search path. These prefixes get combined with additional path suffixes, which together
362   form the actual search path. Any combination that honors the
363   `CMake package search procedure`_ is valid and will work.
364
365If you want to completely disable the search for these packages, you can use the special CMake
366``CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`` variable for that. Just set
367``CMAKE_DISABLE_FIND_PACKAGE_ZephyrBuildConfiguration`` or
368``CMAKE_DISABLE_FIND_PACKAGE_ZephyrAppConfiguration`` to ``TRUE`` to disable the package.
369
370An example folder structure could look like this:
371
372.. code-block:: none
373
374   <projects>/zephyr-workspace
375   ├── zephyr
376   ├── ...
377   ├── manifest repo (can be named anything)
378   │    └── cmake/ZephyrBuildConfig.cmake
379   ├── ...
380   └── zephyr application
381        └── share/zephyrapp-package/cmake/ZephyrAppConfig.cmake
382
383A sample :file:`ZephyrBuildConfig.cmake` can be seen below.
384
385.. code-block:: cmake
386
387   # ZephyrBuildConfig.cmake sample code
388
389   # To ensure final path is absolute and does not contain ../.. in variable.
390   get_filename_component(APPLICATION_PROJECT_DIR
391                          ${CMAKE_CURRENT_LIST_DIR}/../../..
392                          ABSOLUTE
393   )
394
395   # Add this project to list of board roots
396   list(APPEND BOARD_ROOT ${APPLICATION_PROJECT_DIR})
397
398   # Default to GNU Arm Embedded toolchain if no toolchain is set
399   if(NOT ENV{ZEPHYR_TOOLCHAIN_VARIANT})
400       set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
401       find_program(GNU_ARM_GCC arm-none-eabi-gcc)
402       if(NOT ${GNU_ARM_GCC} STREQUAL GNU_ARM_GCC-NOTFOUND)
403           # The toolchain root is located above the path to the compiler.
404           get_filename_component(GNUARMEMB_TOOLCHAIN_PATH ${GNU_ARM_GCC}/../.. ABSOLUTE)
405       endif()
406   endif()
407
408Zephyr CMake package source code
409********************************
410
411The Zephyr CMake package source code in
412:zephyr_file:`share/zephyr-package/cmake` and
413:zephyr_file:`share/zephyrunittest-package/cmake` contains the CMake config
414package which is used by the CMake ``find_package`` function.
415
416It also contains code for exporting Zephyr as a CMake config package.
417
418The following is an overview of the files in these directories:
419
420:file:`ZephyrConfigVersion.cmake`
421    The Zephyr package version file. This file is called by CMake to determine
422    if this installation fulfils the requirements specified by user when calling
423    ``find_package(Zephyr ...)``. It is also responsible for detection of Zephyr
424    repository or workspace only installations.
425
426:file:`ZephyrUnittestConfigVersion.cmake`
427    Same responsibility as ``ZephyrConfigVersion.cmake``, but for unit tests.
428    Includes ``ZephyrConfigVersion.cmake``.
429
430:file:`ZephyrConfig.cmake`
431    The Zephyr package file. This file is called by CMake to for the package
432    meeting which fulfils the requirements specified by user when calling
433    ``find_package(Zephyr ...)``. This file is responsible for sourcing of
434    boilerplate code.
435
436:file:`ZephyrUnittestConfig.cmake`
437    Same responsibility as ``ZephyrConfig.cmake``, but for unit tests.
438    Includes ``ZephyrConfig.cmake``.
439
440:file:`zephyr_package_search.cmake`
441   Common file used for detection of Zephyr repository and workspace candidates.
442   Used by ``ZephyrConfigVersion.cmake`` and ``ZephyrConfig.cmake`` for common code.
443
444:file:`zephyr_export.cmake`
445   See :ref:`zephyr_cmake_package_export`.
446
447.. _CMake package: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html
448.. _CMake user package registry: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#user-package-registry
449.. _CMake package version: https://cmake.org/cmake/help/latest/command/find_package.html#version-selection
450.. _CMake package search procedure: https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
451