@@ -360,28 +360,66 @@ def check_lib_archive_exists():
360
360
361
361
362
362
def 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
+ """
363
367
if terminal_cp != "utf-8" :
364
368
print ("Firmware metrics can not be shown. Set the terminal codepage to \" utf-8\" " )
365
369
return
370
+
366
371
map_file = os .path .join (env .subst ("$BUILD_DIR" ), env .subst ("$PROGNAME" ) + ".map" )
367
372
if not os .path .isfile (map_file ):
368
373
# map file can be in project dir
369
374
map_file = os .path .join (get_project_dir (), env .subst ("$PROGNAME" ) + ".map" )
370
375
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
+ # Map-file as last argument
402
+ cmd .append (map_file )
403
+
404
+ # Debug-Info if wanted
405
+ if env .GetProjectOption ("custom_esp_idf_size_verbose" , False ):
406
+ print (f"Running command: { ' ' .join (cmd )} " )
407
+
408
+ # Call esp-idf-size
409
+ result = subprocess .run (cmd , check = False , capture_output = False )
410
+
411
+ if result .returncode != 0 :
412
+ print (f"Warning: esp-idf-size exited with code { result .returncode } " )
413
+
414
+ except ImportError :
415
+ print ("Error: esp-idf-size module not found." )
416
+ print ("Install with: pip install esp-idf-size" )
417
+ except FileNotFoundError :
418
+ print ("Error: Python executable not found." )
419
+ print ("Check your Python installation." )
420
+ except Exception as e :
421
+ print (f"Error: Failed to run firmware metrics: { e } " )
422
+ print ("Make sure esp-idf-size is installed: pip install esp-idf-size" )
385
423
386
424
#
387
425
# Target: Build executable and linkable firmware or FS image
@@ -618,6 +656,31 @@ def firmware_metrics(target, source, env):
618
656
"Erase Flash" ,
619
657
)
620
658
659
+ #
660
+ # Register Custom Target
661
+ #
662
+ env .AddCustomTarget (
663
+ name = "metrics" ,
664
+ dependencies = "$BUILD_DIR/${PROGNAME}.elf" ,
665
+ actions = firmware_metrics ,
666
+ title = "Firmware Size Metrics" ,
667
+ description = "Analyze firmware size using esp-idf-size (supports CLI args after --)" ,
668
+ always_build = True
669
+ )
670
+
671
+ #
672
+ # Additional Target without Build-Dependency when already compiled
673
+ #
674
+ env .AddCustomTarget (
675
+ name = "metrics-only" ,
676
+ dependencies = None ,
677
+ actions = firmware_metrics ,
678
+ title = "Firmware Size Metrics (No Build)" ,
679
+ description = "Analyze firmware size without building first" ,
680
+ always_build = True
681
+ )
682
+
683
+
621
684
#
622
685
# Override memory inspection behavior
623
686
#
0 commit comments