ci/SYMBOL_ANALYSIS.md
This document describes the new generic symbol analysis functionality that works across all supported platforms including UNO, ESP32, and others.
The symbol analysis tool provides comprehensive analysis of compiled ELF files to help identify optimization opportunities and understand binary size allocation. Unlike the previous ESP32-specific implementation, this tool:
cd ci
uv run symbol_analysis.py --board uno
uv run symbol_analysis.py --board esp32dev
uv run demo_symbol_analysis.py
uv run symbol_analysis_runner.py --board uno --example Blink
symbol_analysis.py - Main generic symbol analysis toolsymbol_analysis_runner.py - GitHub Actions wrapperdemo_symbol_analysis.py - Demonstration script for multiple platformsSYMBOL_ANALYSIS.md - This documentation file================================================================================
UNO SYMBOL ANALYSIS REPORT
================================================================================
SUMMARY:
Total symbols: 51
Total symbol size: 3767 bytes (3.7 KB)
LARGEST SYMBOLS (all symbols, sorted by size):
1. 1204 bytes - ClocklessController<...>::showPixels(...)
2. 572 bytes - CFastLED::show(unsigned char) [clone .constprop.18]
3. 460 bytes - main
4. 204 bytes - CPixelLEDController<...>::show(...)
5. 168 bytes - CPixelLEDController<...>::showColor(...)
SYMBOL TYPE BREAKDOWN:
t: 19 symbols, 2710 bytes (2.6 KB)
T: 14 symbols, 904 bytes (0.9 KB)
b: 15 symbols, 89 bytes (0.1 KB)
d: 3 symbols, 64 bytes (0.1 KB)
================================================================================
ESP32DEV SYMBOL ANALYSIS REPORT
================================================================================
SUMMARY:
Total symbols: 2503
Total symbol size: 237092 bytes (231.5 KB)
LARGEST SYMBOLS (all symbols, sorted by size):
1. 12009 bytes - _vfprintf_r
2. 11813 bytes - _svfprintf_r
3. 8010 bytes - _vfiprintf_r
4. 7854 bytes - _svfiprintf_r
5. 4192 bytes - port_IntStack
SYMBOL TYPE BREAKDOWN:
T: 1240 symbols, 156230 bytes (152.6 KB)
t: 371 symbols, 45841 bytes (44.8 KB)
d: 475 symbols, 13032 bytes (12.7 KB)
D: 60 symbols, 9421 bytes (9.2 KB)
W: 126 symbols, 5209 bytes (5.1 KB)
================================================================================
ESP32S3 SYMBOL ANALYSIS REPORT
================================================================================
SUMMARY:
Total symbols: 2831
Total symbol size: 260710 bytes (254.6 KB)
LARGEST SYMBOLS (all symbols, sorted by size):
1. 11309 bytes - _vfprintf_r
2. 11118 bytes - _svfprintf_r
3. 7337 bytes - _svfiprintf_r
4. 7265 bytes - _vfiprintf_r
5. 4192 bytes - port_IntStack
6. 1164 bytes - printBeforeSetupInfo()
7. 828 bytes - fl::RmtController5::loadPixelData(PixelIterator&)
SYMBOL TYPE BREAKDOWN:
T: 1416 symbols, 172591 bytes (168.5 KB)
t: 429 symbols, 48854 bytes (47.7 KB)
d: 529 symbols, 14189 bytes (13.9 KB)
D: 72 symbols, 9831 bytes (9.6 KB)
W: 122 symbols, 5457 bytes (5.3 KB)
The tool generates JSON files with complete symbol data:
.build/{board}_symbol_analysis.json - Complete analysis results{
"summary": {
"board": "uno",
"total_symbols": 51,
"total_size": 3767,
"largest_symbols": [...],
"type_breakdown": {...},
"dependencies": {...}
},
"all_symbols_sorted_by_size": [
{
"address": "00001240",
"size": 1204,
"type": "t",
"name": "_ZN19ClocklessController...",
"demangled_name": "ClocklessController<...>::showPixels(...)"
},
...
],
"dependencies": {
"module.cpp.o": ["symbol1", "symbol2", ...]
}
}
The tool automatically detects and works with any platform that has:
build_info.json file in .build/{platform}/Successfully tested platforms:
Before (ESP32 only):
# Hard-coded ESP32 board detection
esp32_boards = ["esp32dev", "esp32", "esp32s2", ...]
# FastLED-specific filtering
if any(keyword in search_text for keyword in [
"fastled", "cfastled", "crgb", "hsv", ...]):
fastled_symbols.append(symbol_info)
After (Generic):
# Auto-detect any platform with build_info.json
for item in build_dir.iterdir():
if item.is_dir() and (item / "build_info.json").exists():
available_boards.append((build_info_file, item.name))
# No filtering - analyze ALL symbols
symbols.append(symbol_info) # Everything included
The symbol_analysis_runner.py script provides GitHub Actions compatibility:
- name: Run Symbol Analysis
run: python ci/symbol_analysis_runner.py --board uno --example Blink
This runner:
--skip-on-failureIf you were using the old ESP32-specific analysis:
Old command:
cd ci/ci && python esp32_symbol_analysis.py
New command:
cd ci && uv run symbol_analysis.py --board esp32dev
The new tool provides all the same information plus:
To add support for a new platform:
build_info.json is generated in .build/{platform}/uv run symbol_analysis.py --board {platform}# Analyze all available platforms
uv run demo_symbol_analysis.py
# Analyze specific platforms in sequence
for board in uno esp32dev teensy31; do
uv run symbol_analysis.py --board $board
done
# In your Python build script
from ci.ci.symbol_analysis import main as analyze_symbols
import sys
# Override arguments
sys.argv = ["symbol_analysis.py", "--board", "uno"]
analyze_symbols()
"build_info.json not found"
uv run ci/ci-compile.py {board} --examples Blink"KeyError: 'board_name'"
cat .build/{board}/build_info.json | jq 'keys'"Tool not found"
To debug issues, run with verbose Python output:
uv run python -v symbol_analysis.py --board uno
When adding new features:
Platform analysis times (approximate):
The tool scales well with symbol count and provides progress feedback during demangling.