There is currently a bug in the __build_resolve_and_add_req function in
tools/cmake/build.cmake where the check for registered component
requirements is incorrectly applied to the component itself rather than
its dependencies. This issue likely originated from a typo, using
component_target instead of _component_target. To prevent further
confusion, _component_target has been renamed to _req_target.
Fixing this revealed multiple incorrect dependencies for the Linux
target, which have now been resolved by explicitly specifying the
dependencies for the Linux target.
Closes https://github.com/espressif/esp-idf/issues/13447
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
* reverted old faulty mechanism to set different
standard according to the toolchain
* Using -std=gnu++2b now for both gcc and clang
* Added a build test app to check the C++ standard in IDF
* Updated english docs to reflect the change to C++23
Extend target checks in cmake, in case it's run directly and not via
idf.py or if idf.py misses something. This may happen
for example if cmake variables are set in project's CMakeLists.txt.
Some clean-ups are included along with the new checks and tests.
1. __target_check() function is removed. IIUC it should never fail,
because the selected target is explicitly passed as environmental
variable to kconfgen. Meaning the IDF_TARGET from environment variable may
not be actually used in kconfgen if IDF_TARGET is already set it cmake cache.
Note that the IDF_TARGET environment variable used for kconfgen is not
based on the actual IDF_TARGET environment variable set for idf.py, but
rather on the value set in __target_init() with
set(IDF_TARGET ${env_idf_target} CACHE STRING "IDF Build Target")
My understanding is that the original check was introduced to handle
situation, where IDF_TARGET was already set in cmake's cache and
the IDF_TARGET from environment variable was different. Since
the kconfgen would use the original environment variable(not
explicitly passed as it is now) the IDF_TARGET in cmake and in
sdkconfig could differ. IOW I think the original check was introduced
to cope with the following cmake behaviour
set(VARIABLE "value1" CACHE STRING "test variable")
set(VARIABLE "value2" CACHE STRING "test variable")
message("Variable value: ${VARIABLE}")
output: Variable value: value1
2. I scratched by head how it is possible that the following code
in __target_check()
if(NOT ${IDF_TARGET} STREQUAL ${env_idf_target})
could fail if IDF_TARGET is not set. For example in clean project
IDF_TARGET=esp32 idf.py reconfigure
Here env_idf_target==esp32 and IDF_TARGET is not set, so I would
expect that cmake will fail with error message that the cache
and env target do not match. The thing is that the variable
evaluation is done before the if command, so it actually
sees this
if(NOT STREQUAL esp32)
which is false and the error is not printed. It can be seen
with 'cmake --trace-expand' command. I don't know if this
was used on purpose or it worked just as a coincidence, but
I find it very confusing, so I added explicit check if the
IDF_TARGET is defined before the actual check. Same for
CMAKE_TOOLCHAIN_FILE.
3. Error messages are not formated(line-wrapped) by cmake's markup
so it's easier to check the output in tests.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Unlike COMPILE_OPTIONS, COMPILE_DEFINITIONS CMake property assumes
values without the -D prefix, such as NAME or NAME=VAL.
Previously, IDF build system was passing COMPILE_DEFINITIONS build
property to CMake COMPILE_OPTIONS property, so -D prefix was not
a problem.
Now that COMPILE_DEFINITIONS CMake property is used, -D prefix has
to be removed.
(Note that this doesn't affect 'target_compile_definitions' function,
which strips -D prefix before adding the definition to the property.)
Now that the supported CMake version is >=3.16, this code can be
simplified.
The code to deduplicate the directories can be removed since this is
handled by target_link_directories.
'linux' component provides some of the common header files, such as
'sys/queue.h' and 'sys/lock.h'. For chip targets, it is possible to
include these files without having to add any extra requirements.
With this change, the same behavior will apply for the linux target.
`__COMPONENT_TARGETS` is evaluated very early when components and
component directories are added to the build, which means that all
components (including the ones which are in EXCLUDE_COMPONENTS) have
a build system target defined. The component manager was given the
list of all known components (derived from the list of targets), not
the list of components after EXCLUDE_COMPONENTS were processed.
Because of that, EXCLUDE_COMPONENTS didn't effectively exclude the
component from the consideration of the component manager.
After refactoring the target components (e.g. esp32) no longer contained any real functionality.
What remained in these components have been moved elsewhere and the component itself deleted from the
build system.
lwip was added to common requirements list to provide "sys/socket.h"
header to all components without additional requirements specified.
However, lwip pulls in a lot of dependencies on other components.
This commit removes lwip from common requirements to reduce the number
of components in G1-only apps.
To compensate for this removal, the following changes are made:
- newlib (which is a common requirement) has a public dependency on
lwip if lwip is present in the build. This ensures that sys/socket.h
is available as long as lwip component is included into the build.
- lwip is now a public requirement of esp-tls since esp_tls.h includes
sys/socket.h header.
- lwip is now a public requirement o esp_http_client because
sys/socket.h is included from esp_http_client.h
- lwip is now a private requirement of esp_wifi for "smartconfig_ack"
- lwip is now a private requirement of mqtt for socket functions
- lwip is now a public requirement of tcp_transport because
esp_transport_tcp.h includes sys/socket.h header.
- mbedtls checks if lwip component is present in the build. If yes,
net_sockets.c is added to the build, along with the dependency on
lwip. Previously lwip was a public requirement of mbedtls
unconditionally.
system/g1_components test app is updated to reflect the changes
Default public dependencies of a component before and after this
change, except common requirements:
- esp_timer (public dependency of freertos)
- bootloader_support (public dependency of esp_hw_support)
- vfs (public dependency of lwip)
- esp_wifi (public dependency of lwip)
- esp_event (public dependency of esp_wifi)
- esp_netif (public dependency of esp_event)
- esp_eth (public dependency of esp_netif)
- esp_phy (public dependency of esp_wifi)
After:
- esp_timer (public dependency of freertos)
- bootloader_support (public dependency of esp_hw_support)
Altogether, the following components have been always added as
public requirements to all other components, and are not added now
([breaking-change]):
- lwip
- vfs
- esp_wifi
- esp_event
- esp_netif
- esp_eth
- esp_phy
Application components now need to explicitly declare dependencies on
these components.
When building for "linux" (~POSIX) target on macOS, the system linker
is normally used. MacOS linker doesn't recognise --gc-sections, but
has a -dead_strip flag which is equivalent.
These optional feature produces a graphviz file showing component
dependencies. It is useful for debugging reasons why certain
components got added to the build.
CMake sorts result of file(GLOB) command since version 3.6.0:
https://gitlab.kitware.com/cmake/cmake/-/commit/edcccde7d
Since ESP-IDF sets cmake_minimum_required version to 3.5, and version
3.5.1 is used in CI, sort file lists obtained from file(GLOB)
manually.
This helps obtain reproducible order of libraries passed to the linker
and to ldgen.