Commit Graph

79 Commits

Author SHA1 Message Date
Marek Fiala 1e351a8b67 test(tools): Moved preset parsing into core_ext.py and added tests 2025-10-29 11:47:40 +08:00
Ivan Grokhotkov 78ae7ab085 feat(build): add idf.py support for CMake configuration presets
This commit adds a new idf.py --preset NAME argument, which allows
selecting the CMake configuration preset with a given name.
For idf.py, selecting the preset does two things:
- sets the build directory, which is specified in the preset itself
  using "binaryDir" field
- passes --preset argument to CMake configuration phase

The multi_config example is updated to illustrate how this feature is
expected to be used.
2025-10-29 11:47:40 +08:00
Jaroslav Burian 64379596dd change(tools): Use esptool to detect available ports
This changes how available ports are detected. It removes code duplication
for MacOS filtering which already is in esptool and prepares for port
prioritization to be used from esptool.
2025-10-06 09:50:18 +02:00
Jan Beran b51329bdb1 fix: set sufficient buffer limit for idf.py confserver 2025-10-02 13:19:30 +02:00
Kapil Gupta 8b68791996 fix(tool): increase buffer size for kconfig server 2025-09-27 17:55:28 +05:30
Roland Dobai 36fb960e5f change(tools): Fix pre-commit checks for tools.py 2025-09-24 13:43:23 +02:00
Marek Fiala 96ff174dac feat(tools): idf.py extension - added interface version 2025-09-23 15:26:33 +08:00
Marek Fiala 4f8fb84caa feat(tools): Added check for duplicit action names/aliases from external extensions 2025-09-23 15:26:33 +08:00
Marek Fiala 2ec170b2fb change(tools): idf.py & tools.py ruff formatting 2025-09-23 15:26:33 +08:00
Roland Dobai 16ba8b7e4a Merge branch 'feature/add_utf_8_decoding' into 'master'
feat(tools): Enforced utf-8 encoding with Python open() functions

Closes IDF-10654

See merge request espressif/esp-idf!32303
2024-12-30 16:07:29 +08:00
Frantisek Hrbata 642855c952 feat(tools): add command arguments in the logs produced by RunTool
Currrently, all logs generated by RunTool are stored in files named
idf_py_(stdout|stderr)_output_$$, making it difficult to identify which
log corresponds to which command. To simplify this for idf-diag, include
the command arguments at the beginning of the log. This will allow
idf-diag to use regex to differentiate logs for build, monitor, flash,
and other commands and targets.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-12-27 12:02:23 +01:00
Marek Fiala 2c814ef2fa feat(tools): Enforce utf-8 encoding with open() function 2024-12-27 17:12:21 +08:00
Radim Karniš ed9b2d1fd6 change(port_detection): Filter out BT and WLAN debug serial ports on MacOS
Closes https://github.com/espressif/esp-idf/issues/14058
2024-07-04 20:40:10 +08:00
Jakub Kocka 23ba79d5c7 fix(tools): Avoid crashing when Git is used to acquire IDF version
Closes https://github.com/espressif/esp-idf/issues/13345
2024-06-11 08:13:25 +02:00
Frantisek Hrbata 75c765ff42 fix: exit gracefully when process started via asyncio is terminated
Currently when process is started through asyncio Runner and it is termited
e.g. with SIGINT(ctrl+c) a traceback is printed instead of gracefully
exit.

Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x7fe980970900>
Traceback (most recent call last):
  File "/usr/lib64/python3.12/asyncio/base_subprocess.py", line 129, in __del__
    self.close()
  File "/usr/lib64/python3.12/asyncio/base_subprocess.py", line 107, in close
    proto.pipe.close()
  File "/usr/lib64/python3.12/asyncio/unix_events.py", line 568, in close
    self._close(None)
  File "/usr/lib64/python3.12/asyncio/unix_events.py", line 592, in _close
    self._loop.call_soon(self._call_connection_lost, exc)
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 793, in call_soon
    self._check_closed()
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 540, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

This is caused because asyncio Runner context in asyncio.run is closing the event
loop and if exception is unhandled in coroutine(run_command) the transport is not
closed before the even loop is closed and we get RuntimeError: Event loop is closed
in the transport __del__ function because it's trying to use the closed
even loop.

Let's catch asyncio.CancelledError in case the process we are trying to
read from is terminated, print message, let the asyncio finish and exit
gracefully.

Closes https://github.com/espressif/esp-idf/issues/13418

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-04-04 09:58:01 +02:00
Frantisek Hrbata cf161304bb fix: save RunTool command output with correct line endings
Currently RunTool reads command's output with asyncio read, which
returns bytes. This is decoded into python's string and the output already
contains OS specific line endings, which on Windows is CRLF. Problem is
that the command output is saved by using python's text stream/file,
which replaces LF, native python's line ending, with OS specific line ending.
On Windows, and in this particular case, the CRLF from the command output is
translated into CRCRLF and saved in the commands output file. When this
file is read in again, e.g. for hint modules, the CRCRLF is replaced
with LFLF. Again the file is open as text file. Meaning a new emply line
is added.

Fix this by opening the output file with "newline=''", which prevents
this translation. We already have the OS specific line ending in the
command's output.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-01-23 10:03:40 +01:00
dyarkovoy 1cc04d062c fix(tools): Fixed Python path case sensitive error on Windows
Closes https://github.com/espressif/esp-idf/issues/12779
Closes https://github.com/espressif/esp-idf/pull/12780
2023-12-15 08:01:29 +00:00
Ivan Grokhotkov 54d4662107 feat(tools): idf_monitor: support for loadable hint provider modules
Currently hints are supported based on hints.yml only, which may be
limiting for some use cases. This introduces a generic plugin approach,
which allows to implement hint module that doesn't require entry in hints.yml.
Such module has the full command output available and it is not limited to
a single regex in hints.yml.

Note that regex in hint.yml expects the output concatenated into a single line,
but hint modules are getting the output unchanged.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-08-05 20:13:28 +02:00
Frantisek Hrbata ed35c3a94a feat(tools): add global build context
Introduces get_build_context() helper, which allows to get build context, e.g.
project description, at places where this info is not available. The
build context is set within ensure_build_directory.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-08-05 20:13:28 +02:00
Peter Dragun 341390f928 fix(tools/hints): add guide to fix error with unsupported asyncio
Closes https://github.com/espressif/esp-idf/issues/11732
2023-07-03 10:26:26 +02:00
Alexey Lapshin 07c7fe929b tools: process progression for flash action output 2023-06-12 13:56:59 +04:00
Alexey Lapshin 59206e39a0 tools: fix control characters print if hints enabled
Closes https://github.com/espressif/esp-idf/issues/11351
2023-05-22 20:18:02 +08:00
Frantisek Hrbata a5d3c2d443 tools: fix hints processing in interactive mode
Currently hints are processed only once the process is finished and
exits with non-error exit code. In interactive mode, e.g. for monitor,
we want to process ouput lines for hints right away.

This adds a simple buffer, which keeps the last line and once EOL is
reached, it is processed for hints.

Since the original hints processing was file based, a new helper
function was added to allow processing hints in string.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-05-09 14:35:04 +02:00
Peter Dragun bebd2cec4a bug(idf_monitor): fix color on windows with hints
Closes https://github.com/espressif/esp-idf/issues/9610
2023-04-17 11:18:42 +02:00
Roland Dobai 05a8d0b58a Merge branch 'bugfix/asyncio_progress_term_width' into 'master'
tools: fix progress output in asyncio.run with zero terminal width

Closes IDF-6646

See merge request espressif/esp-idf!22986
2023-04-06 15:23:39 +08:00
Frantisek Hrbata 84deb34035 tools: fix progress output in asyncio.run with zero terminal width
Currently the forced progress in RunTool is trying to fit the output
line into a terminal width, but it doesn't take into an account a
situation when the terminal width is reported as zero. This manifests
when running in docker image with redirected output and can be seen
in the github workflow output for esp-idf-ci-action.

docker run --rm -t my_ubuntu_esp python3 -c 'import os,sys; print(os.get_terminal_size(), sys.stdout.isatty())'
os.terminal_size(columns=238, lines=59) True

vs

docker run --rm -t my_ubuntu_esp python3 -c 'import os,sys; print(os.get_terminal_size(), sys.stdout.isatty())' | tee
os.terminal_size(columns=0, lines=0) True

Since the output is reported as tty and the terminal width as 0, the
fit_text_in_terminal() function returns empty string. I also verified this
by running idf.py build inside a testing docker image.

This fix adjusts the fit_text_in_terminal() function to return original
line if the terminal width is zero.

Also simplify the progress print and use same approach as ninja
https://github.com/ninja-build/ninja/blob/master/src/line_printer.cc#L66

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-29 17:12:36 +02:00
Frantisek Hrbata 9b731e5e35 tools: fix set-target if IDF_TARGET env is set and stale sdkconfig exists
Currently if the IDF_TARGET env is set, and old sdkconfig exists with
different target value in CONFIG_IDF_TARGET, the set-target action fails
complaining about the IDF_TARGET env and value in sdkconfig being different.
We should ignore IDF_TARGET value from sdkconfig, because we are
actually setting new target and the old sdkconfig is renamed in cmake.

This can be easily reproduced with

---8<---
$ IDF_TARGET=esp32 idf.py set-target esp32
$ IDF_TARGET=esp32s3 idf.py set-target esp32s3

Project sdkconfig '/home/fhrbata/work/hello_world/sdkconfig' was generated
for target 'esp32s3', but environment variable IDF_TARGET is set to 'esp32'.
Run 'idf.py set-target esp32' to generate new sdkconfig file for target esp32.
---8<---

This also adds test for this use case to test_non_default_target.py.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-28 11:18:04 +02:00
Frantisek Hrbata a558ad506e tools: fix custom sdkconfig renaming in set-target
Currently the set-target has sdkconfig file name hardcoded to the
default one and doesn't honor custom config paths or names.
IMHO the only place where we can really now the config file name
is in cmake. But also the config should be really renamed only if
the set-target action is running.

This moves the config file renaming into cmake and it's performed only
when _IDF_PY_SET_TARGET_ACTION env. var. is set to 'ON'. This should
hopefully guarantee that it's really renamed only while set-target is
running.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-08 16:45:55 +01:00
Frantisek Hrbata 8e912faad1 tools: add target consistency checks for target specified with -D option
Extend existing target consistency checks for the two following cases.
1. Target does not match currently used toolchain
   $ IDF_TARGET=esp32s2 idf.py reconfigure
   $ idf.py -DIDF_TARGET=esp32c3 build

2. Target is ambiguous, because it's specified also as env. var.
   IDF_TARGET=esp32s3 idf.py set-target esp32c2

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-08 16:43:42 +01:00
Frantisek Hrbata 0d859f2786 tools: move target guessing into cmake
The _guess_or_check_idf_target() function has sdkconfig and sdkconfig.defaults
file names hardcoded. Since config file names may be specified with SDKCONFIG
or SDKCONFIG_DEFAULTS cmake vars, directly in CMakeLists.txt or passed in with
the -D cmake option, they are not respected.

Problem is when SDKCONFIG or SDKCONFIG_DEFAULTS is set in
CMakeLists.txt. While idf can detect cmake vars passed through it
to cmake via the -D option, detecting SDKCONFIG and SDKCONFIG_DEFAULTS
vars settings in CMakeLists.txt would require to parse it. This seems
like error prone approach. Also if the vars defined by the -D option
are passed directly to cmake, not via idf, they will not be visible to idf.

It seems reasonable to move the logic into cmake, where we know the correct
SDKCONFIG and SDKCONFIG_DEFAULTS values. So the IDF_TARGET detection/guessing
is moved into targets.cmake, where the IDF_TARGET is actually set. The target
is guessed based on the following precendence.

1) $ENV{IDF_TARGET}
2) IDF_TARGET
3) SDKCONFIG
4) sdkconfig
5) SDKCONFIG_DEFAULTS if non-empty or
   $ENV{SDKCONFIG_DEFAULTS} if non-empty or
   sdkconfig.defaults
6) esp32

All config files referred in $ENV{SDKCONFIG_DEFAULTS} and SDKCONFIG_DEFAULTS
are searched, compared to the current behaviour. First target found in the
above chain is used.

The original _guess_or_check_idf_target() is renamed to _check_idf_target() and
used for the target consistency checks only.

The get_sdkconfig_filename() helper is now used to get the sdkconfig file
for consistency checks. It looks in SDKCONFIG specified with the -D
option and project_description.json.

With this change config full paths are reported in messages, so it's clear
e.g. from which config the target was guessed from or which config has
consistency problem. test_non_default_target.py was adjusted to this
change and also new test for testing the IDF_TARGET guessing was added.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-08 16:37:58 +01:00
Frantisek Hrbata a8a4d7c66d tools: add get_sdkconfig_filename() helper
Get project's current sdkconfig file name. It looks in SDKCONFIG cmake var
defined by the -D option and project_description.json. If not found return
default sdkconfig.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-08 16:37:58 +01:00
Frantisek Hrbata e89f980193 tools: add _parse_cmdl_cmakecache() helper
This parses cmakes cache vars defined on command line with -D options
into dictionary. It allows to simplify the check for new cache entries
and also can be re-used for other checks.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-03-08 16:37:58 +01:00
Djordje Nedic 17d1e9ae36 bugfix: Fix windows path case sensitivity
This commit fixes an issue where paths on Windows are case insensitive, for instance when setting the build folder its name would be converted to lowercase.

The culprit is our realpath() function, that was calling os.path.normcase() internally, since we are removing that call it makes sense to just remove the function entirely and call os.path.realpath() wherever necessary.

Closes https://github.com/espressif/esp-idf/issues/10282
2023-01-17 20:51:46 +01:00
Aleksei Apaseev 06ac2166d6 tools: added idf.py coredump sub-command 2022-10-28 03:01:56 +00:00
Roland Dobai 2083e4d359 Tools: Detect if the project is configured for a different Python
Closes https://github.com/espressif/esp-idf/issues/9993
2022-10-18 15:56:43 +02:00
Alexey Lapshin c17a7f446c tools: move cmake executable check into function uses it
Before this change idf.py could exit with reason cmake does not exist in PATH
even cmake will not be executed by idf.py (e.g., 'idf.py gdb').
2022-09-21 22:39:03 +04:00
Roland Dobai 9307a932ad Tools: Handle IO error in idf.py output capturing
Closes https://github.com/espressif/esp-idf/issues/9649
2022-09-02 10:49:29 +02:00
simon.chupin 92ef2a4c83 Tools: Add unit tests for idf.py hints 2022-09-01 17:09:46 +02:00
Ivan Grokhotkov 13881a3832 idf.py: ensure that build log is always sanitized from color sequences
The actual output from the build tool (CMake/Ninja) may or may not
contain color escape codes, depending on various factors. The output
written to the log file should never include color escape codes,
though. This is because color escape codes in files are usually not
rendered as "color" in editors, and complicate reading. Also escape
codes would break the regular expressions used to display hints for
compilation errors.
2022-08-30 16:38:14 +02:00
Ivan Grokhotkov d04b554065 tools: idf.py: enable CLICOLOR_FORCE for interactive builds
If stdout is a TTY (meaning that the output is not redirected), tell
the build tool (GNU Make or Ninja) to enable colorized output.

GNU Make and Ninja also check if their stdout is redirected and
strip color escape sequences in that case. CLICOLOR_FORCE environment
variable overrides this behavior.

With this change, if the compiler was launched with the
-fcolor-diagnostics flag and idf.py output is not redirected, the
final output in the terminal will be colorized.

(-fcolor-diagnostics is handled at CMake level by the previous commit)
2022-08-30 16:38:13 +02:00
Roland Dobai cb81d14892 Merge branch 'bugfix/build_color_output_windows' into 'master'
tools: idf.py: use actual sys.stdout instead of the memoized one

See merge request espressif/esp-idf!19847
2022-08-30 16:31:42 +08:00
Ivan Grokhotkov b548d9345e Revert "Merge branch 'feature/build_color_output' into 'master'"
This reverts merge request !19330
2022-08-30 15:14:47 +08:00
Ivan Grokhotkov 2c5b62f10e tools: idf.py: use actual sys.stdout instead of the memoized one
This fixes the issue with build output not being colorized on Windows,
while the hints messages are colorized.

The issue occurred because sys.stdout and sys.stderr get overridden
by colorama.init() at runtime, but the default argument
output_stream=sys.stdout holds the reference to the"original"
sys.stdout.

colorama.init() (which, by the way, gets called via a curious chain
of imports, via idf_component_tools.manifest and tqdm package)
overrides standard streams, on Windows only. The overridden streams
contain logic to convert ANSI color codes into Windows Console API
calls to colorize the text.

Since read_and_write_stream function used the default value of
output_stream evaluated at module loading time, it was using the
original sys.stdout, not the one overridden by colorama.

One extra note is that while this does fix the coloring issue, the
solution is a bit fragile, as it relies on one of the following
(on Windows):
- colorama.init() is called (this can change if idf-component-manager
  stops importing tqdm)
- Sufficiently new version of Windows 10 is used, and ANSI color codes
  support is enabled in the Registry.
2022-08-30 01:30:32 +02:00
Ivan Grokhotkov 712743d777 idf.py: ensure that build log is always sanitized from color sequences
The actual output from the build tool (CMake/Ninja) may or may not
contain color escape codes, depending on various factors. The output
written to the log file should never include color escape codes,
though. This is because color escape codes in files are usually not
rendered as "color" in editors, and complicate reading. Also escape
codes would break the regular expressions used to display hints for
compilation errors.
2022-08-29 11:15:16 +02:00
Ivan Grokhotkov 12abe1f316 tools: idf.py: enable CLICOLOR_FORCE for interactive builds
If stdout is a TTY (meaning that the output is not redirected), tell
the build tool (GNU Make or Ninja) to enable colorized output.

GNU Make and Ninja also check if their stdout is redirected and
strip color escape sequences in that case. CLICOLOR_FORCE environment
variable overrides this behavior.

With this change, if the compiler was launched with the
-fcolor-diagnostics flag and idf.py output is not redirected, the
final output in the terminal will be colorized.

(-fcolor-diagnostics is handled at CMake level by the previous commit)
2022-08-29 11:15:00 +02:00
Roland Dobai 94a2d9f16a Merge branch 'bugfix/fix_hints_templates' into 'master'
tools: fix hints templates

See merge request espressif/esp-idf!19789
2022-08-29 16:43:14 +08:00
simon.chupin e635492c95 tools: fix hints templates 2022-08-25 18:00:23 +02:00
simon.chupin 1cb4f8fdf4 tools: fix multi-byte character appearance in idf.py monitor 2022-08-23 13:25:38 +00:00
simon.chupin cc1eb81b2e tools: add support of templates for hints 2022-08-18 13:37:32 +02:00
Roland Dobai 152ce8884b Tools: Fix idf.py hints to be enabled all the time and being able to disable them 2022-08-15 13:01:39 +02:00