2019-10-29 06:02:57 +08:00
|
|
|
|
.. _build_overview:
|
|
|
|
|
|
2021-05-06 21:48:14 +08:00
|
|
|
|
Build and Configuration Systems
|
|
|
|
|
###############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _cmake-details:
|
|
|
|
|
|
|
|
|
|
Build System (CMake)
|
|
|
|
|
********************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CMake is used to build your application together with the Zephyr kernel. A
|
|
|
|
|
CMake build is done in two stages. The first stage is called
|
|
|
|
|
**configuration**. During configuration, the CMakeLists.txt build scripts are
|
|
|
|
|
executed. After configuration is finished, CMake has an internal model of the
|
|
|
|
|
Zephyr build, and can generate build scripts that are native to the host
|
|
|
|
|
platform.
|
|
|
|
|
|
|
|
|
|
CMake supports generating scripts for several build systems, but only Ninja and
|
|
|
|
|
Make are tested and supported by Zephyr. After configuration, you begin the
|
|
|
|
|
**build** stage by executing the generated build scripts. These build scripts
|
|
|
|
|
can recompile the application without involving CMake following
|
|
|
|
|
most code changes. However, after certain changes, the configuration step must
|
|
|
|
|
be executed again before building. The build scripts can detect some of these
|
|
|
|
|
situations and reconfigure automatically, but there are cases when this must be
|
|
|
|
|
done manually.
|
|
|
|
|
|
|
|
|
|
Zephyr uses CMake's concept of a 'target' to organize the build. A
|
|
|
|
|
target can be an executable, a library, or a generated file. For
|
|
|
|
|
application developers, the library target is the most important to
|
|
|
|
|
understand. All source code that goes into a Zephyr build does so by
|
|
|
|
|
being included in a library target, even application code.
|
|
|
|
|
|
|
|
|
|
Library targets have source code, that is added through CMakeLists.txt
|
|
|
|
|
build scripts like this:
|
|
|
|
|
|
|
|
|
|
.. code-block:: cmake
|
|
|
|
|
|
|
|
|
|
target_sources(app PRIVATE src/main.c)
|
|
|
|
|
|
|
|
|
|
In the above :file:`CMakeLists.txt`, an existing library target named ``app``
|
|
|
|
|
is configured to include the source file :file:`src/main.c`. The ``PRIVATE``
|
|
|
|
|
keyword indicates that we are modifying the internals of how the library is
|
|
|
|
|
being built. Using the keyword ``PUBLIC`` would modify how other
|
|
|
|
|
libraries that link with app are built. In this case, using ``PUBLIC``
|
|
|
|
|
would cause libraries that link with ``app`` to also include the
|
|
|
|
|
source file :file:`src/main.c`, behavior that we surely do not want. The
|
|
|
|
|
``PUBLIC`` keyword could however be useful when modifying the include
|
|
|
|
|
paths of a target library.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Build and Configuration Phases
|
|
|
|
|
==============================
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
2020-01-22 00:09:58 +08:00
|
|
|
|
The Zephyr build process can be divided into two main phases: a configuration
|
|
|
|
|
phase (driven by CMake) and a build phase (driven by Make or Ninja).
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
2020-02-20 10:10:32 +08:00
|
|
|
|
.. _build_configuration_phase:
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
Configuration Phase
|
2021-05-06 21:48:14 +08:00
|
|
|
|
-------------------
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
The configuration phase begins when the user invokes *CMake*,
|
|
|
|
|
specifying a source application directory and a board target.
|
|
|
|
|
|
|
|
|
|
.. figure:: build-config-phase.svg
|
|
|
|
|
:align: center
|
|
|
|
|
:alt: Zephyr's build configuration phase
|
|
|
|
|
:figclass: align-center
|
|
|
|
|
:width: 80%
|
|
|
|
|
|
2020-01-22 00:09:58 +08:00
|
|
|
|
CMake begins by processing the :file:`CMakeLists.txt` file in the application
|
|
|
|
|
directory, which refers to the :file:`CMakeLists.txt` file in the Zephyr
|
|
|
|
|
top-level directory, which in turn refers to :file:`CMakeLists.txt` files
|
|
|
|
|
throughout the build tree (directly and indirectly). Its primary output is a
|
|
|
|
|
set of Makefiles or Ninja files to drive the build process, but the CMake
|
|
|
|
|
scripts also do some processing of their own:
|
|
|
|
|
|
|
|
|
|
Devicetree
|
|
|
|
|
:file:`*.dts` (*devicetree source*) and :file:`*.dtsi` (*devicetree source
|
|
|
|
|
include*) files are collected from the target's architecture, SoC, board,
|
|
|
|
|
and application directories.
|
|
|
|
|
|
|
|
|
|
:file:`*.dtsi` files are included by :file:`*.dts` files via the C
|
|
|
|
|
preprocessor (often abbreviated *cpp*, which should not be confused with
|
|
|
|
|
C++). The C preprocessor is also used to merge in any devicetree
|
|
|
|
|
:file:`*.overlay` files, and to expand macros in :file:`*.dts`,
|
|
|
|
|
:file:`*.dtsi`, and :file:`*.overlay` files.
|
|
|
|
|
|
|
|
|
|
The preprocessed devicetree sources (stored in :file:`*.dts.pre.tmp`) are
|
|
|
|
|
parsed by :zephyr_file:`gen_defines.py <scripts/dts/gen_defines.py>` to
|
|
|
|
|
generate a :file:`devicetree_unfixed.h` header with preprocessor macros.
|
|
|
|
|
|
2020-01-29 15:41:47 +08:00
|
|
|
|
As a debugging aid, :file:`gen_defines.py` writes the final devicetree to
|
|
|
|
|
:file:`zephyr.dts`. This file is just for reference. It is not used
|
|
|
|
|
anywhere.
|
|
|
|
|
|
2020-01-22 00:09:58 +08:00
|
|
|
|
The ``dtc`` devicetree compiler also gets run on the preprocessed devicetree
|
|
|
|
|
sources to catch any extra warnings and errors generated by it. The output
|
|
|
|
|
from ``dtc`` is unused otherwise.
|
|
|
|
|
|
|
|
|
|
The above is just a brief overview. For more information on devicetree, see
|
2020-03-11 09:16:25 +08:00
|
|
|
|
:ref:`dt-guide`.
|
2020-01-22 00:09:58 +08:00
|
|
|
|
|
|
|
|
|
Devicetree fixups
|
|
|
|
|
Files named :file:`dts_fixup.h` from the target’s architecture, SoC, board,
|
|
|
|
|
and application directories are concatenated into a single
|
|
|
|
|
:file:`devicetree_fixups.h` file. :file:`dts_fixup.h` files are used to
|
|
|
|
|
rename generated macros to names expected by the source code.
|
|
|
|
|
|
|
|
|
|
Source code accesses preprocessor macros generated from devicetree by
|
|
|
|
|
including the :zephyr_file:`devicetree.h <include/devicetree.h>` header,
|
|
|
|
|
which includes :file:`devicetree_unfixed.h` and :file:`devicetree_fixups.h`.
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
Kconfig
|
2020-01-22 00:09:58 +08:00
|
|
|
|
:file:`Kconfig` files define available configuration options for for the
|
|
|
|
|
target architecture, SoC, board, and application, as well as dependencies
|
|
|
|
|
between options.
|
|
|
|
|
|
|
|
|
|
Kconfig configurations are stored in *configuration files*. The initial
|
|
|
|
|
configuration is generated by merging configuration fragments from the board
|
|
|
|
|
and application (e.g. :file:`prj.conf`).
|
|
|
|
|
|
|
|
|
|
The output from Kconfig is an :file:`autoconf.h` header with preprocessor
|
|
|
|
|
assignments, and a :file:`.config` file that acts both as a saved
|
|
|
|
|
configuration and as configuration output (used by CMake).
|
|
|
|
|
|
|
|
|
|
Information from devicetree is available to Kconfig, through the functions
|
|
|
|
|
defined in :zephyr_file:`kconfigfunctions.py
|
|
|
|
|
<scripts/kconfig/kconfigfunctions.py>`.
|
|
|
|
|
|
|
|
|
|
See :ref:`the Kconfig section of the manual <kconfig>` for more information.
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
Build Phase
|
2021-05-06 21:48:14 +08:00
|
|
|
|
-----------
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
2020-01-22 00:09:58 +08:00
|
|
|
|
The build phase begins when the user invokes ``make`` or ``ninja``. Its
|
|
|
|
|
ultimate output is a complete Zephyr application in a format suitable for
|
|
|
|
|
loading/flashing on the desired target board (:file:`zephyr.elf`,
|
|
|
|
|
:file:`zephyr.hex`, etc.) The build phase can be broken down, conceptually,
|
2019-10-29 06:02:57 +08:00
|
|
|
|
into four stages: the pre-build, first-pass binary, final binary, and
|
|
|
|
|
post-processing.
|
|
|
|
|
|
|
|
|
|
Pre-build
|
2021-05-06 21:48:14 +08:00
|
|
|
|
+++++++++
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
2021-01-06 04:20:44 +08:00
|
|
|
|
Pre-build occurs before any source files are compiled, because during
|
|
|
|
|
this phase header files used by the source files are generated.
|
|
|
|
|
|
2019-10-29 06:02:57 +08:00
|
|
|
|
Offset generation
|
|
|
|
|
Access to high-level data structures and members is sometimes
|
|
|
|
|
required when the definitions of those structures is not
|
|
|
|
|
immediately accessible (e.g., assembly language). The generation of
|
|
|
|
|
*offsets.h* (by *gen_offset_header.py*) facilitates this.
|
|
|
|
|
|
|
|
|
|
System call boilerplate
|
2019-06-01 06:39:39 +08:00
|
|
|
|
The *gen_syscall.py* and *parse_syscalls.py* scripts work
|
|
|
|
|
together to bind potential system call functions with their
|
|
|
|
|
implementations.
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
.. figure:: build-build-phase-1.svg
|
|
|
|
|
:align: center
|
|
|
|
|
:alt: Zephyr's build stage I
|
|
|
|
|
:figclass: align-center
|
|
|
|
|
:width: 80%
|
|
|
|
|
|
|
|
|
|
First-pass binary
|
2021-05-06 21:48:14 +08:00
|
|
|
|
+++++++++++++++++
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
Compilation proper begins with the first-pass binary. Source files (C
|
|
|
|
|
and assembly) are collected from various subsystems (which ones is
|
|
|
|
|
decided during the configuration phase), and compiled into archives
|
|
|
|
|
(with reference to header files in the tree, as well as those
|
|
|
|
|
generated during the configuration phase and the pre-build stage).
|
|
|
|
|
|
|
|
|
|
If memory protection is enabled, then:
|
|
|
|
|
|
|
|
|
|
Partition grouping
|
2021-01-06 04:18:33 +08:00
|
|
|
|
The *gen_app_partitions.py* script scans all the
|
2019-10-29 06:02:57 +08:00
|
|
|
|
generated archives and outputs linker scripts to ensure that
|
|
|
|
|
application partitions are properly grouped and aligned for the
|
|
|
|
|
target’s memory protection hardware.
|
|
|
|
|
|
|
|
|
|
Then *cpp* is used to combine linker script fragments from the target’s
|
|
|
|
|
architecture/SoC, the kernel tree, optionally the partition output if
|
|
|
|
|
memory protection is enabled, and any other fragments selected during
|
|
|
|
|
the configuration process, into a *linker.cmd* file. The compiled
|
|
|
|
|
archives are then linked with *ld* as specified in the
|
|
|
|
|
*linker.cmd*.
|
|
|
|
|
|
|
|
|
|
In some configurations, this is the final binary, and the next stage
|
|
|
|
|
is skipped.
|
|
|
|
|
|
|
|
|
|
.. figure:: build-build-phase-2.svg
|
|
|
|
|
:align: center
|
|
|
|
|
:alt: Zephyr's build stage II
|
|
|
|
|
:figclass: align-center
|
|
|
|
|
:width: 80%
|
|
|
|
|
|
|
|
|
|
Final binary
|
2021-05-06 21:48:14 +08:00
|
|
|
|
++++++++++++
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
2020-06-30 23:05:35 +08:00
|
|
|
|
The binary from the previous stage is incomplete, with empty and/or
|
|
|
|
|
placeholder sections that must be filled in by, essentially, reflection.
|
|
|
|
|
|
|
|
|
|
Device dependencies
|
|
|
|
|
The *gen_handles.py* script scans the first-pass binary to determine
|
|
|
|
|
relationships between devices that were recorded from devicetree data,
|
|
|
|
|
and replaces the encoded relationships with values that are optimized to
|
|
|
|
|
locate the devices actually present in the application.
|
|
|
|
|
|
|
|
|
|
When :ref:`usermode_api` is enabled:
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
Kernel object hashing
|
|
|
|
|
The *gen_kobject_list.py* scans the *ELF DWARF*
|
|
|
|
|
debug data to find the address of the all kernel objects. This
|
|
|
|
|
list is passed to *gperf*, which generates a perfect hash function and
|
|
|
|
|
table of those addresses, then that output is optimized by
|
|
|
|
|
*process_gperf.py*, using known properties of our special case.
|
|
|
|
|
|
|
|
|
|
Then, the link from the previous stage is repeated, this time with the
|
|
|
|
|
missing pieces populated.
|
|
|
|
|
|
|
|
|
|
.. figure:: build-build-phase-3.svg
|
|
|
|
|
:align: center
|
|
|
|
|
:alt: Zephyr's build stage III
|
|
|
|
|
:figclass: align-center
|
|
|
|
|
:width: 80%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Post processing
|
2021-05-06 21:48:14 +08:00
|
|
|
|
+++++++++++++++
|
2019-10-29 06:02:57 +08:00
|
|
|
|
|
|
|
|
|
Finally, if necessary, the completed kernel is converted from *ELF* to
|
|
|
|
|
the format expected by the loader and/or flash tool required by the
|
|
|
|
|
target. This is accomplished in a straightforward manner with *objdump*.
|
|
|
|
|
|
|
|
|
|
.. figure:: build-build-phase-4.svg
|
|
|
|
|
:align: center
|
|
|
|
|
:alt: Zephyr's build final stage
|
|
|
|
|
:figclass: align-center
|
|
|
|
|
:width: 80%
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _build_system_scripts:
|
|
|
|
|
|
|
|
|
|
Supporting Scripts and Tools
|
2021-05-06 21:48:14 +08:00
|
|
|
|
============================
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
The following is a detailed description of the scripts used during the build process.
|
|
|
|
|
|
|
|
|
|
.. _gen_syscalls.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/gen_syscalls.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
--------------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/gen_syscalls.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
2020-06-30 23:05:35 +08:00
|
|
|
|
.. _gen_handles.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/gen_handles.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
--------------------------------------
|
2020-06-30 23:05:35 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/gen_handles.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
2019-06-01 06:39:39 +08:00
|
|
|
|
.. _gen_kobject_list.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/gen_kobject_list.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
------------------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/gen_kobject_list.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
|
|
|
|
.. _gen_offset_header.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/gen_offset_header.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
-------------------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/gen_offset_header.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
|
|
|
|
.. _parse_syscalls.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/parse_syscalls.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
----------------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/parse_syscalls.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
|
|
|
|
.. _gen_idt.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`arch/x86/gen_idt.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
----------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../arch/x86/gen_idt.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
|
|
|
|
.. _gen_gdt.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`arch/x86/gen_gdt.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
----------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../arch/x86/gen_gdt.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
|
|
|
|
.. _gen_relocate_app.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/gen_relocate_app.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
-------------------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/gen_relocate_app.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
|
|
|
|
|
|
|
|
|
.. _process_gperf.py:
|
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/process_gperf.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
---------------------------------------
|
2019-06-01 06:39:39 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/process_gperf.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
2021-01-09 01:48:19 +08:00
|
|
|
|
|
|
|
|
|
:zephyr_file:`scripts/gen_app_partitions.py`
|
2021-05-06 21:48:14 +08:00
|
|
|
|
--------------------------------------------
|
2021-01-09 01:48:19 +08:00
|
|
|
|
|
|
|
|
|
.. include:: ../../../scripts/gen_app_partitions.py
|
|
|
|
|
:start-after: """
|
|
|
|
|
:end-before: """
|
2021-05-06 21:48:14 +08:00
|
|
|
|
|
|
|
|
|
.. _kconfig:
|
|
|
|
|
|
|
|
|
|
Configuration System (Kconfig)
|
|
|
|
|
*******************************
|
|
|
|
|
|
|
|
|
|
The Zephyr kernel and subsystems can be configured at build time to adapt them
|
|
|
|
|
for specific application and platform needs. Configuration is handled through
|
|
|
|
|
Kconfig, which is the same configuration system used by the Linux kernel. The
|
|
|
|
|
goal is to support configuration without having to change any source code.
|
|
|
|
|
|
|
|
|
|
Configuration options (often called *symbols*) are defined in :file:`Kconfig`
|
|
|
|
|
files, which also specify dependencies between symbols that determine what
|
|
|
|
|
configurations are valid. Symbols can be grouped into menus and sub-menus to
|
|
|
|
|
keep the interactive configuration interfaces organized.
|
|
|
|
|
|
|
|
|
|
The output from Kconfig is a header file :file:`autoconf.h` with macros that
|
|
|
|
|
can be tested at build time. Code for unused features can be compiled out to
|
|
|
|
|
save space.
|
|
|
|
|
|
|
|
|
|
The following sections explain how to set Kconfig configuration options, go
|
|
|
|
|
into detail on how Kconfig is used within the Zephyr project, and have some
|
|
|
|
|
tips and best practices for writing :file:`Kconfig` files.
|
|
|
|
|
|
|
|
|
|
.. toctree::
|
|
|
|
|
:maxdepth: 1
|
|
|
|
|
|
|
|
|
|
kconfig/menuconfig.rst
|
|
|
|
|
kconfig/setting.rst
|
|
|
|
|
kconfig/tips.rst
|
|
|
|
|
kconfig/preprocessor-functions.rst
|
|
|
|
|
kconfig/extensions.rst
|