From f7002bec508b1136877823727d4a2a4a1d4f1202 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 26 May 2025 23:34:16 +0200 Subject: [PATCH 1/2] enhance esp-idf-size use --- builder/main.py | 91 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 14 deletions(-) diff --git a/builder/main.py b/builder/main.py index 6c6dca5f2..8a21d8334 100644 --- a/builder/main.py +++ b/builder/main.py @@ -360,28 +360,66 @@ def check_lib_archive_exists(): def firmware_metrics(target, source, env): + """ + Custom target to run esp-idf-size with support for command line parameters + Usage: pio run -t metrics -- [esp-idf-size arguments] + """ if terminal_cp != "utf-8": print("Firmware metrics can not be shown. Set the terminal codepage to \"utf-8\"") return + map_file = os.path.join(env.subst("$BUILD_DIR"), env.subst("$PROGNAME") + ".map") if not os.path.isfile(map_file): # map file can be in project dir map_file = os.path.join(get_project_dir(), env.subst("$PROGNAME") + ".map") - if os.path.isfile(map_file): - try: - import subprocess - python_exe = env.subst("$PYTHONEXE") - run_env = os.environ.copy() - run_env["PYTHONIOENCODING"] = "utf-8" - run_env["PYTHONUTF8"] = "1" - # Show output of esp_idf_size, but suppresses the command echo - subprocess.run([ - python_exe, "-m", "esp_idf_size", "--ng", map_file - ], env=run_env, check=False) - except Exception: - print("Warning: Failed to run firmware metrics. Is esp-idf-size installed?") - pass + if not os.path.isfile(map_file): + print(f"Error: Map file not found: {map_file}") + print("Make sure the project is built first with 'pio run'") + return + + try: + import subprocess + import sys + import shlex + + cmd = [env.subst("$PYTHONEXE"), "-m", "esp_idf_size", "--ng"] + + # Parameters from platformio.ini + extra_args = env.GetProjectOption("custom_esp_idf_size_args", "") + if extra_args: + cmd.extend(shlex.split(extra_args)) + + # Command Line Parameter, after -- + cli_args = [] + if "--" in sys.argv: + dash_index = sys.argv.index("--") + if dash_index + 1 < len(sys.argv): + cli_args = sys.argv[dash_index + 1:] + cmd.extend(cli_args) + + # Map-file as last argument + cmd.append(map_file) + + # Debug-Info if wanted + if env.GetProjectOption("custom_esp_idf_size_verbose", False): + print(f"Running command: {' '.join(cmd)}") + + # Call esp-idf-size + result = subprocess.run(cmd, check=False, capture_output=False) + + if result.returncode != 0: + print(f"Warning: esp-idf-size exited with code {result.returncode}") + + except ImportError: + print("Error: esp-idf-size module not found.") + print("Install with: pip install esp-idf-size") + except FileNotFoundError: + print("Error: Python executable not found.") + print("Check your Python installation.") + except Exception as e: + print(f"Error: Failed to run firmware metrics: {e}") + print("Make sure esp-idf-size is installed: pip install esp-idf-size") # # Target: Build executable and linkable firmware or FS image @@ -618,6 +656,31 @@ def firmware_metrics(target, source, env): "Erase Flash", ) +# +# Register Custom Target +# +env.AddCustomTarget( + name="metrics", + dependencies="$BUILD_DIR/${PROGNAME}.elf", + actions=firmware_metrics, + title="Firmware Size Metrics", + description="Analyze firmware size using esp-idf-size (supports CLI args after --)", + always_build=True +) + +# +# Additional Target without Build-Dependency when already compiled +# +env.AddCustomTarget( + name="metrics-only", + dependencies=None, + actions=firmware_metrics, + title="Firmware Size Metrics (No Build)", + description="Analyze firmware size without building first", + always_build=True +) + + # # Override memory inspection behavior # From 2d9ff886762f1c1850c38eb4ca5e686f433aee8d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 26 May 2025 23:54:51 +0200 Subject: [PATCH 2/2] Build the map file always for espidf too --- builder/frameworks/espidf.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index e464e64f5..3ed93fe03 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -1799,13 +1799,10 @@ def get_python_exe(): "-DSDKCONFIG=" + SDKCONFIG_PATH, ] -if "CPPDEFINES" in env: - flatten_cppdefines = env.Flatten(env['CPPDEFINES']) - if "SHOW_METRICS" in flatten_cppdefines: - # This will add the linker flag for the map file - extra_cmake_args.append( - f'-DCMAKE_EXE_LINKER_FLAGS=-Wl,-Map={os.path.join(BUILD_DIR, env.subst("$PROGNAME") + ".map")}' - ) +# This will add the linker flag for the map file +extra_cmake_args.append( + f'-DCMAKE_EXE_LINKER_FLAGS=-Wl,-Map={os.path.join(BUILD_DIR, env.subst("$PROGNAME") + ".map")}' +) # Add any extra args from board config extra_cmake_args += click.parser.split_arg_string(board.get("build.cmake_extra_args", ""))