Files
tactility_apps/.claude/skills/tactility-app-development/scripts/verify_symbols.py
T
Adolfo Reyna e68909d64d
Main / Build (BookPlayer) (push) Has been cancelled
Main / Build (Brainfuck) (push) Has been cancelled
Main / Build (Breakout) (push) Has been cancelled
Main / Build (Calculator) (push) Has been cancelled
Main / Build (Diceware) (push) Has been cancelled
Main / Build (EpubReader) (push) Has been cancelled
Main / Build (GPIO) (push) Has been cancelled
Main / Build (GraphicsDemo) (push) Has been cancelled
Main / Build (HelloWorld) (push) Has been cancelled
Main / Build (M5UnitTest) (push) Has been cancelled
Main / Build (Magic8Ball) (push) Has been cancelled
Main / Build (MediaKeys) (push) Has been cancelled
Main / Build (MystifyDemo) (push) Has been cancelled
Main / Build (SerialConsole) (push) Has been cancelled
Main / Build (Snake) (push) Has been cancelled
Main / Build (TamaTac) (push) Has been cancelled
Main / Build (TodoList) (push) Has been cancelled
Main / Build (TwoEleven) (push) Has been cancelled
Main / Bundle (push) Has been cancelled
chore: move app skill in-repo + AGENTS.md
- Migrates tactility-app-development from ~/.hermes/skills/ into
  .claude/skills/ for repo co-location
- Adds AGENTS.md with local workstation context, hardware table,
  board-direct build/env wrapper (PYTHONPATH fix), ELF missing-symbol
  triage, app patterns (immersive, QVGA rail, tutorial 2-row,
  GameKit bubbling, screenshot rate-limit), and skill index

Refs: personal Gitea mirror
2026-07-17 09:51:20 -04:00

60 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""
Verify ELF symbols against firmware exports. Rerunnable from skill.
Usage:
python3 scripts/verify_symbols.py [--elf Apps/BibleVerse/build/cmake-build-esp32s3/BibleVerse.app.elf] [--firmware ../firmware]
Requires: xtensa-esp32s3-elf-nm in PATH after sourcing ~/esp/esp-idf/export.sh
"""
import argparse, pathlib, re, subprocess, sys
def get_undef(elf_path: pathlib.Path):
r = subprocess.run(
["zsh","-c", f"source /Users/adolforeyna/esp/esp-idf/export.sh >/dev/null 2>&1; xtensa-esp32s3-elf-nm -D {elf_path}"],
capture_output=True, text=True
)
undef=[]
for line in r.stdout.splitlines():
parts=line.split()
if len(parts)>=2 and parts[-2]=='U':
undef.append(parts[-1])
return undef, r.stdout
def get_exports(firmware_dir: pathlib.Path):
pat=re.compile(r'(?:ESP_ELFSYM_EXPORT|DEFINE_MODULE_SYMBOL)\s*\(\s*([A-Za-z0-9_]+)\s*\)')
exp=set()
for fp in firmware_dir.rglob("*.*"):
if 'build' in str(fp): continue
if fp.suffix not in ('.c','.h','.cpp'): continue
try:
exp.update(m.group(1) for m in pat.finditer(fp.read_text(errors='ignore')))
except: pass
return exp
def main():
p=argparse.ArgumentParser()
p.add_argument('--elf', default='Apps/BibleVerse/build/cmake-build-esp32s3/BibleVerse.app.elf')
p.add_argument('--firmware', default='../firmware')
args=p.parse_args()
elf=pathlib.Path(args.elf)
fw=pathlib.Path(args.firmware)
if not elf.exists():
print(f"ELF not found: {elf}", file=sys.stderr)
sys.exit(2)
undef, raw = get_undef(elf)
exp = get_exports(fw)
missing=[s for s in undef if s not in exp]
print(f"Undefined: {len(undef)}")
print(f"Exported: {len(exp)}")
if missing:
print(f"Missing {len(missing)}:")
for s in sorted(missing):
print(f" - {s}")
sys.exit(1)
print("✅ All symbols resolved")
sys.exit(0)
if __name__ == '__main__':
main()