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>
Since the idf_project_default is already available, let's use it in the
buildv2 testing application. Also change the test app name from
buildv2_test_app to build_test_app, as some tests require the ELF and
bin images to be created under this name.
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>
Based on the configuration, set the IDF_TARGET build property. This is
also set by cmakev1 and can be used to easily determine the architecture
for the project.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add embedded source files to the component target sources. This is
intentionally managed in idf_component_include instead of
idf_component_register, allowing even cmakev2 components to set the
component's EMBED_FILES and EMBED_TXTFILES properties. Although it might
be more convenient to call the target_add_binary_data helper function
directly in cmakev2.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add a backward-compatible idf_component_register function. This is
necessary to enable existing components to integrate with cmakev2. Note
that, by design, when the configuration is evaluated first, the KCONFIG
and KCONFIG_PROJBUILD options become obsolete, and an error is reported
if non-default configuration file names are specified.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add a component interface alias only after the actual target is created,
meaning the component is included. The alias has a well-defined name and
can be used in generator expressions like
`$<$<TARGET_EXISTS:idf::esp_netif>:>` without needing to retrieve the
COMPONENT_ALIAS property.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add binary data into the build target by converting it into a generated
source file, which is then compiled into a binary object as part of the
build process.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The add_deprecated_target_alias function is used by some existing
components, so it should be added to cmakev2 as well.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The file_generate function is used by some existing components, so it
should be added to cmakev2 as well.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The fail_target function is used by some existing components, so it
should be added to cmakev2 as well.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>