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
- 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
60 lines
2.0 KiB
Python
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()
|