|
| 1 | +--- |
| 2 | +name: binary-size-comparison |
| 3 | +description: |
| 4 | + Guidelines for comparing binary (ELF) sizes using Rust-based tooling |
| 5 | + (elf-bloat and asm-annotate) across various platforms to analyze the impact |
| 6 | + of code changes on footprint. |
| 7 | +--- |
| 8 | + |
| 9 | +# Binary Size Comparison Workflow |
| 10 | + |
| 11 | +This skill provides the workflow to compare binary sizes between your current |
| 12 | +branch and a baseline (like the `master` fork-point). |
| 13 | + |
| 14 | +## 1. Prerequisites & Tool Installation |
| 15 | + |
| 16 | +### A. Containerized Build Setup |
| 17 | + |
| 18 | +You MUST use the `podman-vscode-build` skill to handle container setup and build |
| 19 | +execution. |
| 20 | + |
| 21 | +- **macOS Note**: As per `podman-vscode-build`, use `docker` instead of |
| 22 | + `podman` on macOS due to stability and proper Rosetta 2 support for the x86 |
| 23 | + toolchains. |
| 24 | + |
| 25 | +### B. Rust Tools Installation (macOS & Linux) |
| 26 | + |
| 27 | +These tools must be installed on your **Host machine**. They require the Rust |
| 28 | +toolchain. |
| 29 | + |
| 30 | +_If you don't have Rust (`cargo`) installed, install it first:_ |
| 31 | + |
| 32 | +```bash |
| 33 | +# This official installer works for both macOS and Linux |
| 34 | +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
| 35 | +source "$HOME/.cargo/env" |
| 36 | +``` |
| 37 | + |
| 38 | +_Once Rust is available, install the size comparison tools:_ |
| 39 | + |
| 40 | +```bash |
| 41 | +cargo install elf_bloat asm-annotate |
| 42 | +``` |
| 43 | + |
| 44 | +## 2. Platform ELF Locations |
| 45 | + |
| 46 | +Identify your target's ELF path relative to the repo root before you start: |
| 47 | + |
| 48 | +- **Linux / POSIX**: `out/<target>/<app-name>` |
| 49 | +- **ESP32**: `out/<target>/<app-name>.elf` |
| 50 | +- **Silicon Labs EFR32**: `out/<target>/<app-name>.out` |
| 51 | +- **nRF Connect (script)**: |
| 52 | + `examples/<app>/nrfconnect/build/nrfconnect/zephyr/zephyr.elf` |
| 53 | +- **nRF/Telink (build_examples.py)**: `out/<target>/zephyr/zephyr.elf` |
| 54 | + |
| 55 | +## 3. Comparison Workflow |
| 56 | + |
| 57 | +### A. Build the Baseline (Master Fork-Point) |
| 58 | + |
| 59 | +Determine the fork-point to isolate only your changes. |
| 60 | + |
| 61 | +```bash |
| 62 | +CURRENT_COMMIT=$(git rev-parse HEAD) |
| 63 | +FORK_POINT=$(git merge-base master HEAD) |
| 64 | + |
| 65 | +git checkout $FORK_POINT |
| 66 | +scripts/checkout_submodules.py --shallow --force |
| 67 | + |
| 68 | +# BUILD STEP: Use 'podman-vscode-build' skill here |
| 69 | +# Example: docker exec -w /workspace bld_vscode bash -c "source scripts/activate.sh && scripts/examples/nrfconnect_example.sh all-clusters-app nrf52840dk/nrf52840" |
| 70 | + |
| 71 | +mkdir -p out/size-compares/master-baseline |
| 72 | +cp <PATH_TO_ELF> out/size-compares/master-baseline/baseline.elf |
| 73 | + |
| 74 | +git checkout $CURRENT_COMMIT |
| 75 | +scripts/checkout_submodules.py --shallow --force |
| 76 | +``` |
| 77 | + |
| 78 | +### B. Build the PR Branch |
| 79 | + |
| 80 | +```bash |
| 81 | +# BUILD STEP: Use 'podman-vscode-build' skill here |
| 82 | +# Example: docker exec -w /workspace bld_vscode bash -c "source scripts/activate.sh && scripts/examples/nrfconnect_example.sh all-clusters-app nrf52840dk/nrf52840" |
| 83 | + |
| 84 | +mkdir -p out/size-compares/pr-branch |
| 85 | +cp <PATH_TO_ELF> out/size-compares/pr-branch/updated.elf |
| 86 | +``` |
| 87 | + |
| 88 | +### C. Run and Analyze Comparison |
| 89 | + |
| 90 | +Run `elf-bloat` on your **Host machine** to generate the report. |
| 91 | + |
| 92 | +```bash |
| 93 | +elf-bloat --compare-base out/size-compares/master-baseline/baseline.elf \ |
| 94 | + --viewer none \ |
| 95 | + out/size-compares/pr-branch/updated.elf \ |
| 96 | + > out/size-compares/size_diff_report.csv |
| 97 | + |
| 98 | +# View top 20 growth contributors (skips CSV header) |
| 99 | +tail -n +2 out/size-compares/size_diff_report.csv | sort -t',' -k3 -rn | head -n 20 |
| 100 | +``` |
| 101 | + |
| 102 | +### D. Deep Dive Analysis (Optional) |
| 103 | + |
| 104 | +To find the largest functions in a single binary non-interactively (without |
| 105 | +TUI), use `elf-bloat` with the custom viewer to dump a CSV: |
| 106 | + |
| 107 | +```bash |
| 108 | +elf-bloat out/size-compares/pr-branch/updated.elf --viewer custom:cat > out/size-compares/single_size_report.csv |
| 109 | +head -n 20 out/size-compares/single_size_report.csv |
| 110 | +``` |
| 111 | + |
| 112 | +If a specific function grew significantly and you want to see exactly which C++ |
| 113 | +lines generated the bloated assembly, use `asm-annotate`. It maps the compiled |
| 114 | +assembly instructions back to your original source code. |
| 115 | + |
| 116 | +> **CRITICAL RULE FOR AI AGENTS**: ALWAYS use the `--dump` flag when running |
| 117 | +> `asm-annotate`. |
| 118 | +
|
| 119 | +```bash |
| 120 | +# Dump the assembly to a file for analysis or for pasting into a PR description |
| 121 | +asm-annotate out/size-compares/pr-branch/updated.elf "chip::app::CodegenDataModelProvider::InitDataModelForTesting()" --dump > out/size-compares/annotated_function.txt |
| 122 | +cat out/size-compares/annotated_function.txt |
| 123 | +``` |
0 commit comments