@@ -360,28 +360,70 @@ 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
+ # 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" )
385
427
386
428
#
387
429
# Target: Build executable and linkable firmware or FS image
@@ -618,6 +660,31 @@ def firmware_metrics(target, source, env):
618
660
"Erase Flash" ,
619
661
)
620
662
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
+
621
688
#
622
689
# Override memory inspection behavior
623
690
#
0 commit comments