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