451 lines
16 KiB
ReStructuredText
451 lines
16 KiB
ReStructuredText
.. _cmake_pkg:
|
|
|
|
Zephyr CMake Package
|
|
####################
|
|
|
|
The Zephyr `CMake package`_ is a convenient way to create a Zephyr-based application.
|
|
|
|
.. note::
|
|
The :ref:`zephyr-app-types` section introduces the application types
|
|
used in this page.
|
|
|
|
The Zephyr CMake package ensures that CMake can automatically select a Zephyr installation to use for building
|
|
the application, whether it is a :ref:`Zephyr repository application <zephyr-repo-app>`,
|
|
a :ref:`Zephyr workspace application <zephyr-workspace-app>`, or a
|
|
:ref:`Zephyr freestanding application <zephyr-freestanding-app>`.
|
|
|
|
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/packages/Zephyr``
|
|
|
|
.. group-tab:: macOS
|
|
|
|
In macOS, the CMake user package registry is found in:
|
|
|
|
``~/.cmake/packages/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:
|
|
|
|
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 -P <PATH-TO-ZEPHYR>/share/zephyr-package/cmake/zephyr_export.cmake
|
|
|
|
This will export the current Zephyr to the CMake user package registry.
|
|
|
|
To also export the Zephyr Unittest CMake package, run the following command in addition:
|
|
|
|
.. code-block:: bash
|
|
|
|
cmake -P <PATH-TO-ZEPHYR>/share/zephyrunittest-package/cmake/zephyr_export.cmake
|
|
|
|
.. _zephyr_cmake_package_zephyr_base:
|
|
|
|
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.
|
|
|
|
.. note::
|
|
The root of a Zephyr workspace is identical to ``west topdir`` if the workspace was
|
|
installed using ``west``
|
|
|
|
* 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
|
|
|
|
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
|
|
|
|
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
|
|
|
|
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
|
|
|
|
find_package(Zephyr 2.z)
|
|
project(app)
|
|
|
|
then an error similar to below will be printed:
|
|
|
|
.. code-block:: none
|
|
|
|
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
|
|
|
|
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
|
|
|
|
set(ZEPHYR_PREFER "zephyr-test")
|
|
find_package(Zephyr)
|
|
|
|
project(my_first_app)
|
|
|
|
.. _cmake_build_config_package:
|
|
|
|
Zephyr Build Configuration CMake packages
|
|
*****************************************
|
|
|
|
There are two Zephyr Build configuration packages which provide control over the build
|
|
settings in Zephyr in a more generic way. These packages are:
|
|
|
|
* **ZephyrBuildConfiguration**: Applies to all Zephyr applications in the workspace
|
|
* **ZephyrAppConfiguration**: Applies only to the application you are currently building
|
|
|
|
They are similar to the per-user :file:`.zephyrrc` file that can be used to set :ref:`env_vars`,
|
|
but they set CMake variables instead. They also allow you to automatically share the build
|
|
configuration among all users through the project repository. They also allow more advanced use
|
|
cases, such as loading of additional CMake boilerplate code.
|
|
|
|
The Zephyr Build Configuration CMake packages will be loaded in the Zephyr boilerplate code after
|
|
initial properties and ``ZEPHYR_BASE`` has been defined, but before CMake code execution. The
|
|
ZephyrBuildConfiguration is included first and ZephyrAppConfiguration afterwards. That means the
|
|
application-specific package could override the workspace settings, if needed.
|
|
This allows the Zephyr Build Configuration CMake packages 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 ZephyrBuildConfiguration or ZephyrAppConfiguration, create
|
|
:file:`ZephyrBuildConfig.cmake` and/or :file:`ZephyrAppConfig.cmake` respectively and place them
|
|
in the appropriate location. The CMake ``find_package`` mechanism will search for these files with
|
|
the steps below. Other default CMake package search paths and hints are disabled and there is no
|
|
version checking implemented for these packages. This also means that these packages cannot be
|
|
installed in the CMake package registry. The search steps are:
|
|
|
|
1. If ``ZephyrBuildConfiguration_ROOT``, or ``ZephyrAppConfiguration_ROOT`` respectively, is set,
|
|
search within this prefix path. If a matching file is found, execute this file. If no matching
|
|
file is found, go to step 2.
|
|
2. Search within ``${ZEPHYR_BASE}/../*``, or ``${APPLICATION_SOURCE_DIR}`` respectively. If a
|
|
matching file is found, execute this file. If no matching file is found, abort the search.
|
|
|
|
It is recommended to place the files in the default paths from step 2, but with the
|
|
``<PackageName>_ROOT`` variables you have the flexibility to place them anywhere. This is
|
|
especially necessary for freestanding applications, for which the default path to
|
|
ZephyrBuildConfiguration usually does not work. In this case the ``<PackageName>_ROOT`` variables
|
|
can be set on the CMake command line, **before** ``find_package(Zephyr ...)``, as environment
|
|
variable or from a CMake cache initialization file with the ``-C`` command line option.
|
|
|
|
.. note:: The ``<PackageName>_ROOT`` variables, as well as the default paths, are just the prefixes
|
|
to the search path. These prefixes get combined with additional path suffixes, which together
|
|
form the actual search path. Any combination that honors the
|
|
`CMake package search procedure`_ is valid and will work.
|
|
|
|
If you want to completely disable the search for these packages, you can use the special CMake
|
|
``CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`` variable for that. Just set
|
|
``CMAKE_DISABLE_FIND_PACKAGE_ZephyrBuildConfiguration`` or
|
|
``CMAKE_DISABLE_FIND_PACKAGE_ZephyrAppConfiguration`` to ``TRUE`` to disable the package.
|
|
|
|
An example folder structure could look like this:
|
|
|
|
.. code-block:: none
|
|
|
|
<projects>/zephyr-workspace
|
|
├── zephyr
|
|
├── ...
|
|
├── manifest repo (can be named anything)
|
|
│ └── cmake/ZephyrBuildConfig.cmake
|
|
├── ...
|
|
└── zephyr application
|
|
└── share/zephyrapp-package/cmake/ZephyrAppConfig.cmake
|
|
|
|
A sample :file:`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
|
|
:zephyr_file:`share/zephyr-package/cmake` and
|
|
:zephyr_file:`share/zephyrunittest-package/cmake` contains the CMake config
|
|
package which is used by the CMake ``find_package`` function.
|
|
|
|
It also contains code for exporting Zephyr as a CMake config package.
|
|
|
|
The following is an overview of the files in these directories:
|
|
|
|
: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:`zephyr_export.cmake`
|
|
See :ref:`zephyr_cmake_package_export`.
|
|
|
|
.. _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 procedure: https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
|