cmake: Add "Preview release" getting start guide & build system documentation

This commit is contained in:
Angus Gratton 2018-02-22 15:05:05 +11:00 committed by Angus Gratton
parent 95e17d6d92
commit 9f8cdd3572
20 changed files with 1510 additions and 41 deletions

View file

@ -3,7 +3,7 @@ set(COMPONENT_SRCDIRS library port)
register_component()
target_compile_definitions(expat PRIVATE HAVE_EXPAT_CONFIG_H)
component_compile_definitions(HAVE_EXPAT_CONFIG_H)
# patch around warnings in third-party files
set_source_files_properties(

View file

@ -72,7 +72,7 @@ set(COMPONENT_PRIV_INCLUDEDIRS ${SRC}/include/sodium port_include/sodium port)
register_component()
target_compile_definitions(libsodium PRIVATE
component_compile_definitions(
CONFIGURED
NATIVE_LITTLE_ENDIAN
HAVE_WEAK_SYMBOLS
@ -80,9 +80,7 @@ target_compile_definitions(libsodium PRIVATE
__STDC_CONSTANT_MACROS
)
target_compile_options(libsodium PRIVATE
-Wno-unknown-pragmas
)
component_compile_options(-Wno-unknown-pragmas)
# patch around warnings in third-party files
set_source_files_properties(

View file

@ -18,9 +18,7 @@ set(COMPONENT_SRCDIRS
register_component()
target_compile_options(lwip PRIVATE
-Wno-address
)
component_compile_options(-Wno-address)
# patch around warnings in third-party files
set_source_files_properties(api/tcpip.c

View file

@ -3,5 +3,5 @@ set(COMPONENT_ADD_INCLUDEDIRS include port/include)
register_component()
target_compile_definitions(wpa_supplicant PRIVATE __ets__)
target_compile_options(wpa_supplicant PRIVATE -Wno-strict-aliasing)
component_compile_definitions(__ets__)
component_compile_options(-Wno-strict-aliasing)

View file

@ -0,0 +1,749 @@
CMake-based Build System
************************
This document explains the CMake-based ESP-IDF build system and the concept of "components".
Read this document if you want to know how to organise and build a new ESP-IDF project using the CMake-based build system.
We recommend using the esp-idf-template_ project as a starting point for your project.
Preview Release
===============
.. note::
The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). The document describing the :doc:`fully supported non-CMake build system is here </api-guides/build-system>`.
CMake-based build system preview release temporarily has the following limitations:
- No instructions published for use with any IDEs.
- No support for building ULP firmware as part of the build.
- No support for flash encryption, secure boot.
- ``idf.py monitor`` only runs at 115200bps
- The rebuild/reflash commands inside monitor don't work correctly.
These missing features will be added before CMake support is officially supported.
Overview
========
An ESP-IDF project can be seen as an amalgamation of a number of components.
For example, for a webserver that shows the current humidity, there could be:
- The ESP32 base libraries (libc, ROM bindings, etc)
- The WiFi drivers
- A TCP/IP stack
- The FreeRTOS operating system
- A webserver
- A driver for the humidity sensor
- Main code tying it all together
ESP-IDF makes these components explicit and configurable. To do that,
when a project is compiled, the build system will look up all the
components in the ESP-IDF directories, the project directories and
(optionally) in additional custom component directories. It then
allows the user to configure the ESP-IDF project using a a text-based
menu system to customize each component. After the components in the
project are configured, the build system will compile the project.
Concepts
--------
- A "project" is a directory that contains all the files and configuration to build a single "app" (executable), as well as additional supporting output such as a partition table, data/filesystem partitions, and a bootloader.
- "Project configuration" is held in a single file called ``sdkconfig`` in the root directory of the project. This configuration file is modified via ``idf.py menuconfig`` to customise the configuration of the project. A single project contains exactly one project configuration.
- An "app" is an executable which is built by esp-idf. A single project will usually build two apps - a "project app" (the main executable, ie your custom firmware) and a "bootloader app" (the initial bootloader program which launches the project app).
- "components" are modular pieces of standalone code which are compiled into static libraries (.a files) and linked into an app. Some are provided by ESP-IDF itself, others may be sourced from other places.
Some things are not part of the project:
- "ESP-IDF" is not part of the project. Instead it is standalone, and linked to the project via the ``IDF_PATH`` environment variable which holds the path of the ``esp-idf`` directory. This allows the IDF framework to be decoupled from your project.
- The toolchain for compilation is not part of the project. The toolchain should be installed in the system command line PATH.
Using the Build System
======================
idf.py
------
The ``idf.py`` command line tool provides a front-end for easily managing your project builds. It manages the following tools:
- CMake_, which configures the project to be built
- A command line build tool (either Ninja_ build or `GNU Make`)
- `esptool.py`_ for flashing ESP32.
The :ref:`getting started guide <get-started-configure-cmake>` contains a brief introduction to how to set up ``idf.py`` to configure, build, and flash projects.
``idf.py`` should be run in an ESP-IDF "project" directory, ie one containing a ``CMakeLists.txt`` file. Older style projects with a Makefile will not work with ``idf.py``.
Type ``idf.py --help`` for a full list of commands. Here are a summary of a few:
- ``idf.py menuconfig`` runs the "menuconfig" tool to configure the project.
- ``idf.py build`` will build the project found in the current directory. This can involve multiple steps:
- Create the build directory if needed. The subdirectory ``build`` is used to hold build output, although this can be changed with the ``-B`` option.
- Run CMake_ as necessary to configure the project and generate build files for the main build tool.
- Run the main build tool (Ninja_ or `GNU Make`). By default, the build tool is automatically detected but it can be explicitly set by passing the ``-G`` option to ``idf.py``.
Building is incremental so if no source files or configuration has changed since the last build, nothing will be done.
- ``idf.py clean`` will "clean" the project by deleting build output files from the build directory, forcing a "full rebuild" the next time the project is built. Cleaning doesn't delete CMake configuration output and some other files.
- ``idf.py fullclean`` will delete the entire "build" directory contents. This includes all CMake configuration output. The next time the project is built, CMake will configure it from scratch. Note that this option recursively deletes *all* files in the build directory, so use with care.
- ``idf.py reconfigure`` re-runs CMake_ even if it doesn't seem to need re-running. This isn't necessary during normal usage, but can be useful after adding/removing files from the source tree.
- ``idf.py flash`` will automatically build the project if necessary, and then flash it to an ESP32. The ``-p`` and ``-b`` options can be used to set serial port name and flasher baud rate, respectively.
- ``idf.py monitor`` will display serial output from the ESP32. The ``-p`` option can be used to set the serial port name. Type ``Ctrl-]`` to exit the monitor.
Multiple ``idf.py`` commands can be combined into one. For example, ``idf.py -p COM4 clean build flash monitor`` will perform a clean build of the project, then flash to the ESP32 and run the serial monitor.
Advanced Commands
^^^^^^^^^^^^^^^^^
- ``idf.py app``, ``idf.py bootloader``, ``idf.py partition_table`` can be used to build only the app, bootloader, or partition table from the project as applicable.
- There are matching commands ``idf.py app-flash``, etc. to flash only that single part of the project to the ESP32.
- ``idf.py -p PORT erase_flash`` will use esptool.py to erase the ESP32's entire flash chip.
- ``idf.py size`` prints some size information about the app. ``size-components`` and ``size-files`` are similar commands which print more detailed per-component or per-source-file information, respectively.
Using CMake Directly
--------------------
``idf.py`` is a wrapper around CMake_ for convenience. However, you can also invoke CMake directly if you prefer.
When ``idf.py`` does something, it prints each command that it runs for easy reference. For example, the ``idf.py build`` command is the same as running these commands::
mkdir -p build
cd build
cmake .. -G Ninja # or 'GNU Make'
ninja
In the above list, the ``cmake`` command configures the project and generates build files for use with the final build tool. In this case the final build tool is Ninja_: runnning ``ninja`` actually builds the project.
It's not necessary to run ``cmake`` more than once. After the first build, you only need to run ``ninja`` each time. ``ninja`` will automatically re-invoke ``cmake`` if the project needs reconfiguring.
If using CMake with ``ninja`` or ``make``, there are also targets for more of the ``idf.py`` subcommands - for example running ``make menuconfig`` in the build directory will work the same as ``idf.py menuconfig``.
.. note::
If you're already familiar with CMake_, you may find the ESP-IDF CMake-based build system unusual because it wraps a lot of CMake's functionality to reduce boilerplate. See `writing pure CMake components`_ for some information about writing more "CMake style" components.
Using CMake in an IDE
---------------------
You can also use an IDE with CMake integration. The IDE will want to know the path to the project's ``CMakeLists.txt`` file. IDEs with CMake integration often provide their own build tools (CMake calls these "generators") to build the source files as part of the IDE.
When adding custom non-build steps like "flash" to the IDE, it is recommended to execute ``idf.py`` for these "special" commands.
Example Project
===============
An example project directory tree might look like this::
- myProject/
- CMakeLists.txt
- sdkconfig
- components/ - component1/ - CMakeLists.txt
- Kconfig
- src1.c
- component2/ - CMakeLists.txt
- Kconfig
- src1.c
- include/ - component2.h
- main/ - src1.c
- src2.c
- build/
This example "myProject" contains the following elements:
- A top-level project CMakeLists.txt file. This is the primary file which CMake uses to learn how to build the project. The project CMakeLists.txt file sets the ``MAIN_SRCS`` variable which lists all of the source files in the "main" directory (part of this project's executable). It may set other project-wide CMake variables, as well. Then it includes the file :idf_file:`/tools/cmake/project.cmake` which
implements the rest of the build system. Finally, it sets the project name and defines the project.
- "sdkconfig" project configuration file. This file is created/updated when "make menuconfig" runs, and holds configuration for all of the components in the project (including esp-idf itself). The "sdkconfig" file may or may not be added to the source control system of the project.
- Optional "components" directory contains components that are part of the project. A project does not have to contain custom components of this kind, but it can be useful for structuring reusable code or including third party components that aren't part of ESP-IDF.
- "main" directory is a special "by convention" directory that contains source code for the project executable itself. These source files are listed in the project's CMakeLists file. You don't need to name this directory "main", but we recommend you follow this convention. If you have a lot of source files in your project, we recommend grouping most into components instead of putting them all in "main".
- "build" directory is where build output is created. This directory is created by ``idf.py`` if it doesn't already exist. CMake configures the project and generates interim build files in this directory. Then, after the main build process is run, this directory will also contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code.
Component directories each contain a component ``CMakeLists.txt`` file. This file contains variable definitions
to control the build process of the component, and its integration into the overall project. See `Component CMakeLists Files`_ for more details.
Each component may also include a ``Kconfig`` file defining the `component configuration`_ options that can be set via ``menuconfig``. Some components may also include ``Kconfig.projbuild`` and ``project_include.cmake`` files, which are special files for `overriding parts of the project`_.
Project CMakeLists File
=======================
Each project has a single top-level ``CMakeLists.txt`` file that contains build settings for the entire project. By default, the project CMakeLists can be quite minimal.
Minimal Example CMakeLists
--------------------------
::
cmake_minimum_required(VERSION 3.5)
set(MAIN_SRCS main/src1.c main/src2.c)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(myProject)
Mandatory Parts
---------------
The inclusion of these four lines, in the order shown above, is necessary for every project:
- ``cmake_minimum_required(VERSION 3.5)`` tells CMake what version is required to build the project. ESP-IDF is designed to work with CMake 3.5 or newer. This line must be the first line in the CMakeLists.txt file.
- ``set(MAIN_SRCS xxx)`` sets a variable - ``MAIN_SRCS`` to be a list of the "main" source files in the project. Paths are relative to the CMakeLists. They don't specifically need to be under the "main" subdirectory, but this structure is encouraged.
It is *strongly recommended not to add a lot of files to the MAIN_SRCS list*. If you have a lot of source files then it recommended to organise them functionally into individual components under the project "components" directory. This will make your project more maintainable, reusable, and easier to configure. Components are further explained below.
``MAIN_SRCS`` must name at least one source file (although that file doesn't need to necessarily include an ``app_main()`` function or anything else).
- ``include($ENV{IDF_PATH}/tools/cmake/project.cmake)`` pulls in the rest of the CMake functionality to configure the project, discover all the components, etc.
- ``project(myProject)`` creates the project itself, and specifies the project name. The project name is used for the final binary output files of the app - ie ``myProject.elf``, ``myProject.bin``. Only one project can be defined per CMakeLists file.
Optional Project Variables
--------------------------
These variables all have default values that can be overridden for custom behaviour. Look in :idf_file:`/tools/cmake/project.cmake` for all of the implementation details.
- ``COMPONENT_DIRS``: Directories to search for components. Defaults to `${IDF_PATH}/components`, `${PROJECT_PATH}/components`, and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in these places.
- ``EXTRA_COMPONENT_DIRS``: Optional list of additional directories to search for components. Paths can be relative to the project directory, or absolute.
- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the ``COMPONENT_DIRS`` directories. Use this variable to "trim down" the project for faster build times.
Any paths in these variables can be absolute paths, or set relative to the project directory.
To set these variables, use the `cmake set command <cmake-set>` ie ``set(VARIABLE "VALUE")``. The ``set()`` commands should be placed after the ``cmake_minimum(...)`` line but before the ``include(...)`` line.
Component CMakeLists Files
==========================
Each project contains one or more components. Components can be part of esp-idf, part of the project's own components directory, or added from custom component directories (see above).
A component is any directory in the ``COMPONENT_DIRS`` list which contains a ``CMakeLists.txt`` file.
Searching for Components
------------------------
The list of directories in ``COMPONENT_DIRS`` is searched for the project's components. Directories in this list can either be components themselves (ie they contain a `CMakeLists.txt` file), or they can be top-level directories whose subdirectories are components.
When CMake runs to configure the project, it logs the components included in the build. This list can be useful for debugging the inclusion/exclusion of certain components.
Multiple components with the same name
--------------------------------------
When ESP-IDF is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means ESP-IDF's internal components first, then the project's components, and finally any components set in ``EXTRA_COMPONENT_DIRS``. If two or more of these directories
contain component subdirectories with the same name, the component in the last place searched is used. This allows, for example, overriding ESP-IDF components
with a modified version by copying that component from the ESP-IDF components directory to the project components directory and then modifying it there.
If used in this way, the ESP-IDF directory itself can remain untouched.
Minimal Component CMakeLists
----------------------------
The minimal component ``CMakeLists.txt`` file is as follows::
set(COMPONENT_SRCDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS "include")
register_component()
- ``COMPONENT_SRCDIRS`` is a (space-separated) list of directories to search for source files. Source files (``*.c``, ``*.cpp``, ``*.cc``, ``*.S``) in these directories will be compiled into the component library.
- ``COMPONENT_ADD_INCLUDEDIRS`` is a (space-separated) list of directories to add to the global include search path for all other components, and the main source files.
- ``register_component()`` is required to add the component (using the variables set above) to the build. A library with the name of the component will be built and linked into the final app. If this step is skipped (perhaps due to use of a CMake `if() statement<cmake-if>` or similar), this component will not be built at all.
Directories are usually specified relative to the ``CMakeLists.txt`` file itself, although they can be absolute.
See `example component CMakeLists`_ for more complete component ``CMakeLists.txt`` examples.
.. _component variables:
Preset Component Variables
--------------------------
The following component-specific variables are available for use inside component CMakeLists, but should not be modified:
- ``COMPONENT_PATH``: The component directory. Evaluates to the absolute path of the directory containing ``component.mk``. The component path cannot contain spaces. This is the same as the ``CMAKE_CURRENT_SOURCE_DIR`` variable.
- ``COMPONENT_NAME``: Name of the component. Same as the name of the component directory.
The following variables are set at the project level, but available for use in component CMakeLists:
- ``PROJECT_NAME``: Name of the project, as set in project Makefile
- ``PROJECT_PATH``: Absolute path of the project directory containing the project Makefile. Same as the ``CMAKE_SOURCE_DIR`` variable.
- ``COMPONENTS``: Names of all components that are included in this build, formatted as a semicolon-delimited CMake list.
- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in make. All names begin with ``CONFIG_``. `More information here </api-reference/kconfig>`.
- ``IDF_VER``: Git version of ESP-IDF (produced by ``git describe``)
If you modify any of these variables inside ``CMakeLists.txt`` then this will not prevent other components from building but it may make your component hard to build and/or debug.
Optional Project-Wide Component Variables
-----------------------------------------
The following variables can be set inside component ``CMakeLists.txt`` to control build settings across the entire project:
- ``COMPONENT_ADD_INCLUDEDIRS``: Paths, relative to the component
directory, which will be added to the include search path for
all components in the project. If an include directory is only needed to compile
this specific component, add it to ``COMPONENT_PRIV_INCLUDEDIRS`` instead.
- ``COMPONENT_DEPENDS``: Optional list of component names that should be
compiled before this component. This is not necessary for
link-time dependencies, because all component include directories
are available at all times. It is necessary if one component
generates an include file which you then want to include in another
component. Most components do not need to set this variable.
Optional Component-Specific Variables
-------------------------------------
The following variables can be set inside ``component.mk`` to control the build of that component:
- ``COMPONENT_PRIV_INCLUDEDIRS``: Directory paths, must be relative to
the component directory, which will be added to the include search
path for this component's source files only.
- ``COMPONENT_SRCDIRS``: Directory paths, must be relative to the
component directory, which will be searched for source files (``*.cpp``,
``*.c``, ``*.S``). Set this to specify a list of directories
which contain source files.
- ``COMPONENT_SRCS``: Paths to individual source files to compile. Setting this causes ``COMPONENT_SRCDIRS`` to be ignored. Setting this variable instead gives you finer grained control over which files are compiled.
If you don't set ``COMPONENT_SRCDIRS`` or ``COMPONENT_SRCS``, your component won't compile a library but it may still add paths to include search paths.
Controlling Component Compilation
---------------------------------
To pass compiler options when compiling source files belonging to a particular component, use the ``component_compile_options`` function::
component_compile_options(-Wno-unused-variable)
This is a wrapper around the CMake `target_compile_options`_ command.
To apply the compilation flags to a single source file, use the CMake `set_source_files_properties`_ command::
set_source_files_properties(mysrc.c
PROPERTIES COMPILE_FLAGS
-Wno-unused-variable
)
This can be useful if there is upstream code that emits warnings.
When using these commands, place them after the ``register_component()`` line in the component CMakeLists file.
Component Configuration
=======================
Each component can also have a Kconfig file, alongside ``component.mk``. This contains contains
configuration settings to add to the "make menuconfig" for this component.
These settings are found under the "Component Settings" menu when menuconfig is run.
To create a component Kconfig file, it is easiest to start with one of the Kconfig files distributed with esp-idf.
For an example, see `Adding conditional configuration`_.
Preprocessor Definitions
========================
The ESP-IDF build system adds the following C preprocessor definitions on the command line:
- ``ESP_PLATFORM`` — Can be used to detect that build happens within ESP-IDF.
- ``IDF_VER`` — Defined to a git version string. E.g. ``v2.0`` for a tagged release or ``v1.0-275-g0efaa4f`` for an arbitrary commit.
Build Process Internals
=======================
For full details about CMake_ and CMake commands, see the `CMake v3.5 documentation`.
project.cmake contents
----------------------
When included from a project CMakeLists file, the ``project.cmake`` file defines some utility modules and global variables and then sets ``IDF_PATH`` if it was not set in the system environmenmt.
It also defines an overriden custom version of the built-in CMake_ ``project`` function. This function is overriden to add all of the ESP-IDF specific project functionality.
project function
----------------
The custom ``project()`` function performs the following steps:
- Finds all components in the project (searching ``COMPONENT_DIRS`` and filtering by ``COMPONENTS`` if this is set).
- Loads the project configuration from the ``sdkconfig`` file and produces a ``cmake`` include file and a C header file, to set config macros. If the project configuration changes, cmake will automatically be re-run to reconfigure the project.
- Sets the `CMAKE_TOOLCHAIN_FILE`_ variable to the ESP-IDF toolchain file with the Xtensa ESP32 toolchain.
- Declare the actual cmake-level project by calling the `CMake project function <project-function-cmake>`.
- Load the git version. This includes some magic which will automatically re-run cmake if a new revision is checked out in git. See `File Globbing & Incremental Builds`_.
- Include ``project_include.cmake`` files from any components which have them.
- Add each component to the build. Each component CMakeLists file calls ``register_component``, calls the cmake `add_library <add-library-cmake>` function to add a library and then adds source files, compile options, etc.
- Add the final app executable to the build.
- Go back and add inter-component dependencies between components (ie adding the public header directories of each component to each other component).
Browse the :idf_file:`/tools/cmake/project.cmake` file and supporting functions in :idf_file:`/tools/cmake/idf_functions.cmake` for more details.
Debugging CMake
---------------
Some tips for debugging the esp-idf CMake-based build system:
- When CMake runs, it prints quite a lot of diagnostic information including lists of components and component paths.
- Running ``cmake`` with the ``--trace`` or ``--trace-expand`` options will give a lot of information about control flow. See the `cmake command line documentation`_.
.. _warn-undefined-variables-cmake:
Warning On Undefined Variables
------------------------------
By default, ``idf.py`` passes the ``--warn-uninitialized`` flag to CMake_ so it will print a warning if an undefined variable is referenced in the build. This can be very useful to find buggy CMake files.
If you don't want this behaviour, it can be disabled by passing ``--no-warnings`` to ``idf.py``.
Overriding Parts of the Project
-------------------------------
project_include.cmake
^^^^^^^^^^^^^^^^^^^^^
For components that have build requirements that must be evaluated before any component CMakeLists
files are evaluated, you can create a file called ``project_include.cmake`` in the
component directory. This makefile is included when ``project.cmake`` is evaluating the entire project.
``project_include.cmake`` files are used heavily inside ESP-IDF, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app".
Note that ``project_include.cmake`` isn't necessary for the most common component uses - such as adding include directories to the project, or LDFLAGS to the final linking step. These values can be customised via the ``CMakeLists.txt`` file itself. See `Optional Project Variables`_ for details.
Take great care when setting variables or targets in this file. As the values are included into the top-level project CMake pass, they can influence or break functionality across all components!
KConfig.projbuild
^^^^^^^^^^^^^^^^^
This is an equivalent to ``project_include.cmake`` for `component configuration` KConfig files. If you want to include
configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``CMakeLists.txt`` file.
Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for `component configuration`.
Configuration-Only Components
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Special components which contain no source files, only ``Kconfig.projbuild`` and ``KConfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``register_config_only_component()``. This function will include the component in the project build, but no library will be built *and* no header files will be added to any include paths.
If a CMakeLists.txt file doesn't call ``register_component()`` or ``register_config_only_component()``, it will be excluded from the project entirely. This may sometimes be desirable, depending on the project configuration.
Example Component CMakeLists
============================
Because the build environment tries to set reasonable defaults that will work most
of the time, component ``CMakeLists.txt`` can be very small or even empty (see `Minimal Component CMakeLists`_). However, overriding `component variables`_ is usually required for some functionality.
Here are some more advanced examples of component CMakeLists files.
Adding conditional configuration
--------------------------------
The configuration system can be used to conditionally compile some files
depending on the options selected in the project configuration.
``Kconfig``::
config FOO_ENABLE_BAR
bool "Enable the BAR feature."
help
This enables the BAR feature of the FOO component.
``CMakeLists.txt``::
set(COMPONENT_SRCS "foo.c" "more_foo.c")
if(CONFIG_FOO_ENABLE_BAR)
list(APPEND COMPONENT_SRCS "bar.c")
endif(CONFIG_FOO_ENABLE_BAR)
This example makes use of the CMake `if function <if-cmake>` and `list APPEND <list-cmake>` function.
This can also be used to select or stub out an implementation, as such:
``Kconfig``::
config ENABLE_LCD_OUTPUT
bool "Enable LCD output."
help
Select this if your board has a LCD.
config ENABLE_LCD_CONSOLE
bool "Output console text to LCD"
depends on ENABLE_LCD_OUTPUT
help
Select this to output debugging output to the lcd
config ENABLE_LCD_PLOT
bool "Output temperature plots to LCD"
depends on ENABLE_LCD_OUTPUT
help
Select this to output temperature plots
``CMakeLists.txt``::
if(CONFIG_ENABLE_LCD_OUTPUT)
set(COMPONENT_SRCS lcd-real.c lcd-spi.c)
else()
set(COMPONENT_SRCS lcd-dummy.c)
endif()
# We need font if either console or plot is enabled
if(CONFIG_ENABLE_LCD_CONSOLE OR CONFIG_NEABLE_LCD_PLOT)
list(APPEND COMPONENT_SRCS "font.c")
endif()
Source Code Generation
----------------------
Some components will have a situation where a source file isn't
supplied with the component itself but has to be generated from
another file. Say our component has a header file that consists of the
converted binary data of a BMP file, converted using a hypothetical
tool called bmp2h. The header file is then included in as C source
file called graphics_lib.c::
COMPONENT_EXTRA_CLEAN := logo.h
add_custom_command(OUTPUT logo.h
COMMAND bmp2h -i ${COMPONENT_PATH}/logo.bmp -o log.h
DEPENDS ${COMPONENT_PATH}/logo.bmp
VERBATIM)
add_custom_target(logo DEPENDS logo.h)
add_dependencies(${COMPONENT_NAME} logo)
set_property(DIRECTORY "${COMPONENT_PATH}" APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES logo.h)
This answer is adapted from the `CMake FAQ entry <cmake-faq-generated-files>`, which contains some other examples that will also work with ESP-IDF builds.
In this example, logo.h will be generated in the
current directory (the build directory) while logo.bmp comes with the
component and resides under the component path. Because logo.h is a
generated file, it should be cleaned when make clean is called which
why it is added to the `ADDITIONAL_MAKE_CLEAN_FILES`_ property.
(Note: If generating files as part of the project CMakeLists, not a component CMakeLists, use ``${PROJECT_PATH}`` instead of ``${COMPONENT_PATH}`` and ``${PROJECT_NAME}.elf`` instead of ``${COMPONENT_NAME}``.)
If a a source file from another component included ``logo.h``, then this
component's name would have to be added to the other component's
``COMPONENT_DEPENDS`` list to ensure that the components were built
in-order.
Embedding Binary Data
---------------------
Sometimes you have a file with some binary or text data that you'd like to make available to your component - but you don't want to reformat the file as C source.
You can set a variable ``COMPONENT_EMBED_FILES`` in your component's CMakeLists, giving the names of the files to embed in this way::
set(COMPONENT_EMBED_FILES server_root_cert.der)
Or if the file is a string, you can use the variable ``COMPONENT_EMBED_TXTFILES``. This will embed the contents of the text file as a null-terminated string::
set(COMPONENT_EMBED_TXTFILES server_root_cert.pem)
The file's contents will be added to the .rodata section in flash, and are available via symbol names as follows::
extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end");
The names are generated from the full name of the file, as given in ``COMPONENT_EMBED_FILES``. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files.
For an example of using this technique, see :example:`protocols/https_request` - the certificate file contents are loaded from the text .pem file at compile time.
Fully Overriding The Component Build Process
--------------------------------------------
Obviously, there are cases where all these recipes are insufficient for a
certain component, for example when the component is basically a wrapper
around another third-party component not originally intended to be
compiled under this build system. In that case, it's possible to forego
the esp-idf build system entirely by using a CMake feature called ExternalProject_. Example component CMakeLists::
# External build process for quirc, runs in source dir and
# produces libquirc.a
ExternalProject_Add(quirc_build
PREFIX ${COMPONENT_PATH}
SOURCE_DIR ${COMPONENT_PATH}/quirc
CONFIGURE_COMMAND ""
BUILD_IN_SOURCE 1
BUILD_COMMAND make CC=${CMAKE_C_COMPILER} libquirc.a
INSTALL_COMMAND ""
)
# Add libquirc.a to the build process
#
add_library(quirc STATIC IMPORTED GLOBAL)
add_dependencies(quirc quirc_build)
set_target_properties(quirc PROPERTIES IMPORTED_LOCATION
${COMPONENT_PATH}/quirc/libquirc.a)
set_target_properties(quirc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
${COMPONENT_PATH}/quirc/lib)
set_directory_properties( PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
"${COMPONENT_PATH}/quirc/libquirc.a")
(The above CMakeLists.txt can be used to create a component named ``quirc`` that builds the quirc_ project using its own Makefile.)
- ExternalProject_Add defines an external build system.
- ``SOURCE_DIR``, ``CONFIGURE_COMMAND``, ``BUILD_COMMAND`` and ``INSTALL_COMMAND`` should always be set. ``CONFIGURE_COMMAND`` can be set to an empty string if the build system has no "configure" step. ``INSTALL_COMMAND`` will generally be empty for ESP-IDF builds.
- Setting ``BUILD_IN_SOURCE`` means the build directory is the same as the source directory. Otherwise you can set ``BUILD_DIR``.
- Consult the ExternalProject_ documentation for more details about ``ExternalProject_Add()``
- The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is.
- Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.)
ExternalProject dependencies, clean builds
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CMake has some unusual behaviour around external project builds:
.. ADDITIONAL_MAKE_CLEAN_FILES_note:
- `ADDITIONAL_MAKE_CLEAN_FILES`_ only works when "make" is used as the build system. If Ninja_ or an IDE build system is used, it won't delete these files when cleaning.
- However, the ExternalProject_ configure & build commands will *always* be re-run after a clean is run.
- Therefore, there are two alternative recommended ways to configure the external build command:
1. Have the external ``BUILD_COMMAND`` run a full clean compile of all sources. The build command will be run if any of the dependencies passed to ``ExternalProject_Add`` with ``DEPENDS`` have changed, or if this is a clean build (ie any of ``idf.py clean``, ``ninja clean``, or ``make clean`` was run.)
2. Have the external ``BUILD_COMMAND`` be an incremental build command. Pass the parameter ``BUILD_ALWAYS 1`` to ``ExternalProject_Add``. This means the external project will be built each time a build is run, regardless of dependencies. This is only recommended if the external project has correct incremental build behaviour, and doesn't take too long to run.
The best of these approaches for building an external project will depend on the project itself, its build system, and whether you anticipate needing to frequently recompile the project.
.. _custom-sdkconfig-defaults-cmake:
Custom sdkconfig defaults
=========================
For example projects or other projects where you don't want to specify a full sdkconfig configuration, but you do want to override some key values from the esp-idf defaults, it is possible to create a file ``sdkconfig.defaults`` in the project directory. This file will be used when creating a new config from scratch, or when any new config value hasn't yet been set in the ``sdkconfig`` file.
To override the name of this file, set the ``SDKCONFIG_DEFAULTS`` environment variable.
Flash arguments
===============
There're some scenarios that we want to flash the target board without IDF. For this case we want to save the built binaries, esptool.py and esptool write_flash arguments. It's simple to write a script to save binaries and esptool.py.
After running a project build, the build directory contains binary output files (``.bin`` files) for the project and also the following flashing data files:
- ``flash_project_args`` contains arguments to flash the entire project (app, bootloader, partition table, PHY data if this is configured).
- ``flash_app_args`` contains arguments to flash only the app.
- ``flash_bootloader_args`` contains arguments to flash only the bootloader.
You can pass any of these flasher argument files to ``esptool.py`` as follows::
python esptool.py --chip esp32 write_flash @build/flash_project_args
Alternatively, it is possible to manually copy the parameters from the argument file and pass them on the command line.
The build directory also contains a generated file ``project_description.json`` which contains project information, including project flash information, in the JSON format. This file is used by ``idf.py`` and can also be used by other tools which need information about the project build.
Building the Bootloader
=======================
The bootloader is built by default as part of ``idf.py build``, or can be built standalone via ``idf.py bootloader``.
The bootloader is a special "subproject" inside :idf:`/components/bootloader/subproject`. It has separate .ELF and .BIN files to the main project. However it shares its configuration and build directory with the main project.
The subproject is inserted as an external project from the top-level project, by the file :idf_file:`/components/bootloader/project_include.cmake`. The main build process runs CMake for the subproject, which includes discovering components (a subset of the main components) and generating a bootloader-specific config (derived from the main ``sdkconfig``).
Writing Pure CMake Components
=============================
The ESP-IDF build system "wraps" CMake with the concept of "components", and helper functions to automatically integrate these components into a project build.
However, underneath the concept of "components" is a full CMake build system. It is also possible to make a component which is pure CMake.
Here is an example minimal "pure CMake" component CMakeLists file for a componen named ``json``::
add_library(json STATIC
cJSON/cJSON.c
cJSON/cJSON_Utils.c)
target_include_directories(json PUBLIC cJSON)
- This is actually an equivalent version of the IDF ``json`` component :idf_file:`/components/json/CMakeLists.txt`.
- This file quite simple as there are not a lot of source files. For components with a large number of files, the globbing behaviour of ESP-IDF's component logic can make the component CMakeLists style simpler.)
- Any time a component adds a library target with the component name, the ESP-IDF build system will automatically add this to the build, expose public include directories, etc. If a component wants to add a library target with a different name, dependencies will need to be added manually via CMake commands.
File Globbing & Incremental Builds
==================================
The preferred way to include source files in an ESP-IDF component is to set ``COMPONENT_SRC_DIRS``::
set(COMPONENT_SRCDIRS library platform)
The build system will automatically find (via "file globbing") all source files in this directory. Alternatively, files can be specified individually::
set(COMPONENT_SRCS library/a.c library/b.c platform/platform.c)
Usually, CMake_ recommends always to name all files individually (ie ``COMPONENT_SRCS``). This is because CMake is automatically re-run whenever a CMakeLists file changes. If a new source file is added and file globbing is used, then CMake won't know to automatically re-run and this file won't be added to the build.
The tradeoff is acceptable when you're adding the file yourself, because you can trigger a clean build or run ``idf.py reconfigure`` to manually re-run CMake_. However, the problem gets harder when you share your project with others who may check out a new version using a source control tool like Git...
For components which are part of ESP-IDF, we use a third party Git CMake integration module (:idf_file:`/tools/cmake/third_party/GetGitRevisionDescription.cmake`) which automatically re-runs CMake any time the repository commit changes. This means if you check out a new ESP-IDF version, CMake will automatically rerun.
For project CMakeLists files, ``MAIN_SRCS`` is a list of source files. Therefore if a new file is added, CMakeLists will change and this triggers a re-run of CMake. (This is "the CMake way" to do things.)
For project components (not part of ESP-IDF), there are a few options:
- If keeping your project file in Git, ESP-IDF will automaticallytrack the Git revision and re-run CMake if the revision changes.
- If some components are kept in a third git repo (not the project repo or ESP-IDF repo), you can add calls to the ``git_describe`` function to component CMakeLists to trigger re-runs of CMake.
- If not using Git, you remember to manually run ``idf.py reconfigure`` whenever a source file may change.
- Use ``COMPONENT_SRCS`` to list all source files in project components.
The best option will depend on your particular project and its users.
Migrating from ESP-IDF GNU Make System
======================================
Some aspects of the CMake-based ESP-IDF build system are very similar to the older GNU Make-based system. For example, to adapt a ``component.mk`` file to ``CMakeLists.txt`` variables like ``COMPONENT_SRCS`` and ``COMPONENT_SRCDIRS`` can stay the same and the syntax only needs changing to CMake syntax.
However, some features are significantly different or removed in the CMake-based system:
The following variables no longer exist in the CMake-based build system:
- ``COMPONENT_BUILD_DIR``: Use ``CMAKE_CURRENT_BINARY_DIR`` instead.
- ``COMPONENT_LIBRARY``: Defaulted to ``$(COMPONENT_NAME).a``, but the library name could be overriden by the user. The name of the component library can no longer be overriden by the user.
- ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. Use ``CMAKE_C_COMPILER``, ``CMAKE_C_LINK_EXECUTABLE``, ``CMAKE_OBJCOPY``, etc instead. `Full list here <language-variables-cmake>`_.
- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. These are no longer provided, external projects should detect any required host toolchain manually.
- ``COMPONENT_ADD_LDFLAGS``: Used to override linker flags. Use the CMake `target_link_libraries`_ command instead.
- ``COMPONENT_ADD_LINKER_DEPS``: List of files that linking should depend on. `target_link_libraries`_ will usually infer these dependencies automatically for files like linker scripts.
- ``COMPONENT_SUBMODULES``: No longer used by ESP-IDF components, the build system will automatically enumerate all submodules in the repo.
- ``COMPONENT_EXTRA_INCLUDES``: Used to be an alternative to ``COMPONENT_PRIV_INCLUDEDIRS`` for absolute paths. Use ``COMPONENT_PRIV_INCLUDEDIRS`` for all cases now (can be relative or absolute).
- ``COMPONENT_OBJS``: Used to be specified as a list of object files. Now specified as an optional list of source files via ``COMPONENT_SRCS``.
- ``COMPONENT_EXTRA_CLEAN``: Set property `ADDITIONAL_MAKE_CLEAN_FILES` instead but note `CMake has some restrictions around this functionality <ADDITIONAL_MAKE_CLEAN_FILES_note>`.
- ``COMPONENT_OWNBUILDTARGET`` & ``COMPONENT_OWNCLEANTARGET``: Use CMake `ExternalProject`_ instead. See `Fully Overriding The Component CMakeLists` for full details.
- ``COMPONENT_CONFIG_ONLY``: Call ``register_config_only_component()`` instead. See `Configuration-Only Components`_.
- ``CFLAGS``, ``CPPFLAGS``, ``CXXFLAGS``: Use CMake_ commands instead. See `Controlling Component Compilation`_.
The following variables no longer have default values:
- ``COMPONENT_SRCDIRS``
- ``COMPONENT_ADD_INCLUDEDIRS``
It is no longer necessary to set ``COMPONENT_SRCDIRS`` if setting ``COMPONENT_SRCS`` (in fact, ``COMPONENT_SRCDIRS`` is ignored if ``COMPONENT_SRCS`` is set).
.. _esp-idf-template: https://github.com/espressif/esp-idf-template
.. _cmake: https://cmake.org
.. _ninja: https://ninja-build.org
.. _esptool.py: https://github.com/espressif/esptool/#readme
.. _CMake v3.5 documentation_: https://cmake.org/cmake/help/v3.5/index.html
.. _cmake command line documentation: https://cmake.org/cmake/help/v3.5/manual/cmake.1.html#options
.. _add_compile_options-cmake: https://cmake.org/cmake/help/v3.5/command/add_compile_options.html
.. _if-cmake: https://cmake.org/cmake/help/v3.5/command/if.html
.. _string-cmake: https://cmake.org/cmake/help/v3.5/command/string.html
.. _cmake-faq-generated-files: https://cmake.org/Wiki/CMake_FAQ#How_can_I_generate_a_source_file_during_the_build.3F
.. _ADDITIONAL_MAKE_CLEAN_FILES: https://cmake.org/cmake/help/v3.5/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.html
.. _ExternalProject: https://cmake.org/cmake/help/v3.5/module/ExternalProject.html
.. _language-variables-cmake: https://cmake.org/cmake/help/v3.5/manual/cmake-variables.7.html#variables-for-languages
.. _set_source_files_properties: https://cmake.org/cmake/help/v3.5/command/set_source_files_properties.html
.. _target_compile_options: https://cmake.org/cmake/help/v3.5/command/target_compile_options.html
.. _target_link_libraries: https://cmake.org/cmake/help/v3.5/command/target_link_libraries.html#command:target_link_libraries
.. _cmake_toolchain_file: https://cmake.org/cmake/help/v3.5/variable/CMAKE_TOOLCHAIN_FILE.html
.. _quirc: https://github.com/dlbeer/quirc

View file

@ -0,0 +1,10 @@
CMake-Based Build System Preview
********************************
.. toctree::
:maxdepth: 1
Getting Started <../get-started/index-cmake>
Linux Setup <../get-started/linux-setup-cmake>
Windows Setup <../get-started/windows-setup-cmake>
Build System Guide <build-system-cmake>

View file

@ -193,3 +193,5 @@ Language features
To be written.
.. _cmake-lint: https://github.com/richq/cmake-lint

View file

@ -0,0 +1,66 @@
Add IDF_PATH & idf.py PATH to User Profile
==========================================
.. note::
The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). The original (non-cmake) version of this doc is :doc:`here<add-idf_path-to-profile>`.
To use the CMake-based build system and the idf.py tool, two modifications need to be made to system environment variables:
- ``IDF_PATH`` needs to be set to the path of the directory containing ESP-IDF.
- System ``PATH`` variable to include the directory containing the ``idf.py`` tool (part of ESP-IDF).
To preserve setting of these variables between system restarts, add them to the user profile by following the instructions below.
.. note::
If you only plan to use ``idf.py`` from the command line, and don't need integration with any IDEs, then you can skip setting ``IDF_PATH``. ``idf.py`` will use its own IDF directory as the default ``IDF_PATH``.
.. _add-paths-to-profile-windows-cmake:
Windows
-------
To edit Environment Variables on Windows 10, search for "Edit Environment Vartiables" under the Start menu.
On earlier Windows versions, open the System Control Panel then choose "Advanced" and look for the Environment Variables button.
You can set these environment variables for all users, or only for the current user, depending on whether other users of your computer will be using ESP-IDF.
- Click ``New...`` to add a new environment variable named ``IDF_PATH``. Set the path to directory containing ESP-IDF, for example ``C:\Users\myuser\esp\esp-idf``.
- Locate the ``Path`` environment variable and double-click to edit it. Append the following to the end: ``;%IDF_PATH%\tools``. This will allow you to run ``idf.py`` and other tools from Windows Command Prompt.
If you got here from section :ref:`get-started-setup-path-cmake`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project-cmake`.
.. _add-idf_path-to-profile-linux-macos-cmake:
Linux and MacOS
---------------
Set up ``IDF_PATH`` and add ``idf.py`` to the PATH by adding the following two lines to ``~/.profile`` file::
export IDF_PATH=~/esp/esp-idf
export PATH="$PATH:'$IDF_PATH/tools'"
Log off and log in back to make this change effective.
.. note::
If you have ``/bin/bash`` set as login shell, and both ``.bash_profile`` and ``.profile`` exist, then update ``.bash_profile`` instead.
Run the following command to check if ``IDF_PATH`` is set::
printenv IDF_PATH
The path previously entered in ``~/.profile`` file (or set manually) should be printed out.
To verify idf.py is now on the ``PATH``, you can run the following::
which idf.py
A path like ``${IDF_PATH}/tools/idf.py`` should be printed.
If you do not like to have ``IDF_PATH`` set up permanently, you should enter it manually in terminal window on each restart or logout::
export IDF_PATH=~/esp/esp-idf
If you got here from section :ref:`get-started-setup-path-cmake`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project-cmake`.

View file

@ -125,5 +125,7 @@ If you see some legible log, it means serial connection is working and you are r
If you got here from section :ref:`get-started-connect` when installing s/w for ESP32 development, then go back to section :ref:`get-started-configure`.
(If you are following the CMake preview documentation, `go back to the CMake-specific section instead <:ref:get-started-configure>`.
.. _esptool documentation: https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection#automatic-bootloader

View file

@ -0,0 +1,346 @@
***************************************
Get Started with the CMake build system
***************************************
.. note::
The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). For a stable experience, follow the :doc:`original (non-cmake) setup guide here<index>`.
This document is intended to help users set up the software environment for development of applications using hardware based on the Espressif ESP32.
Through a simple example we would like to illustrate how to use ESP-IDF (Espressif IoT Development Framework), including the menu based configuration, compiling the ESP-IDF and firmware download to ESP32 boards.
Introduction
============
ESP32 integrates Wi-Fi (2.4 GHz band) and Bluetooth 4.2 solutions on a single chip, along with dual high performance cores, Ultra Low Power co-processor and several peripherals. Powered by 40 nm technology, ESP32 provides a robust, highly integrated platform to meet the continuous demands for efficient power usage, compact design, security, high performance, and reliability.
Espressif provides the basic hardware and software resources that help application developers to build their ideas around the ESP32 series hardware. The software development framework by Espressif is intended for rapidly developing Internet-of-Things (IoT) applications, with Wi-Fi, Bluetooth, power management and several other system features.
What You Need
=============
To develop applications for ESP32 you need:
* **PC** loaded with either Windows, Linux or Mac operating system
* **Toolchain** to build the **Application** for ESP32
* **ESP-IDF** that essentially contains API for ESP32 and scripts to operate the **Toolchain**
* A text editor to write programs (**Projects**) in C, e.g. `Eclipse <https://www.eclipse.org/>`_
* The **ESP32** board itself and a **USB cable** to connect it to the **PC**
.. figure:: ../../_static/what-you-need.png
:align: center
:alt: Development of applications for ESP32
:figclass: align-center
Development of applications for ESP32
Preparation of development environment consists of three steps:
1. Setup of **Toolchain**
2. Getting of **ESP-IDF** from GitHub
3. Installation and configuration of **Eclipse**
You may skip the last step, if you prefer to use different editor.
Having environment set up, you are ready to start the most interesting part - the application development. This process may be summarized in four steps:
1. Configuration of a **Project** and writing the code
2. Compilation of the **Project** and linking it to build an **Application**
3. Flashing (uploading) of the **Application** to **ESP32**
4. Monitoring / debugging of the **Application**
See instructions below that will walk you through these steps.
Guides
======
If you have one of ESP32 development boards listed below, click on provided links to get you up and running.
.. toctree::
:maxdepth: 1
ESP32 DevKitC <get-started-devkitc>
ESP-WROVER-KIT <get-started-wrover-kit>
ESP32-PICO-KIT <get-started-pico-kit>
If you have different board, move to sections below.
.. _get-started-setup-toolchain-cmake:
Setup Toolchain
===============
The quickest way to start development with ESP32 is by installing a prebuilt toolchain. Pick up your OS below and follow provided instructions.
.. toctree::
:hidden:
Windows <windows-setup-cmake>
Linux <linux-setup-cmake>
MacOS <macos-setup-cmake>
+-------------------+-------------------+-------------------+
| |windows-logo| | |linux-logo| | |macos-logo| |
+-------------------+-------------------+-------------------+
| `Windows`_ | `Linux`_ | `Mac OS`_ |
+-------------------+-------------------+-------------------+
.. |windows-logo| image:: ../../_static/windows-logo.png
:target: ../get-started/windows-setup-cmake.html
.. |linux-logo| image:: ../../_static/linux-logo.png
:target: ../get-started/linux-setup-cmake.html
.. |macos-logo| image:: ../../_static/macos-logo.png
:target: ../get-started/macos-setup-cmake.html
.. _Windows: ../get-started/windows-setup-cmake.html
.. _Linux: ../get-started/linux-setup-cmake.html
.. _Mac OS: ../get-started/macos-setup-cmake.html
.. note::
We are using ``~/esp`` directory to install the prebuilt toolchain, ESP-IDF and sample applications. You can use different directory, but need to adjust respective commands.
Depending on your experience and preferences, instead of using a prebuilt toolchain, you may want to customize your environment. To set up the system your own way go to section :ref:`get-started-customized-setup`.
Once you are done with setting up the toolchain then go to section :ref:`get-started-get-esp-idf-cmake`.
.. _get-started-get-esp-idf-cmake:
Get ESP-IDF
===========
.. highlight:: bash
Besides the toolchain (that contains programs to compile and build the application), you also need ESP32 specific API / libraries. They are provided by Espressif in `ESP-IDF repository <https://github.com/espressif/esp-idf>`_. To get it, open terminal, navigate to the directory you want to put ESP-IDF, and clone it using ``git clone`` command::
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
ESP-IDF will be downloaded into ``~/esp/esp-idf``.
.. note::
Do not miss the ``--recursive`` option. If you have already cloned ESP-IDF without this option, run another command to get all the submodules::
cd ~/esp/esp-idf
git submodule update --init
.. _get-started-setup-path-cmake:
Setup Paths for ESP-IDF
=======================
The toolchain programs access ESP-IDF using ``IDF_PATH`` environment variable. This variable should be set up on your PC, otherwise projects will not build. Setting may be done manually, each time PC is restarted. Another option is to set up it permanently by defining ``IDF_PATH`` in user profile. To do so, follow instructions specific to :ref:`Windows <add-paths-to-profile-windows-cmake>` , :ref:`Linux and MacOS <add-idf_path-to-profile-linux-macos-cmake>` in section :doc:`add-idf_path-to-profile-cmake`.
.. _get-started-start-project-cmake:
Start a Project
===============
Now you are ready to prepare your application for ESP32. To start off quickly, we will use :example:`get-started/hello_world` project from :idf:`examples` directory in IDF.
Copy :example:`get-started/hello_world` to ``~/esp`` directory. You can do this via your operating system's file manager (like Windows Explorer). Or for Linux and MacOS, to do it from a Bash shell::
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world .
You can also find a range of example projects under the :idf:`examples` directory in ESP-IDF. These example project directories can be copied in the same way as presented above, to begin your own projects.
.. important::
The esp-idf build system does not support spaces in paths to esp-idf or to projects.
.. _get-started-connect-cmake:
Connect
=======
You are almost there. To be able to proceed further, connect ESP32 board to PC, check under what serial port the board is visible and verify if serial communication works. If you are not sure how to do it, check instructions in section :doc:`establish-serial-connection`. Note the port number, as it will be required in the next step.
.. _get-started-configure-cmake:
Configure
=========
Open a terminal window (or a Windows Command Prompt), go to directory of the ``hello_world`` application by typing ``cd ~/esp/hello_world`` or ```cd \Users\esp\hello_world`` for Windows. Then start the project configuration utility ``menuconfig``::
cd ~/esp/hello_world
idf.py menuconfig
.. note::
The first time you run ``idf.py`` for a given ESP-IDF project, CMake will run to configure the project. If any software tools or other requirements like environment variables are not configured correctly, this will produce a configuration error at this stage.
.. note::
The previous (non-CMake) build system instructions would have told you to run ``make`` here, but the CMake-based system doesn't require use of ``make``.
If previous steps have been done correctly, the following menu will be displayed:
.. figure:: ../../_static/project-configuration.png
:align: center
:alt: Project configuration - Home window
:figclass: align-center
Project configuration - Home window
In the menu, navigate to ``Serial flasher config`` > ``Default serial port`` to configure the serial port, where project will be loaded to. Confirm selection by pressing enter, save configuration by selecting ``< Save >`` and then exit application by selecting ``< Exit >``.
.. note::
On Windows, serial ports have names like COM1. On MacOS, they start with ``/dev/cu.``. On Linux, they start with ``/dev/tty``.
(See :doc:`establish-serial-connection` for full details.)
Here are couple of tips on navigation and use of ``menuconfig``:
* Use up & down arrow keys to navigate the menu.
* Use Enter key to go into a submenu, Escape key to go out or to exit.
* Type ``?`` to see a help screen. Enter key exits the help screen.
* Use Space key, or ``Y`` and ``N`` keys to enable (Yes) and disable (No) configuration items with checkboxes "``[*]``"
* Pressing ``?`` while highlighting a configuration item displays help about that item.
* Type ``/`` to search the configuration items.
.. _get-started-build-flash-cmake:
Build and Flash
===============
Now you can build and flash the application. To build (but not flash) run::
idf.py build
This will compile the application and all the ESP-IDF components, generate bootloader, partition table, and application binaries.
To flash these built firmware files to your ESP32 board, run::
idf.py -p <PORT> flash
For ``<PORT>``, specify the connected ESP32's serial port like ``/dev/ttyUSB0`` (Linux), ``/dev/cu.USBx`` (MacOS) or ``COM1`` (Windows).
.. highlight:: none
::
esptool.py v2.0-beta2
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000)...
esptool.py v2.0-beta2
Connecting........___
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Attaching SPI flash...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 11616 bytes to 6695...
Wrote 11616 bytes (6695 compressed) at 0x00001000 in 0.1 seconds (effective 920.5 kbit/s)...
Hash of data verified.
Compressed 408096 bytes to 171625...
Wrote 408096 bytes (171625 compressed) at 0x00010000 in 3.9 seconds (effective 847.3 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 82...
Wrote 3072 bytes (82 compressed) at 0x00008000 in 0.0 seconds (effective 8297.4 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting...
If there are no issues, at the end of build process, you should see messages describing progress of loading process. Finally, the end module will be reset and "hello_world" application will start.
.. note::
It's not necessary to run ``idf.py build`` before ``idf.py flash``, then flash step will automatically build the firmware if it needs to be built.
.. _get-started-build-monitor-cmake:
Monitor
=======
To see if "hello_world" application is indeed running, type ``idf.py monitor``. This command is launching :doc:`IDF Monitor <idf-monitor>` application::
$ idf.py monitor
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun 8 2016 00:22:57
...
Several lines below, after start up and diagnostic log, you should see "Hello world!" printed out by the application. ::
...
Hello world!
Restarting in 10 seconds...
I (211) cpu_start: Starting scheduler on APP CPU.
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
To exit the monitor use shortcut ``Ctrl+]``.
.. note::
If instead of the messages above, you see a random garbage similar to::
e<><65><EFBFBD>)(Xn@<40>y.!<21><>(<28>PW+)<29><>Hn9a؅/9<>!<21>t5<74><35>P<EFBFBD>~<7E>k<EFBFBD><6B>e<EFBFBD>ea<65>5<EFBFBD>jA
~zY<7A><59>Y(1<>,1<15><> e<><65><EFBFBD>)(Xn@<40>y.!Dr<44>zY(<28>jpi<70>|<7C>+z5Ymvp
or monitor fails shortly after upload, your board is likely using 26MHz crystal, while the ESP-IDF assumes default of 40MHz. Exit the monitor, go back to the :ref:`menuconfig <get-started-configure>`, change :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` to 26MHz, then :ref:`build and flash <get-started-build-flash>` the application again. This is found under ``idf.py menuconfig`` under Component config --> ESP32-specific --> Main XTAL frequency.
To execute ``idf.py flash`` and then ``idf.py monitor``, you can run ``idf.py flash monitor``. Check section :doc:`IDF Monitor <idf-monitor>` for handy shortcuts and more details on using this application.
.. note::
At the moment not all of the idf_monitor shortcuts work correctly with the CMake-based build system.
That's all what you need to get started with ESP32!
Now you are ready to try some other :idf:`examples`, or go right to developing your own applications.
Updating ESP-IDF
================
After some time of using ESP-IDF, you may want to update it to take advantage of new features or bug fixes. The simplest way to do so is by deleting existing ``esp-idf`` folder and cloning it again, exactly as when doing initial installation described in sections :ref:`get-started-get-esp-idf`.
Another solution is to update only what has changed. This method is useful if you have slow connection to the GiHub. To do the update run the following commands::
cd ~/esp/esp-idf
git pull
git submodule update --init --recursive
The ``git pull`` command is fetching and merging changes from ESP-IDF repository on GitHub. Then ``git submodule update --init --recursive`` is updating existing submodules or getting a fresh copy of new ones. On GitHub the submodules are represented as links to other repositories and require this additional command to get them onto your PC.
If you would like to use specific release of ESP-IDF, e.g. `v2.1`, run::
cd ~/esp
git clone https://github.com/espressif/esp-idf.git esp-idf-v2.1
cd esp-idf-v2.1/
git checkout v2.1
git submodule update --init --recursive
After that remember to :doc:`add-idf_path-to-profile-cmake`, so the toolchain scripts know where to find the ESP-IDF in it's release specific location.
Related Documents
=================
.. toctree::
:maxdepth: 1
add-idf_path-to-profile-cmake
establish-serial-connection
make-project
idf-monitor
toolchain-setup-scratch

View file

@ -0,0 +1,113 @@
*************************************
Setup for cmake on Linux
*************************************
.. note::
The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). The original (non-cmake) version of this doc is :doc:`here<linux-setup>`.
Install Prerequisites
=====================
To compile with ESP-IDF you need to get the following packages:
- CentOS 7::
sudo yum install git wget ncurses-devel flex bison gperf python pyserial cmake ninja-build
- Ubuntu and Debian::
sudo apt-get install git wget libncurses-dev flex bison gperf python python-serial cmake ninja-build
- Arch::
sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial cmake ninja
.. note::
CMake version 3.5 or newer is required for use with ESP-IDF. Older Linux distributions may require updating, or enabling of a "backports" repository, or installing of a "cmake3" package not "cmake")
Toolchain Setup
===============
ESP32 toolchain for Linux is available for download from Espressif website:
- for 64-bit Linux:
https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
- for 32-bit Linux:
https://dl.espressif.com/dl/xtensa-esp32-elf-linux32-1.22.0-80-g6c4433a-5.2.0.tar.gz
1. Download this file, then extract it in ``~/esp`` directory::
mkdir -p ~/esp
cd ~/esp
tar -xzf ~/Downloads/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
.. _setup-linux-toolchain-add-it-to-path:
2. The toolchain will be extracted into ``~/esp/xtensa-esp32-elf/`` directory.
To use it, you will need to update your ``PATH`` environment variable in ``~/.profile`` file. To make ``xtensa-esp32-elf`` available for all terminal sessions, add the following line to your ``~/.profile`` file::
export PATH="$PATH:$HOME/esp/xtensa-esp32-elf/bin"
Alternatively, you may create an alias for the above command. This way you can get the toolchain only when you need it. To do this, add different line to your ``~/.profile`` file::
alias get_esp32='export PATH="$PATH:$HOME/esp/xtensa-esp32-elf/bin"'
Then when you need the toolchain you can type ``get_esp32`` on the command line and the toolchain will be added to your ``PATH``.
.. note::
If you have ``/bin/bash`` set as login shell, and both ``.bash_profile`` and ``.profile`` exist, then update ``.bash_profile`` instead.
3. Log off and log in back to make the ``.profile`` changes effective. Run the following command to verify if ``PATH`` is correctly set::
printenv PATH
You are looking for similar result containing toolchain's path at the end of displayed string::
$ printenv PATH
/home/user-name/bin:/home/user-name/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/user-name/esp/xtensa-esp32-elf/bin
Instead of ``/home/user-name`` there should be a home path specific to your installation.
Permission issues /dev/ttyUSB0
------------------------------
With some Linux distributions you may get the ``Failed to open port /dev/ttyUSB0`` error message when flashing the ESP32. :ref:`This can be solved by adding the current user to the dialout group<linux-dialout-group>`.
Arch Linux Users
----------------
To run the precompiled gdb (xtensa-esp32-elf-gdb) in Arch Linux requires ncurses 5, but Arch uses ncurses 6.
Backwards compatibility libraries are available in AUR_ for native and lib32 configurations:
- https://aur.archlinux.org/packages/ncurses5-compat-libs/
- https://aur.archlinux.org/packages/lib32-ncurses5-compat-libs/
Before installing these packages you might need to add the author's public key to your keyring as described in the "Comments" section at the links above.
Alternatively, use crosstool-NG to compile a gdb that links against ncurses 6.
Next Steps
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`.
Related Documents
=================
.. toctree::
:maxdepth: 1
linux-setup-scratch
.. _AUR: https://wiki.archlinux.org/index.php/Arch_User_Repository

View file

@ -0,0 +1,61 @@
*************************
Setup for CMake on Mac OS
*************************
.. note::
The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). The original (non-cmake) version of this doc is `here <:doc:macos-setup>`.
Install Prerequisites
=====================
- install pip::
sudo easy_install pip
- install pyserial::
sudo pip install pyserial
- install CMake & Ninja build:
If you have HomeBrew, you can run::
brew install cmake ninja
Otherwise, consult the CMake_ and Ninja_ home pages for Mac OS installation.
Toolchain Setup
===============
ESP32 toolchain for macOS is available for download from Espressif website:
https://dl.espressif.com/dl/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz
Download this file, then extract it in ``~/esp`` directory::
mkdir -p ~/esp
cd ~/esp
tar -xzf ~/Downloads/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz
.. _setup-macos-toolchain-add-it-to-path:
The toolchain will be extracted into ``~/esp/xtensa-esp32-elf/`` directory.
To use it, you will need to update your ``PATH`` environment variable in ``~/.profile`` file. To make ``xtensa-esp32-elf`` available for all terminal sessions, add the following line to your ``~/.profile`` file::
export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin
Alternatively, you may create an alias for the above command. This way you can get the toolchain only when you need it. To do this, add different line to your ``~/.profile`` file::
alias get_esp32="export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin"
Then when you need the toolchain you can type ``get_esp32`` on the command line and the toolchain will be added to your ``PATH``.
Next Steps
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`.
.. _cmake: https://cmake.org/
.. _ninja: https://ninja-build.org/

View file

@ -0,0 +1,78 @@
***************************************
Setup for cmake on Windows
***************************************
.. note::
The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). The original (non-cmake) version of this doc is :doc:`here<windows-setup>`.
.. note::
Windows support in particular currently requires more manual installation of tools and setup of system Path than is planned for final release.
Introduction
============
Unlike the conventional ESP-IDF make-based build environment, cmake does not require a GNU-compatible environment for building. You can build with cmake from Windows Command Prompt, or from an IDE with cmake support.
Tools
=====
The following software packages need to be installed:
cmake
^^^^^
Download the latest stable release of CMake_ for Windows and run the installer.
When the installer asks for Install Options, choose either "Add CMake to the system PATH for all users" or "Add CMake to the system PATH for the current user".
Ninja build
^^^^^^^^^^^
Download the ninja_ latest stable Windows release from the (`download page <ninja-dl>`_).
The Ninja for Windows download is a .zip file containing a single ``ninja.exe`` file which needs to be unzipped to a directory on your PATH.
An easy directory to place ``ninja.exe`` is the CMake executable directory, as this is already on the PATH. This directory will be something like ``C:\Program Files\CMake\bin`` (look for the file ``cmake.exe`` in this directory to know it's the correct one).
Python 2.x
^^^^^^^^^^
Download the latest Python_ 2.7 for Windows installer, and run it.
The "Customise" step of the Python installer gives a list of options. The last option is "Add python.exe to Path". Change this option to select "Will be installed".
Once Python is installed, open a Windows Command Prompt from the Start menu and run the following command::
pip install pyserial
Toolchain Setup
===============
Download the precompiled Windows toolchain from dl.espressif.com:
https://dl.espressif.com/dl/xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip
Unzip the zip file to ``C:\Program Files`` (or some other location). The zip file contains a single directory ``xtensa-esp32-elf``.
Next, you need to add the ``bin`` subdirectory to your PATH. For example, the directory to add may be ``C:\Program Files\xtensa-esp32-elf\bin``.
Open the System control panel and navigate to the Environment Variables dialog. (On Windows 10, this is found under Advanced System Settings).
Double-click the ``Path`` variable (either User or System Path, depending if you want other users to use the toolchain.) Go to the end of the value, and append ``;C:\Program Files\xtensa-esp32-elf\bin`` (or whatever the path to your toolchain ``bin`` directory is).
.. note::
If you already have the MSYS2 environment (for use with the "GNU Make" build system) installed, you can skip the separate download and add the directory ``C:\msys32\opt\xtensa-esp32-elf\bin`` to the Path instead, as the toolchain is included in the MSYS2 environment.
Next Steps
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`.
.. _cmake: https://cmake.org/download/
.. _ninja: https://ninja-build.org/
.. _ninja-dl: https://github.com/ninja-build/ninja/releases
.. _Python: https://www.python.org/downloads/windows/

View file

@ -40,6 +40,7 @@ This is the documentation for Espressif IoT Development Framework (`esp-idf <htt
API Reference <api-reference/index>
H/W Reference <hw-reference/index>
API Guides <api-guides/index>
CMake Build System Preview <api-guides/cmake-preview-index>
Contribute <contribute/index>
Resources <resources>
Copyrights <COPYRIGHT>

View file

@ -133,20 +133,23 @@ function(components_finish_registration)
# (we can't do this until all components are registered, because if(TARGET ...) won't work
foreach(a ${COMPONENTS} ${CMAKE_PROJECT_NAME}.elf)
if (TARGET ${a})
get_target_property(a_imported ${a} IMPORTED)
get_target_property(a_type ${a} TYPE)
if (${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
foreach(b ${COMPONENTS})
if (TARGET ${b} AND NOT ${a} STREQUAL ${b})
# Add all public compile options from b in a
target_include_directories(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_DEFINITIONS>)
target_compile_options(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>)
endif()
endforeach(b)
endif(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
if (NOT a_imported)
if (${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
foreach(b ${COMPONENTS})
if (TARGET ${b} AND NOT ${a} STREQUAL ${b})
# Add all public compile options from b in a
target_include_directories(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_DEFINITIONS>)
target_compile_options(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>)
endif()
endforeach(b)
endif(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
endif(NOT a_imported)
if (${a_type} MATCHES .+_LIBRARY)
set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}")
@ -166,4 +169,6 @@ function(components_finish_registration)
target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${COMPONENT_LIBRARIES})
message(STATUS "Component libraries: ${COMPONENT_LIBRARIES}")
endfunction(components_finish_registration)

View file

@ -30,9 +30,6 @@ macro(idf_set_global_variables)
# path to idf.py tool
set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py")
# generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
endmacro()
# Add all the IDF global compiler & preprocessor options
@ -161,6 +158,31 @@ endfunction(add_map_file)
# Add argument file(s) for flashing the app, and for flashing the whole system
function(add_flasher_argfile)
endfunction(add_flasher_argfile)
# component_compile_options
#
# Wrapper around target_compile_options that passes the component name
function(component_compile_options)
target_compile_options(${COMPONENT_NAME} PRIVATE ${ARGV})
endfunction()
# component_compile_definitions
#
# Wrapper around target_compile_definitions that passes the component name
function(component_compile_definitions)
target_compile_definitions(${COMPONENT_NAME} PRIVATE ${ARGV})
endfunction()
# idf_get_git_revision
#
# Set global IDF_VER to the git revision of ESP-IDF.
#
# Running git_describe() here automatically triggers rebuilds
# if the ESP-IDF git version changes
function(idf_get_git_revision)
git_describe(IDF_VER "${IDF_PATH}")
add_definitions(-DIDF_VER=\"${IDF_VER}\")
git_submodule_check("${IDF_PATH}")
set(IDF_VER ${IDF_VER} PARENT_SCOPE)
endfunction()

View file

@ -9,6 +9,8 @@ macro(kconfig_set_variables)
set(SDKCONFIG_JSON ${CMAKE_BINARY_DIR}/sdkconfig.json)
set(ROOT_KCONFIG ${IDF_PATH}/Kconfig)
set_default(SDKCONFIG_DEFAULTS "${SDKCONFIG}.defaults")
endmacro()
# Use the existing Makefile to build mconf (out of tree) when needed
@ -46,8 +48,8 @@ function(kconfig_process_config)
endif()
endforeach(dir ${COMPONENT_PATHS})
if(EXISTS ${SDKCONFIG}.defaults)
set(defaults_arg --defaults "${SDKCONFIG}.defaults")
if(EXISTS ${SDKCONFIG_DEFAULTS})
set(defaults_arg --defaults "${SDKCONFIG_DEFAULTS}")
endif()
set(confgen_basecommand

View file

@ -44,6 +44,12 @@ macro(project name)
# Search COMPONENT_DIRS for COMPONENTS, make a list of full paths to each component in COMPONENT_PATHS
components_find_all("${COMPONENT_DIRS}" "${COMPONENTS}" COMPONENT_PATHS COMPONENTS)
# Print list of components
string(REPLACE ";" " " COMPONENTS_SPACES "${COMPONENTS}")
message(STATUS "Component names: ${COMPONENTS_SPACES}")
unset(COMPONENTS_SPACES)
message(STATUS "Component paths: ${COMPONENT_PATHS}")
kconfig_set_variables()
kconfig_process_config()
@ -59,17 +65,20 @@ macro(project name)
# Declare the actual cmake-level project
_project(${name} ASM C CXX)
# Verify the environment is configured correctly
# generate compile_commands.json (needs to come after project)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# Verify the environment is configured correctly
idf_verify_environment()
# Add some idf-wide definitions
idf_set_global_compiler_options()
# Check git version (may trigger reruns of cmake)
# & set GIT_REVISION/IDF_VER variable
git_describe(GIT_REVISION)
add_definitions(-DIDF_VER=\"${GIT_REVISION}\")
git_submodule_check("${IDF_PATH}")
# Check git revision (may trigger reruns of cmake)
## sets IDF_VER to IDF git revision
idf_get_git_revision()
## if project uses git, retrieve revision
git_describe(PROJECT_VER "${CMAKE_CURRENT_SOURCE_DIR}")
# Include any top-level project_include.cmake files from components
foreach(component ${COMPONENT_PATHS})
@ -79,10 +88,12 @@ macro(project name)
#
# Add each component to the build as a library
#
foreach(component ${COMPONENT_PATHS})
get_filename_component(component_name ${component} NAME)
add_subdirectory(${component} ${component_name})
foreach(COMPONENT_PATH ${COMPONENT_PATHS})
get_filename_component(COMPONENT_NAME ${COMPONENT_PATH} NAME)
add_subdirectory(${COMPONENT_PATH} ${COMPONENT_NAME})
endforeach()
unset(COMPONENT_NAME)
unset(COMPONENT_PATH)
#
# Add the app executable to the build (has name of PROJECT.elf)

View file

@ -5,7 +5,7 @@
"config_file": "${SDKCONFIG}",
"app_elf": "${PROJECT_NAME}.elf",
"app_bin": "${PROJECT_NAME}.bin",
"git_revision": "${GIT_REVISION}",
"git_revision": "${IDF_VER}",
"project_binaries": {
"bootloader": [ "0x1000", "bootloader/bootloader.bin" ],
"partition_table": [ "0x8000", "partition_table/partition-table.bin" ],

View file

@ -141,7 +141,11 @@ def _ensure_build_directory(args, always_run_cmake=False):
if args.generator is None:
args.generator = detect_cmake_generator()
try:
_run_tool("cmake", ["cmake", "-G", args.generator, project_dir], cwd=args.build_dir)
cmake_args = ["cmake", "-G", args.generator]
if not args.no_warnings:
cmake_args += [ "--warn-uninitialized" ]
cmake_args += [ project_dir]
_run_tool("cmake", cmake_args, cwd=args.build_dir)
except:
# don't allow partially valid CMakeCache.txt files,
# to keep the "should I run cmake?" logic simple
@ -315,6 +319,7 @@ def main():
parser.add_argument('-C', '--project-dir', help="Project directory", default=os.getcwd())
parser.add_argument('-B', '--build-dir', help="Build directory", default=None)
parser.add_argument('-G', '--generator', help="Cmake generator", choices=GENERATOR_CMDS.keys())
parser.add_argument('-n', '--no-warnings', help="Disable Cmake warnings")
parser.add_argument('actions', help="Actions (build targets or other operations)", nargs='+',
choices=ACTIONS.keys())