@@ -360,28 +360,70 @@ def check_lib_archive_exists():
360360
361361
362362def firmware_metrics (target , source , env ):
363+ """
364+ Custom target to run esp-idf-size with support for command line parameters
365+ Usage: pio run -t metrics -- [esp-idf-size arguments]
366+ """
363367 if terminal_cp != "utf-8" :
364368 print ("Firmware metrics can not be shown. Set the terminal codepage to \" utf-8\" " )
365369 return
370+
366371 map_file = os .path .join (env .subst ("$BUILD_DIR" ), env .subst ("$PROGNAME" ) + ".map" )
367372 if not os .path .isfile (map_file ):
368373 # map file can be in project dir
369374 map_file = os .path .join (get_project_dir (), env .subst ("$PROGNAME" ) + ".map" )
370375
371- if os .path .isfile (map_file ):
372- try :
373- import subprocess
374- python_exe = env .subst ("$PYTHONEXE" )
375- run_env = os .environ .copy ()
376- run_env ["PYTHONIOENCODING" ] = "utf-8"
377- run_env ["PYTHONUTF8" ] = "1"
378- # Show output of esp_idf_size, but suppresses the command echo
379- subprocess .run ([
380- python_exe , "-m" , "esp_idf_size" , "--ng" , map_file
381- ], env = run_env , check = False )
382- except Exception :
383- print ("Warning: Failed to run firmware metrics. Is esp-idf-size installed?" )
384- pass
376+ if not os .path .isfile (map_file ):
377+ print (f"Error: Map file not found: { map_file } " )
378+ print ("Make sure the project is built first with 'pio run'" )
379+ return
380+
381+ try :
382+ import subprocess
383+ import sys
384+ import shlex
385+
386+ cmd = [env .subst ("$PYTHONEXE" ), "-m" , "esp_idf_size" , "--ng" ]
387+
388+ # Parameters from platformio.ini
389+ extra_args = env .GetProjectOption ("custom_esp_idf_size_args" , "" )
390+ if extra_args :
391+ cmd .extend (shlex .split (extra_args ))
392+
393+ # Command Line Parameter, after --
394+ cli_args = []
395+ if "--" in sys .argv :
396+ dash_index = sys .argv .index ("--" )
397+ if dash_index + 1 < len (sys .argv ):
398+ cli_args = sys .argv [dash_index + 1 :]
399+ cmd .extend (cli_args )
400+
401+ # Add CLI arguments before the map file
402+ if cli_args :
403+ cmd .extend (cli_args )
404+
405+ # Map-file as last argument
406+ cmd .append (map_file )
407+
408+ # Debug-Info if wanted
409+ if env .GetProjectOption ("custom_esp_idf_size_verbose" , False ):
410+ print (f"Running command: { ' ' .join (cmd )} " )
411+
412+ # Call esp-idf-size
413+ result = subprocess .run (cmd , check = False , capture_output = False )
414+
415+ if result .returncode != 0 :
416+ print (f"Warning: esp-idf-size exited with code { result .returncode } " )
417+
418+ except ImportError :
419+ print ("Error: esp-idf-size module not found." )
420+ print ("Install with: pip install esp-idf-size" )
421+ except FileNotFoundError :
422+ print ("Error: Python executable not found." )
423+ print ("Check your Python installation." )
424+ except Exception as e :
425+ print (f"Error: Failed to run firmware metrics: { e } " )
426+ print ("Make sure esp-idf-size is installed: pip install esp-idf-size" )
385427
386428#
387429# Target: Build executable and linkable firmware or FS image
@@ -618,6 +660,31 @@ def firmware_metrics(target, source, env):
618660 "Erase Flash" ,
619661)
620662
663+ #
664+ # Register Custom Target
665+ #
666+ env .AddCustomTarget (
667+ name = "metrics" ,
668+ dependencies = "$BUILD_DIR/${PROGNAME}.elf" ,
669+ actions = firmware_metrics ,
670+ title = "Firmware Size Metrics" ,
671+ description = "Analyze firmware size using esp-idf-size (supports CLI args after --)" ,
672+ always_build = True
673+ )
674+
675+ #
676+ # Additional Target without Build-Dependency when already compiled
677+ #
678+ env .AddCustomTarget (
679+ name = "metrics-only" ,
680+ dependencies = None ,
681+ actions = firmware_metrics ,
682+ title = "Firmware Size Metrics (No Build)" ,
683+ description = "Analyze firmware size without building first" ,
684+ always_build = True
685+ )
686+
687+
621688#
622689# Override memory inspection behavior
623690#
0 commit comments