CLI Reference
Complete reference for the membrowse command-line tool. For the GitHub Actions integration, see the membrowse-action repository.
Installation
pip install membrowse
To update to the latest version:
pip install --upgrade membrowse
Requirements: Python 3.8+
Quick Start
# Generate a local report
membrowse report build/firmware.elf "linker.ld"
# Output as JSON (for troubleshooting)
membrowse report build/firmware.elf "linker.ld" --json
# Analyze and upload to MemBrowse
membrowse report build/firmware.elf "linker.ld" \
--upload \
--target-name my-target \
--api-key YOUR_API_KEY
Commands
membrowse report
Generate and optionally upload a memory report.
membrowse report <elf_path> [ld_scripts] [options]
Arguments
| Argument | Required | Description |
|---|---|---|
elf_path | Yes* | Path to the ELF file (*not required with --identical) |
ld_scripts | No | Space-separated linker script paths in quotes — supports GNU LD (.ld) and IAR ICF (.icf) formats (if omitted, uses default Code/Data regions based on ELF section flags) |
Mode Options
| Option | Description |
|---|---|
--upload | Upload report to MemBrowse platform |
--no-git | Disable auto-detection of Git metadata when uploading |
--github | Use GitHub Actions environment for Git metadata detection (use with --upload) |
Upload Options
Required when using --upload:
| Option | Description |
|---|---|
--api-key KEY | MemBrowse API key |
--target-name NAME | Build configuration/target (e.g., esp32, stm32, x86) |
--api-url URL | MemBrowse API base URL (default: https://api.membrowse.com) |
--identical | Mark commit as having identical memory footprint to previous (metadata-only upload, no ELF analysis required) |
Git Metadata Options
These are auto-detected by default. Use --no-git to disable auto-detection, or specify manually to override:
| Option | Description |
|---|---|
--commit-sha | Git commit SHA |
--parent-sha | Git parent commit SHA. Use append to set the parent to the head of the default branch, or none for no parent. |
--base-sha | Alias for --parent-sha |
--branch-name | Git branch name |
--repo-name | Repository name |
--commit-message | Commit message |
--commit-timestamp | Commit timestamp (ISO format) |
--author-name | Commit author name |
--author-email | Commit author email |
--pr-number | Pull request number |
--pr-name | Pull request name/title |
--pr-author-name | Pull request author name |
--pr-author-email | Pull request author email |
Performance Options
| Option | Description |
|---|---|
--skip-line-program | Skip DWARF line program processing for faster analysis |
--def VAR=VALUE | Define linker script variable (can be specified multiple times) |
Alert Options
| Option | Description |
|---|---|
--dont-fail-on-alerts | Exit 0 even if budget alerts triggered |
Output Options
| Option | Description |
|---|---|
--json | Output report as JSON (default is human-readable format) |
--all-symbols | Display all symbols instead of just top 20 (human-readable mode only) |
--output-raw-response | Output raw API response as JSON to stdout |
Upload Response
When uploading with --upload, the API returns a JSON response containing:
success: Whether the upload succeededreport_id: The ID of the uploaded reportalerts: Any budget alerts triggereddiffs: Memory differences compared to the previous commit, broken down by region and section
Use --output-raw-response to output this JSON to stdout for further processing:
RESULT=$(membrowse report \
build/firmware.elf \
"linker.ld" \
--upload \
--target-name my-target \
--api-key YOUR_API_KEY \
--output-raw-response)
echo "$RESULT" | jq '.diffs'
Examples
# Local analysis - human-readable output (default)
membrowse report build/firmware.elf "linker.ld"
# Local analysis without linker scripts (uses default Code/Data regions)
membrowse report build/firmware.elf
# Show all symbols locally
membrowse report build/firmware.elf "linker.ld" --all-symbols
# Output as JSON
membrowse report build/firmware.elf "linker.ld" --json
# Upload to MemBrowse (Git metadata auto-detected)
membrowse report build/firmware.elf "linker.ld" \
--upload \
--target-name my-target \
--api-key YOUR_API_KEY
# Upload without Git metadata
membrowse report build/firmware.elf "linker.ld" \
--upload --no-git \
--target-name my-target \
--api-key YOUR_API_KEY
# GitHub Actions mode (auto-detects Git metadata from GitHub environment)
membrowse report build/firmware.elf "linker.ld" \
--upload --github \
--target-name stm32f4 \
--api-key YOUR_API_KEY
# Multiple linker scripts
membrowse report build/firmware.elf "memory.ld sections.ld" \
--upload \
--target-name my-target \
--api-key YOUR_API_KEY
# Define linker script variables
membrowse report build/firmware.elf "linker.ld" \
--def __flash_size__=4096K \
--def __ram_size__=256K
membrowse summary
Retrieve memory footprint summaries for a commit from the MemBrowse API. Returns data for all targets associated with the commit — each target's region changes, section changes, and layout are included in the response under a targets list.
membrowse summary <commit_sha> --api-key KEY [options]
Arguments
| Argument | Required | Description |
|---|---|---|
commit_sha | Yes | Git commit SHA to retrieve summary for |
Options
| Option | Description |
|---|---|
--api-key KEY | MemBrowse API key (required) |
--api-url URL | MemBrowse API base URL (default: https://api.membrowse.com) |
--json | Output raw JSON response from API (includes targets array with per-target summaries) |
--template PATH | Path to custom Jinja2 template file (default: built-in template). The template receives the full response including the targets list. |
--json and --template are mutually exclusive.
Examples
# Human-readable summary (all targets)
membrowse summary abc123def --api-key YOUR_API_KEY
# Raw JSON output (for scripting)
membrowse summary abc123def --api-key YOUR_API_KEY --json
# Custom template
membrowse summary abc123def --api-key YOUR_API_KEY --template my_template.j2
membrowse onboard
Analyze historical commits to build baseline data. Supports two modes: processing the last N commits, or processing a specific list of commits/tags.
# Mode 1: Last N commits
membrowse onboard <num_commits> <build_script> <elf_path> <target_name> <api_key> [api_url] [options]
# Mode 2: Specific commits
membrowse onboard <build_script> <elf_path> <target_name> <api_key> --commits "REF1 REF2 ..." [options]
Arguments
| Argument | Required | Description |
|---|---|---|
num_commits | No | Number of commits to process (required unless --commits is used) |
build_script | Yes | Shell command to build the firmware (quoted) |
elf_path | Yes | Path to ELF file after build |
target_name | Yes | Target name in MemBrowse |
api_key | Yes | MemBrowse API key |
api_url | No | MemBrowse API base URL (default: https://api.membrowse.com) |
Options
| Option | Description |
|---|---|
--ld-scripts SCRIPTS | Space-separated linker script paths — supports GNU LD (.ld) and IAR ICF (.icf) formats (if omitted, uses default Code/Data regions) |
--def VAR=VALUE | Define linker script variable (can be specified multiple times) |
--build-dirs DIR [DIR ...] | Directories that trigger rebuilds. Commits with no changes in these directories upload metadata-only reports with identical=True. Mutually exclusive with --binary-search. |
--initial-commit HASH | Start processing from this commit hash (must be on the main branch). Only valid with num_commits. |
--commits REFS | Space-separated list of commit hashes and/or tags to process. Mutually exclusive with num_commits and --initial-commit. |
--initial-parent REF | Set the parent of the first commit when using --commits. Used to chain multiple onboard runs together. Only valid with --commits. |
--binary-search | Minimize builds using binary search — builds endpoints first, compares memory fingerprints, and only builds midpoints where changes are detected. Mutually exclusive with --build-dirs. |
--dry-run | Run the full workflow but skip uploading reports (logs what would be uploaded) |
Examples
# Basic onboarding with linker scripts
membrowse onboard \
50 \
"make clean && make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--ld-scripts "linker.ld"
# Without linker scripts (uses default Code/Data regions)
membrowse onboard \
50 \
"make clean && make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY
# With custom API URL
membrowse onboard \
25 \
"idf.py build" \
build/firmware.elf \
esp32 \
YOUR_API_KEY \
https://custom-api.example.com \
--ld-scripts "build/esp-idf/esp32/esp32.project.ld"
# Skip commits without changes in build directories
membrowse onboard \
100 \
"make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--ld-scripts "linker.ld" \
--build-dirs src/ lib/ include/
# Start from a specific commit
membrowse onboard \
50 \
"make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--ld-scripts "linker.ld" \
--initial-commit abc123def
# Onboard specific version tags
membrowse onboard \
"make clean && make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--commits "v1.0 v1.1 v2.0 v2.1" \
--ld-scripts "linker.ld"
# Chain multiple onboard runs across version boundaries
membrowse onboard \
"make clean && make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--commits "v2.0 v2.1 v2.2" \
--initial-parent v1.9 \
--ld-scripts "linker.ld"
# Minimize builds with binary search
membrowse onboard \
100 \
"make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--ld-scripts "linker.ld" \
--binary-search
# Dry run to verify setup without uploading
membrowse onboard \
10 \
"make all" \
build/firmware.elf \
my-target \
YOUR_API_KEY \
--ld-scripts "linker.ld" \
--dry-run
Behavior
- Fetches git history (requires full clone)
- Uses
--first-parentto follow only main branch (not feature branch commits) - Iterates from oldest to newest commit
- For each commit:
- Checks out the commit
- Runs the build script
- Analyzes the ELF file
- Uploads the report
- Skips building commits with no changes in
--build-dirs(uploads metadata-only) - With
--binary-search, builds only endpoints first, then bisects where memory fingerprints differ - Uploads empty reports for failed builds
- Restores original HEAD when complete
Global Options
These options apply to all commands:
| Option | Description |
|---|---|
-v, --verbose LEVEL | Set logging verbosity: WARNING (default), DEBUG, INFO |
--version | Show installed version |
--help | Show help message |
# Info output
membrowse -v INFO report build/firmware.elf "linker.ld"
# Debug output
membrowse -v DEBUG report build/firmware.elf "linker.ld"
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (budget alert, invalid input, API error, etc.) |
Use --dont-fail-on-alerts to prevent budget alerts from causing exit code 1.
Output Formats
Human-Readable (default)
Memory Report for build/firmware.elf
=====================================
FLASH: 45,234 / 262,144 bytes (17.3%)
.text: 32,456 bytes
.rodata: 12,778 bytes
RAM: 12,834 / 65,536 bytes (19.6%)
.data: 1,234 bytes
.bss: 11,600 bytes
Top Symbols by Size:
1. main 2,456 bytes (.text)
2. usb_buffer 4,096 bytes (.bss)
3. string_table 1,892 bytes (.rodata)
...
JSON (with --json)
When using --json, the report is output as JSON to stdout. When uploading with --upload, a JSON report is generated containing:
- Memory regions with usage
- All sections with sizes
- Complete symbol table
- Git metadata (commit, branch, etc.)