This is basically a renamed version of __create_save_defconfig_target.
The creation of the save-defconfig target is done in
`idf_project_default()`.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
For a specified executable, create a menuconfig target using the name
provided in the TARGET option. The function generates a config.env file
specific to the executable, where Kconfig files for components linked to
the executable and Kconfig files for components not linked to it are
separated. This separation allows for a clear visual distinction between
the configuration of components that are linked and those that are not
linked to the executable within the menuconfig.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Generate the config.env file for the specified executable. The
configuration file will be stored in the build directory, within a
directory named after the executable target name. The kconfigs*.in
files, which are generated by prepare_kconfig_files.py, will also be
stored in this directory.
This function primarily prepares the arguments for the
__create_config_env_file function based on the components linked to the
executable, ensuring that component Kconfig files are stored in the
appropriate kconfigs*.in files, depending on whether the component is
linked to the executable.
The directory where the generated files are stored is added to the
executable CONFIG_ENV_DIR property.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The __create_config_env_file function generates a configuration file for
the prepare_kconfig_files.py script. Currently, it specifies the paths
for the kconfigs*.in files, which are generated by
prepare_kconfig_files.py, to be located in the build directory. The
kconfigs*.in files, along with the configuration file, must also be
generated for each executable, as each executable may have a
different set of linked components. Set the paths for the
kconfigs*.in files to be generated by the prepare_kconfig_files.py
script in the same directory as the configuration file.
Also allow explicit specification of which component configuration files
should be placed in different kconfigs*.in files. For sdkconfig
generation, it is not relevant whether a component's Kconfig file is
placed in the kconfigs.in or kconfigs_excluded.in file. This distinction
is only important for visually separating the configuration of included
and excluded components in the menuconfig. For the main sdkconfig, all
component Kconfig files are placed in the kconfigs.in file, and the
generated kconfigs*.in files are stored in the build directory. For
executables, the generated kconfigs*.in files will be stored in separate
directories for each executable.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The excluded Kconfig files cannot be collected globally, they must be
collected per executable. The distinction between included and excluded
Kconfig files is relevant only for menuconfig, which is specific to each
executable, as each executable may have a different set of linked
components. For the global sdkconfig file and its CMake and JSON
variants, whether the Kconfig files are excluded or not is irrelevant.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Currently, the cmakev2 implementation of Kconfig name consistency has a
slightly different warning message compared to cmakev2, causing the test
`test_build.py::test_build_with_misspelled_kconfig` to fail. Make the
warning messages consistent with cmakev1.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Currently, cmakev2 evaluates each component using add_subdirectory with
the EXCLUDE_FROM_ALL option. The intention was to exclude all components
from being built by default unless they are explicitly linked to an
executable based on dependencies. This approach aims to avoid building
components that are included but not actually linked to the executable.
However, this has the side effect of preventing components from adding
their custom targets to the "all" target, which is used, for example, by
esp_phy. Generally, we should not restrict components from adding
targets to "all". Since components are only included if explicitly
requested by default, removing the EXCLUDE_FROM_ALL option should be
acceptable.
The downside is that if IDF_INCLUDE_ALL_COMPONENTS is set and the user
runs `idf.py build`, all components will be built, even if they are not
linked to the executable.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Currently, the check is based on the existence of sdkconfig, but there
may be situations where sdkconfig exists without containing
CONFIG_IDF_TARGET. Perform a target consistency check only if the target
is identified in the main sdkconfig file.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The function arguments in the documentation comments were using field
list, which caused text overflow in the generated documentation and
generally resulted in poor formatting. Let's use paragraphs for
the argument descriptions instead.
The documentation comments are written in reStructuredText, but
currently, they use inconsistent indentation. Standardize all the
documentation comments to use a four-character indentation.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add a Sphinx extension that introduces a new `cmakev2` domain with
multiple directives, allowing for the automatic extraction of
documentation comments from CMake files and their inclusion in the
Sphinx-generated documentation.
Directives:
- `cmakev2:include`: The included CMake file is processed for
documentation comments within the `#[[api` and `#]]` marks, which
should contain valid reStructuredText markup.
- `cmakev2:function`: Creates a CMake function node. All function nodes
are sorted by name and placed into the `_cmakev2_functions` section.
- `cmakev2:macro`: Creates a CMake macro node. All macro nodes are
sorted by name and placed into the `_cmakev2_macros` section.
- `cmakev2:variable`: Describes a CMake variable node. All variable
nodes are sorted by name and placed into the `_cmakev2_variables`
section.
Each node can be referenced with `` :cmakev2:ref:`<node name>` ``, where
the node name is the function, macro, or variable name as used in the
related directive.
Example:
CMake file:
```
#[[api
.. cmakev2:function:: idf_flash_binary
#]]
```
This function can be referenced with `` :cmakev2:ref:`idf_flash_binary` ``
and will be placed in the `.. _cmakev2_functions:` section.
The extension is currently located in esp-idf, but in the future, we
should consider moving it to esp-docs.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The build system should include the file generated by the component
manager after downloading components even if the component manager
requested a re-run due to a missing Kconfig.
This commit updates the order of initialization for build system v2. All
non-project initializations are handled in idf.cmake and all
project-specific initializations are now moved to idf_project_init().
Generate the flasher_args.json file for the global flash target for
tools that require it.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Generate binary images and add flash targets for hello_world_example and
fatfs_example.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
All other functions, such as idf_build_binary, use OUTPUT_FILE. This is
more descriptive and provides more flexibility to add additional
file-related options in the future if necessary. Make
idf_build_generate_metadata consistent with the other function
interfaces by using OUTPUT_FILE.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Use idf_build_binary, idf_sign_binary, and idf_flash_binary to generate
and flash the default project application.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Given the binary target generated by the idf_build_binary or
idf_sign_binary function, add a new POST_BUILD dependency that displays
a message indicating the binary image must be manually signed before
flashing. This situation arises when CONFIG_SECURE_SIGNED_APPS is
enabled, but CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is not set. As a
result, the binary image is not signed during the build process and
requires manual signing.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Given the binary target created by the idf_build_binary or
idf_sign_binary function, add a new dependency that verifies whether the
binary image fits within the smallest application partition.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Create a new flash target for a previously created binary target using
the idf_build_binary or idf_sign_binary function. Specify the new target
name with the TARGET option. The binary image path is stored in the
BINARY_PATH property of the binary target and is set when the binary
target is created using the idf_build_binary or idf_sign_binary
function. Use the NAME option as a prefix for the generated esptool
argument file, and the FLASH option can be used to include the binary
image flashing in the global flash target.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Create a signed binary image from a previously generated binary using
the `idf_build_binary` function. This image can be signed with an
optional key from a KEYFILE or, by default, with the key specified in
the sdkconfig. A new custom command is added to generate the signed
binary, which is stored at the location specified by the OUTPUT_FILE
option and a new custom target is created for it, with the name provided
in the TARGET option. The BINARY_PATH property is added to this new
TARGET, containing the path to the signed binary image.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The `idf_build_binary` function generates a binary image for a specified
executable target, which may or may not have been created using the
`idf_build_executable` function. It adds a custom command to generate
the binary image file at the location specified by the `OUTPUT_FILE`
option and creates a new target for it, with the name specified by the
`TARGET` option. The path of the generated binary file is also stored in
the `BINARY_PATH` property of the newly created binary target.
Additionally, this binary path is stored in the `EXECUTABLE_BINARY`
property of the given executable. This information is used by the
`idf_build_generate_metadata` function, which takes the executable
target as an argument and includes the binary name in the
`project_description.json`.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The global flash targets are created using
__create_project_flash_targets, but these are merely placeholders that
allow components to declare their dependencies on the global flash or
encrypted-flash target in their project_include.cmake. The actual logic
for flash targets is located in the project_include.cmake of the
esptool_py component. Therefore, the targets must be initialized
after this file has been included. To address this, a new function,
__init_project_flash_targets, has been added for this purpose.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Create a phony target that intentionally fails the build, displaying the
error messages specified in the message arguments. An empty CMake file is
created and included, which is then deleted when the target is executed.
This forces CMake to rerun, as the file is added to the CMake rerun
dependencies.
This has been carried over from cmakev1 as it is used by several
components.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Some components rely on the existence of flash targets to declare
dependencies. Add flash and encrypted-flash targets during project
initialization to ensure they are available before including
project_include.cmake files.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The optional dependency is currently added if the optional component
interface target exists, which is always the case unless a non-existent
component is requested. Instead, base the optional dependency on the
component interface target alias, as it is created only when the
component is included in the project.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
If the IDF_INCLUDE_ALL_COMPONENTS variable is set, all discovered
components will be included. By default, components are included based
on their requirements. When IDF_INCLUDE_ALL_COMPONENTS is enabled, the
all_component_info dictionary in the project_description.json file will
be fully populated.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The `idf_build_generate_metadata()` function is used to generate project
metadata, specifically the `project_description.json` file, for a given
executable target. The output file path can be specified as an argument
to the function, allowing metadata generation for multiple executables.
It identifies the library, created by the `idf_build_library` function,
that is linked to the executable based on the `LINK_LIBRARIES`
executable target property. The `LIBRARY_INTERFACES` build property
tracks all library interfaces created with the `idf_build_library`
function, so the targets in the `LINK_LIBRARIES` executable property are
checked against this list to find the library. The library contains
information about components linked to it in the
`LIBRARY_COMPONENTS_LINKED` library property. These components are
processed and added to the `build_component_info` dictionary in the
`project_description.json` along with other information.
Note that, compared to cmakev1, the `all_component_info` dictionary in
`project_description` does not include some information by default, such
as included directories. This information is available in cmakev1 due to
early component evaluation, which is not done in cmakev2. This will
likely require some adjustments on the hints side.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The cmakev1 sets __PREFIX as a component property. To maintain backward
compatibility, set it in cmakev2 as well.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Search for the library interface target created with the
idf_build_library() function and linked to the executable, examine the
LINK_LIBRARIES for the executable and the LIBRARY_INTERFACES build
property, which stores all library interface targets created by the
idf_build_library() function.
This helper is intended for use by functions, such as the
idf_build_generate_metadata() function, which accepts the executable
target as an argument to find the library linked to it.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The idf_project_default macro is intended to be used by default for
ESP-IDF projects. Currently, it handles the necessary project
initialization that must occur after CMake's project() is called. It
creates the default executable based on the project name and links a
library to it, based on the main component and its transitive
dependencies. This macro will be further extended to also generate
binary image, project metadata, and add other expected targets. It
primarily serves as a replacement for the project() macro used in
cmakev1.
Expected typical usage:
```
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmakev2/idf.cmake)
project(hello_world LANGUAGES C CXX ASM)
idf_project_default()
```
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Create an empty source file for the add_executable target, along with a
library containing specified components, and then create an executable.
This approach allows for the easy creation of multiple executables by
specifying the component with the app_main function, as demonstrated in
the test.
```
idf_build_executable(fatfs_example COMPONENTS fatfs_example)
idf_build_executable(hello_world_example COMPONENTS hello_world_example)
```
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The option is unnecessary and complicates the interface. Additionally,
it does not adhere to the previously established naming convention. The
target name for the library interface is provided as a standard function
argument.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add two components: fatfs_example and hello_world_example. These are
simply copies of the main components from the existing examples.
Enhance the test_executable test to create targets for two
executables, which can be built after CMake configuration.
```
cmake --build build/ --target hello_world_example
cmake --build build/ --target fatfs_example
```
Additionally, move the test_component_priority to the end of the test
chain, as it modifies the esp_system component, which interferes with
the linkage of the executables.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Integrate the ldgen into cmakev2. With this change, it becomes possible
to actually link the project executables.
In cmakev2, the handling of linker scripts is deferred to
idf_build_library, unlike in cmakev1, where linker scripts were added
and generated during the target_linker_script call. In cmakev2, the
target_linker_script only adds the linker scripts and templates, along
with the output filenames for the linker scripts generated from the
templates, to the component property. When idf_build_library is called
and all the requested components are included, it uses the
__get_target_dependencies function to obtain all transitively linked
targets to the library interface target. These targets are mapped to the
components, and the LIBRARY_COMPONENTS_LINKED library property is set.
It contains all components linked to the library interface target. The
components from LIBRARY_COMPONENTS_LINKED are used to collect linker
fragments and linker scripts utilized in the library. Additionally, all
targets transitively linked to the library are used to identify archive
files used in the library. This includes component archives and archives
added with the add_prebuilt_library function. The archives and
ldfragments related to the components linked to the library are used
when ldgen generates the linker scripts from templates.
The linker scripts, both static and generated by ldgen, are added to the
library interface link options and INTERFACE_LINK_DEPENDS property. For
generated linker scripts, a custom target is created and added as a
dependency for the library interface to ensure they are generated before
the link.
The difference compared to cmakev1 is that the generated linker scripts,
currently only sections.ld, are not global in the project but are
generated per library. This means there might be multiple versions of
sections.ld depending on the components included in the library. For
example, a component like esp_system may be linked to multiple library
interface targets, each with a different set of components. This results
in different sets of fragment files and library archives and different
versions of the sections.ld linker script. This should ensure proper
dependencies between targets. In other words, if a component changes its
linker fragment, only executables linked to libraries using this
component should be re-linked. As a consequence of this approach, the
generated linker scripts for different libraries need to have different
names or be stored in different directories to avoid overwriting the
linker script for one library with the linker script for another library
using the same component. This is handled with a suffix, which is based
on the library interface target name and appended to the generated
linker script. So, for example, there is no sections.ld, but instead
sections.ld_fatfs_lib or sections.ld_hello_world_lib. As a next step, we
can add a DEFAULT option to idf_build_library and avoid adding the
suffix for the default library.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
There may be multiple libraries, each linking a different set of
components. Introduce a new library property, LIBRARY_COMPONENTS_LINKED,
to track the components linked with a specific library. This property
can be used, for example, by menuconfig to distinguish between included
and excluded components on a per-library or per-executable basis, or by
ldgen to identify linker scripts for the linked components.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Based on the INTERFACE_LINK_LIBRARIES and LINK_LIBRARIES properties,
recursively retrieve the list of dependencies for the specified target.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Currently, the common components are initialized in the idf_project_init
macro, which means they are included even for cmakev2 components.
However, cmakev2 components are expected to explicitly specify all their
dependencies instead of relying on common components being automatically
linked. Therefore, common components are only relevant within the
context of cmakev1 components. To address this, move the
__init_common_components function call to idf_component_register and
include common components only when they are truly needed for a cmakev1
component.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add a simple test_executable that links to all discovered components.
This is intended to verify if the component sources can be compiled
using the command `cmake --build build/ --target test_executable`. The
ldgen is not yet integrated, so the test_executable is not actually
created or linked. However, this process can be used to check if the
components are compiled.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Set the ESP_PLATFORM macro to indicate to component sources that they
are being compiled with ESP-IDF.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Currently, the generic compile_options are ignored because they are
unset after retrieving the build property. To fix this, avoid explicitly
setting compile_options, as this variable is initialized with the
idf_build_get_property(compile_options ...) call.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Automatically link commonly required components to the component target
created in the idf_component_register function. This is still necessary
even in cmakev2, as existing components depend on this behavior.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Identify the commonly required components based on the target and
architecture, and store them in the __COMPONENT_REQUIRES_COMMON build
property. These components are automatically included, and their
interfaces are stored in the __COMMON_COMPONENT_INTERFACES build
property. The commonly required component interfaces are automatically
linked to each component.
Existing components for cmakev1 rely on the automatic linking of common
components. Therefore, at least initially, we need to implement the same
functionality in cmakev2.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>